etopolayer.java

来自「openmap java写的开源数字地图程序. 用applet实现,可以像g」· Java 代码 · 共 879 行 · 第 1/3 页

JAVA
879
字号
                // call the "darker" method on the base color for                // negative slopes                for (int k = 3; k >= 0; k--) {                    // set                    slopeColors[i][k] = slopeColors[i][k + 1].darker();                }            }        }        // get the elevation band index        int elIdx = getElevIndex(elevation);        // compute slope idx        int slopeIdx = ((int) slopeVal + 127) / 32;        // return color        Color norm = slopeColors[elIdx][slopeIdx];        // set alpha        return new Color(norm.getRed(), norm.getGreen(), norm.getBlue(), opaqueness);    }    /**     * Set all the ETOPO properties from a properties object.     */    public void setProperties(String prefix, java.util.Properties properties) {        super.setProperties(prefix, properties);        prefix = PropUtils.getScopedPropertyPrefix(this);        path = properties.getProperty(prefix + ETOPOPathProperty);        opaqueness = PropUtils.intFromProperties(properties, prefix                + OpaquenessProperty, DEFAULT_OPAQUENESS);        viewType = PropUtils.intFromProperties(properties, prefix                + ETOPOViewTypeProperty, COLOREDSHADING);        slopeAdjust = PropUtils.intFromProperties(properties, prefix                + ETOPOSlopeAdjustProperty, DEFAULT_SLOPE_ADJUST);        minuteSpacing = PropUtils.intFromProperties(properties, prefix                + ETOPOMinuteSpacingProperty, DEFAULT_MINUTE_SPACING);    }    /**     * Builds the slope index map. This method is called when the     * ETOPO resolution changes and when the slope contrast changes.     * The slope of the terrain is cliped; slopes are between the     * range of +/- 45 deg. The calculated slope value is then     * linearly scaled to the range +/- 127.     */    protected void buildSlopeMap() {        // this should never happen, but...        if (dataBuffer == null)            return;        // get resolution index        int resIdx = minuteSpacing / 5; //ep-g        if (resIdx < 0)            resIdx = 0;        else if (resIdx > 3) //ep-g            resIdx = 3; //ep-g        // Set deltaX constant. The deltaX is actually is smaller at        // latitude        // extremes, but        double deltaX = etopoSpacings[resIdx];        // allocate storage for slope map        slopeMap = new byte[bufferWidth * bufferHeight];        // process dataBuffer to create slope        for (int y = 0; y < bufferHeight; y++) {            // compute the lattitude of this            double lat = 90. - 180. * (double) y / (double) bufferHeight;            // get cosine of the latitude. This is used because the            // spacing between minutes gets smaller in high latitude            // extremes.            double coslat = Math.cos(Math.toRadians(lat));            // for scaling the slope            double slopeScaler = (double) slopeAdjust * coslat / deltaX;            // indexcies            int idx0 = y * bufferWidth;            // do each row            for (int x = 0; x < bufferWidth; x++) {                // indexcies                int idx1 = idx0 + x;                int idx2 = idx1 + bufferWidth;                ;                // special case at end                if (y == bufferHeight - 1)                    idx2 = idx1;                // get altitudes                double d1 = (double) dataBuffer[idx1];                double d2 = (double) dataBuffer[idx2];                // compute (lookup) slope                double slope = slopeScaler * (d2 - d1);                // clip                if (slope > 0.99)                    slope = 0.99;                else if (slope < -0.99)                    slope = -0.99;                // scale                int islope = (int) (slope * 127.);                // store                slopeMap[idx1] = (byte) islope;            }        }    }    /**     * Loads the database from the appropriate file based on the     * current resolution. The data files are in INTEL format (must     * call BinaryBufferedFile.byteOrder(true)).     */    protected void loadBuffer() {        // get the resolution index        int resIdx = minuteSpacing / 5; //ep-g        if (resIdx < 0)            resIdx = 0;        else if (resIdx > 3) //ep-g            resIdx = 3; //ep-g        // build file name        String fileName = path + etopoFileNames[resIdx];        // Clean this out...dfd        dataBuffer = null;                try {            // treat as buffered binary            BinaryBufferedFile binFile = new BinaryBufferedFile(fileName);            binFile.byteOrder(true);            // set width/height            bufferWidth = etopoWidths[resIdx];            bufferHeight = etopoHeights[resIdx];                        int spacer = 1;            // don't know why I have to do this, but there seems to be            // a wrapping thing going on with different data sets.            switch (minuteSpacing) {            case (2):                spacer = 1;                break;            case (5):                spacer = 0;                break;            default:                spacer = 1;            }//            bufferWidth = bufferWidth + spacer;            // allocate storage            dataBuffer = new short[(bufferWidth + spacer) * bufferHeight];            // read data            for (int i = 0; i < bufferWidth * bufferHeight; i++)                dataBuffer[i] = binFile.readShort();            // done            binFile.close();            //This is important for image creation.            bufferWidth += spacer;                    } catch (FileNotFoundException e) {            Debug.error("ETOPOLayer loadBuffer(): file " + fileName                    + " not found");        } catch (IOException e) {            Debug.error("ETOPOLayer loadBuffer(): File IO Error!\n"                    + e.toString());        } catch (FormatException e) {            Debug.error("ETOPOLayer loadBuffer(): Format exception!\n"                    + e.toString());        }    }    /*     * Builds the raster image that has the dimensions of the current     * projection. The alogorithm is is follows: <P><pre> allocate     * storage the size of the projection (use ints for RGBA)     *      * for each screen point     *      * inverse project screen point to get lat/lon (world coords) get     * altitude and/or slope at the world coord compute (lookup) color     * at the world coord set color value into screen coord location     *      * end     *      * create OMRaster from the int array data. </pre>     *      * The code contains a HACK (primarily for the Orthographic     * projection) since * x/y values which would return an "Outer     * Space" value actually return lat/lon values for the center of     * the projection (see Orthographic.inverse(...)). This resulted     * in the "Outer Space" being painted the color of whatever the     * center lat/lon was. The HACK turns any center lat/lon value     * into black. Of course, this causes valid center lat/lon values     * to be painted black, but the trade off is worth it visually.     * The appropriate method may be to have Projection.inverse and     * its variants raise an exception for "Outer Space" values.     */    protected OMRaster buildRaster() {        // initialize the return        OMRaster ret = null;        Projection projection = getProjection();        // work with the slopeMap        if (slopeMap != null) {            // compute our deltas            int width = projection.getWidth();            int height = projection.getHeight();            // create int array to hold colors            int[] colors = new int[width * height];            // compute scalers for lat/lon indicies            float scy = (float) bufferHeight / 180F;            float scx = (float) bufferWidth / 360F;            // starting and ending indices            int sx = 0, sy = 0, ex = width, ey = height;            // handle CADRG            if (projection instanceof CADRG) {                // get corners                LatLonPoint ul = projection.getUpperLeft();                LatLonPoint lr = projection.getLowerRight();                // set start/end indicies                Point ulp = projection.forward(ul);                Point lrp = projection.forward(lr);                sx = (int) ulp.getX();                ex = (int) lrp.getX();                sy = (int) ulp.getY();                ey = (int) lrp.getY();            }            // get the center lat/lon (used by the HACK, see above in            // method description)            LatLonPoint center = projection.getCenter();            LatLonPoint llp = new LatLonPoint();            // build array            for (int y = sy; y < ey; y++) {                // process each column                for (int x = sx; x < ex; x++) {                    // inverse project x,y to lon,lat                    projection.inverse(x, y, llp);                    // get point values                    float lat = llp.getLatitude();                    float lon = llp.getLongitude();                    // check... dfd                    if (minuteSpacing == 2) {                        lon += 180.;                    } else {                        if (lon < 0.)                            lon += 360.;                    }                    // find indicies

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?