📄 cadrg.java
字号:
* @param ret_val Point retval * @return Point ret_val */ public Point forward(LatLonPoint pt, Point ret_val) { float lon_ = wrap_longitude(pt.radlon_ - ctrLon); float lat_ = normalize_latitude(pt.radlat_); ret_val.x = (int) ProjMath.roundAdjust(spps_x * lon_) - ul.x; ret_val.y = (int) ProjMath.roundAdjust(-spps_y * lat_) + ul.y + oy; return ret_val; } /** * Forward projects lat,lon into XY space and returns a Point. * * @param lat float latitude in radians * @param lon float longitude in radians * @param ret_val Resulting XY Point * @return Point ret_val */ public Point forward(float lat, float lon, Point ret_val, boolean b) { float lon_ = wrap_longitude(lon - ctrLon); float lat_ = normalize_latitude(lat); ret_val.x = (int) ProjMath.roundAdjust(spps_x * lon_) - ul.x; ret_val.y = (int) ProjMath.roundAdjust(-spps_y * lat_) + ul.y + oy; return ret_val; } /** * Forward projects lat,lon coordinates. * <p> * * @param lat raw latitude in decimal degrees * @param lon raw longitude in decimal degrees * @param ret_val Resulting XY Point * @return Point ret_val */ public Point forward(float lat, float lon, Point ret_val) { float lon_ = wrap_longitude(ProjMath.degToRad(lon) - ctrLon); float lat_ = normalize_latitude(ProjMath.degToRad(lat)); ret_val.x = (int) ProjMath.roundAdjust(spps_x * lon_) - ul.x; ret_val.y = (int) ProjMath.roundAdjust(-spps_y * lat_) + ul.y + oy; return ret_val; } /** * Inverse project a Point. * * @param pt x,y Point * @param ret_val resulting LatLonPoint * @return LatLonPoint ret_val * */ public LatLonPoint inverse(Point pt, LatLonPoint ret_val) { //Debug.output("CADRG.inverse"); Point pixpoint = new Point(0, 0); /* offset back into pixel space from Drawable space */ pixpoint.x = pt.x + ul.x/* - ox */; pixpoint.y = -pt.y + ul.y + oy; // Check bounds on the call (P Space). Mutate if needed. if (pixpoint.x > (int) ProjMath.roundAdjust(world.x / 2.0)) { pixpoint.x = (int) ProjMath.roundAdjust(world.x / 2.0); } else if (pixpoint.x < (int) ProjMath.roundAdjust(-world.x / 2.0)) { pixpoint.x = (int) ProjMath.roundAdjust(-world.x / 2.0); } if (pixpoint.y > (int) ProjMath.roundAdjust(world.y / 2.0)) { pixpoint.y = (int) ProjMath.roundAdjust(world.y / 2.0); } else if (pixpoint.y < (int) ProjMath.roundAdjust(-world.y / 2.0)) { pixpoint.y = (int) ProjMath.roundAdjust(-world.y / 2.0); } // normalize_latitude on the way out. float lat_ = normalize_latitude((float) ((double) pixpoint.y / (double) spps_y)); ret_val.setLatitude(ProjMath.radToDeg(lat_)); // longitude is wrapped as usual. ret_val.setLongitude(ProjMath.radToDeg((float) ((double) pixpoint.x / (double) spps_x) + ctrLon)); // // normalize_latitude on the way out. // float lat_ = // normalize_latitude(degToRad(((float)MoreMath.SC_TO_DEG( // (int)(ProjMath.roundAdjust((double)pixpoint.y/(double)spps_y)))))); // ret_val.setLatitude((float)ProjMath.radToDeg(lat_)); // // longitude is wrapped as usual. // ret_val.setLongitude((float)MoreMath.SC_TO_DEG( // (int)(ProjMath.roundAdjust((double)pixpoint.x/(double)spps_x) // + // MoreMath.DEG_TO_SC(ProjMath.radToDeg(ctrLon))))); return ret_val; } /** * Inverse project x,y coordinates into a LatLonPoint. * <p> * * @param x integer x coordinate * @param y integer y coordinate * @param ret_val LatLonPoint * @return LatLonPoint ret_val * @see Proj#inverse(Point) * */ public LatLonPoint inverse(int x, int y, LatLonPoint ret_val) { //Debug.output("CADRG.inverse"); Point pixpoint = new Point(0, 0); /* offset back into pixel space from Drawable space */ pixpoint.x = x + ul.x/* - ox */; pixpoint.y = -y + ul.y + oy; // Check bounds on the call (P Space). Mutate if needed. if (pixpoint.x > (int) ProjMath.roundAdjust(world.x / 2.0)) { pixpoint.x = (int) ProjMath.roundAdjust(world.x / 2.0); } else if (pixpoint.x < (int) ProjMath.roundAdjust(-world.x / 2.0)) { pixpoint.x = (int) ProjMath.roundAdjust(-world.x / 2.0); } if (pixpoint.y > (int) ProjMath.roundAdjust(world.y / 2.0)) { pixpoint.y = (int) ProjMath.roundAdjust(world.y / 2.0); } else if (pixpoint.y < (int) ProjMath.roundAdjust(-world.y / 2.0)) { pixpoint.y = (int) ProjMath.roundAdjust(-world.y / 2.0); } // normalize_latitude on the way out. float lat_ = normalize_latitude((float) ((double) pixpoint.y / (double) spps_y)); ret_val.setLatitude(ProjMath.radToDeg(lat_)); // longitude is wrapped as usual. ret_val.setLongitude(ProjMath.radToDeg((float) ((double) pixpoint.x / (double) spps_x) + ctrLon)); return ret_val; } /** * Called when some fundamental parameters change. * <p> * Each projection will decide how to respond to this change. For * instance, they may need to recalculate "constant" paramters * used in the forward() and inverse() calls. * <p> * */ protected void computeParameters() { int w, h; if (ul == null) ul = new Point(0, 0); //HACK // quick calculate the maxscale maxscale = CADRG_calc_maxscale(); if (scale > maxscale) scale = maxscale; // Compute the "ADRG" scale, which gets used below. double adrgscale = 1000000.0 / scale; // 1 million (from ADRG // spec) if (adrgscale > CADRG_SCALE_LIMIT) { Debug.message("proj", "CADRG: adrgscale > CADRG_SCALE_LIMIT"); adrgscale = CADRG_SCALE_LIMIT; } // Compute the y pixel constant based on scale. y_pix_constant = CADRG_y_pix_constant(adrgscale); if (Debug.debugging("proj")) { Debug.output("Y pix constant = " + y_pix_constant); } // What zone are we in? zone = getZone(ProjMath.radToDeg(ctrLat), y_pix_constant); if (Debug.debugging("proj")) { Debug.output("Zone = " + zone); } // Compute the x pixel constant, based on scale and zone. x_pix_constant = CADRG_x_pix_constant(adrgscale, zone); if (Debug.debugging("proj")) { Debug.output("x_pix_constant = " + x_pix_constant); } // Now I can compute the world coordinate. if (world == null) world = new Point(0, 0); world.x = (int) ProjMath.roundAdjust(x_pix_constant); world.y = (int) ProjMath.roundAdjust(y_pix_constant * 4.0 / 2.0); Debug.message("proj", "world = " + world.x + "," + world.y); // Compute scaled pixels per RADIAN, not SCOORD spps_x = (double) x_pix_constant / MoreMath.TWO_PI/* MoreMath.DEG_TO_SC(360) */; spps_y = (double) y_pix_constant / MoreMath.HALF_PI/* MoreMath.DEG_TO_SC(90) */; Debug.message("proj", "spps = " + spps_x + "," + spps_y); // Fix the "small world" situation, computing ox, oy. if (width > world.x) { Debug.message("proj", "CADRG: fixing small world"); w = world.x; // ox = (int) ProjMath.roundAdjust((width - w) / 2.0); } else { w = width; // ox = 0; } if (height > world.y) { h = (int) world.y; oy = (int) ProjMath.roundAdjust((height - h) / 2.0); } else { h = height; oy = 0; } // compute the "upper left" adjustment. long temp = (long) ProjMath.roundAdjust(spps_y * ctrLat); if (Debug.debugging("proj")) { Debug.output("CADRG.temp = " + temp); } if (ul == null) ul = new Point(0, 0); ul.x = (int) ProjMath.roundAdjust(-w / 2.0); if ((temp != 0) && (oy != 0)) { ul.y = (int) ProjMath.roundAdjust(h / 2.0); } else { ul.y = (int) temp + (int) ProjMath.roundAdjust(h / 2.0); } if (Debug.debugging("proj")) { Debug.output("CADRG: ul = " + ul.x + "," + ul.y); Debug.output(/* "ox = " + ox + */" oy = " + oy); } // Finally compute some useful cylindrical projection // parameters // maxscale = (CADRG_ARC_A[0] * (1000000/width));// HACK!!! half_world = world.x / 2; if (scale > maxscale) { scale = maxscale; } // scaled_radius = planetPixelRadius/scale; Debug.message("proj", "CADRG.computeParameters(): maxscale: " + maxscale); } /** * Get the name string of the projection. */ public String getName() { return CADRGName; } /** * Given a couple of points representing a bounding box, find out * what the scale should be in order to make those points appear * at the corners of the projection. * * @param ll1 the upper left coordinates of the bounding box. * @param ll2 the lower right coordinates of the bounding box. * @param point1 a java.awt.Point reflecting a pixel spot on the * projection that matches the ll1 coordinate, the upper * left corner of the area of interest. * @param point2 a java.awt.Point reflecting a pixel spot on the * projection that matches the ll2 coordinate, usually the * lower right corner of the area of interest. */ public float getScale(LatLonPoint ll1, LatLonPoint ll2, Point point1, Point point2) { return getScale(ll1, ll2, point1, point2, 0); } /** * Given a couple of points representing a bounding box, find out * what the scale should be in order to make those points appear * at the corners of the projection. * * @param ll1 the upper left coordinates of the bounding box. * @param ll2 the lower right coordinates of the bounding box. * @param point1 a java.awt.Point reflecting a pixel spot on the * projection that matches the ll1 coordinate, the upper * left corner of the area of interest. * @param point2 a java.awt.Point reflecting a pixel spot on the * projection that matches the ll2 coordinate, usually the * lower right corner of the area of interest. * @param recursiveCount a protective count to keep this method * from getting in a recursive death spiral. */ private float getScale(LatLonPoint ll1, LatLonPoint ll2, Point point1, Point point2, int recursiveCount) { try { float deltaDegrees; float pixPerDegree; int deltaPix; float ret; float dx = Math.abs(point2.x - point1.x); float dy = Math.abs(point2.y - point1.y); float nCenterLat = Math.min(ll1.getLatitude(), ll2.getLatitude()) + Math.abs(ll1.getLatitude() - ll2.getLatitude()) / 2f; float nCenterLon = Math.min(ll1.getLongitude(), ll2.getLongitude()) + Math.abs(ll1.getLongitude() - ll2.getLongitude()) / 2f; if (dx < dy) { float dlat = Math.abs(ll1.getLatitude() - ll2.getLatitude()); deltaDegrees = dlat; deltaPix = getHeight(); pixPerDegree = getScale() * (float) getYPixConstant() / 90f; } else { float dlon; float lat1, lon1, lon2; // point1 is to the right of point2. switch the // LatLonPoints so that ll1 is west (left) of ll2. if (point1.x > point2.x) { lat1 = ll1.getLatitude(); lon1 = ll1.getLongitude(); ll1.setLatLon(ll2); ll2.setLatLon(lat1, lon1); } lon1 = ll1.getLongitude(); lon2 = ll2.getLongitude(); // allow for crossing dateline if (lon1 > lon2) { dlon = (180 - lon1) + (180 + lon2); } else { dlon = lon2 - lon1; } deltaDegrees = dlon; deltaPix = getWidth(); pixPerDegree = getPlanetPixelCircumference() / 360f; } // The new scale... ret = pixPerDegree / (deltaPix / deltaDegrees); //OK, now given the new scale at the apparent new center //location, we need to test if the zone changes, because //if it does, the values don't work out right because the //pixel spacings are different. If the zones are //different, we need to recalculate the scale based on // the //new zone. CADRG newcadrg = new CADRG(new LatLonPoint(nCenterLat, nCenterLon), ret, getWidth(), getHeight()); // Use the recursiveCount to prevent extended recalls. A // couple rounds should suffice. if (newcadrg.getZone() != zone && recursiveCount < 2) { ret = newcadrg.getScale(ll1, ll2, newcadrg.forward(ll1), newcadrg.forward(ll2), recursiveCount + 1); } return ret; } catch (NullPointerException npe) { Debug.error("ProjMath.getScale(): caught null pointer exception."); return Float.MAX_VALUE; } } /* * public static void main (String argv[]) { CADRG proj= new * CADRG(new LatLonPoint(42.0f, 0.0f), 18000000.0f, 620,480); * * Debug.output("---testing latitude"); proj.testPoint(0.0f, * 0.0f); proj.testPoint(10.0f, 0.0f); proj.testPoint(-10.0f, * 0.0f); proj.testPoint(23.1234f, 0.0f); * proj.testPoint(-23.1234f, 0.0f); proj.testPoint(90.0f, 0.0f); * proj.testPoint(-100.0f, 0.0f); * * Debug.output("---testing longitude"); proj.testPoint(0.0f, * 10.0f); proj.testPoint(0.0f, -10.0f); proj.testPoint(0.0f, * 86.45f); proj.testPoint(0.0f, -86.45f); proj.testPoint(0.0f, * 375.0f); proj.testPoint(0.0f, -375.0f); } * * private void testPoint(float lat, float lon) { LatLonPoint * llpoint = new LatLonPoint(ProjMath.radToDeg( * normalize_latitude(ProjMath.degToRad(lat))), lon); Point point = * forward(llpoint); * * Debug.output("(lon="+llpoint.getLongitude()+ * ",lat="+llpoint.getLatitude()+ ") = * (x="+point.x+",y="+point.y+")"); * * llpoint = inverse(point); * * Debug.output("(x="+point.x+",y="+point.y+") = (lon="+ * llpoint.getLongitude()+",lat="+ llpoint.getLatitude()+")"); } */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -