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 + -
显示快捷键?