📄 cadrg.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/proj/CADRG.java,v $// $RCSfile: CADRG.java,v $// $Revision: 1.4.2.3 $// $Date: 2005/08/09 21:17:54 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.proj;import java.awt.Point;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.MoreMath;import com.bbn.openmap.util.Debug;/** * Implements the CADRG projection. This is really an Equal Arc * Projection with pixel spacings as dictated by the RPF * specification. */public class CADRG extends Cylindrical implements EqualArc { /** * The CADRG name. */ public final static transient String CADRGName = "CADRG"; /** * The CADRG type of projection. */ public final static transient int CADRGType = 42; public final static transient float epsilon = 0.0001f; // HACK -degrees private static final float NORTH_LIMIT = ProjMath.degToRad(80.0f); private static final float SOUTH_LIMIT = -NORTH_LIMIT; private double spps_x, spps_y; // scaled pixels per SCoord private static final int CADRG_ARC_A[] = { 369664, 302592, 245760, 199168, 163328, 137216, 110080, 82432 }; private static final double CADRG_SCALE_LIMIT = 2000.0; private static final int CADRG_get_zone_old_extents[] = { 32, 48, 56, 64, 68, 72, 76, 80, 90 }; private int /* ox, */oy; private double x_pix_constant, y_pix_constant; private Point ul;//upper left private float[] lower_zone_extents; private float[] upper_zone_extents; private int zone; /** * Construct a CADRG projection. * * @param center LatLonPoint center of projection * @param scale float scale of projection * @param width width of screen * @param height height of screen */ public CADRG(LatLonPoint center, float scale, int width, int height) { super(center, scale, width, height, CADRGType); minscale = (float) 1000000 / (float) CADRG_SCALE_LIMIT; } /** * Sets radian latitude to something sane. This is an abstract * function since some projections don't deal well with extreme * latitudes. * * @param lat float latitude in radians * @return float latitude (-PI/2 <= y <= PI/2) * @see com.bbn.openmap.LatLonPoint#normalize_latitude(float) * */ public float normalize_latitude(float lat) { if (lat > NORTH_LIMIT) { lat = NORTH_LIMIT; } else if (lat < SOUTH_LIMIT) { lat = SOUTH_LIMIT; } return lat; } // protected void finalize() { // Debug.message("proj", "CADRG finialized"); // } /** * Return stringified description of this projection. * <p> * * @return String * @see Projection#getProjectionID * */ public String toString() { return "CADRG[ spps_x=" + spps_x + " spps_y=" + spps_y + " x_pix=" + x_pix_constant + " y_pix=" + y_pix_constant + /* " ox=" + ox + */" oy=" + oy + " ul(" + ul.x + "," + ul.y + ")" + super.toString(); } /** * Returns the current zone of the projection. Zone number starts * at 1, goes to 8, per the RPF specification. We don't handle * zone 9 (polar). * * @return the zone of the projection. */ public int getZone() { return zone; } /** * Given a letter for a zone, return the CADRG zone equivalent, */ public static int getProjZone(char asciiZone) { int z = (int) asciiZone; if (z == 74) z--; // Fix J to a zone. if (z > 64) z -= 64; // Below the equator else z -= 48; // Above the equator // Now we should have a number, of a zone 1-9 return z; } /** * Get the planet pixel circumference. * * @return float circumference of planet in pixels */ public float getPlanetPixelCircumference() { // Why this algorithm? Well, the CADRG_ARC_A is a pixel count // that needs to be multiplied by 1000000 to normalize it // against the 1:1M factor reflected in the array values. The // 1.5 factor was tossed in there because it was showing up in // other calculations as that 100/150 thing. It works in // tests. return (1000000 * (float) CADRG_ARC_A[zone - 1]) / 1.5f; // These are the same things... // return (float)getXPixConstant() * scale; // This is what the default return value is from the super // class. // return planetPixelCircumference; // the standard return for // projections... } /** * Returns the zone based on the y_pix_constant and a latitude. * <p> * HACK: latitude in decimal degrees DO THE CONSTANTS DEPEND ON * THIS?!! * <p> * * @param lat latitude * @param y_pix_constant pixel constant * */ private int getZone(double lat, double y_pix_constant) { int NOT_SET = -1; int ret = NOT_SET; double delta; double upper_lat, lower_lat; int x; double pivot; /** Pixels per degree */ double ppd = y_pix_constant / 90; if (upper_zone_extents == null) { upper_zone_extents = new float[CADRG_get_zone_old_extents.length]; } if (lower_zone_extents == null) { lower_zone_extents = new float[CADRG_get_zone_old_extents.length + 1]; } /** * Delta*2 is the number of degrees for the height of the * projection. */ if (y_pix_constant == 0) delta = 0; else delta = height / 2.0 * 90.0 / y_pix_constant; Debug.message("proj", "height = " + height); upper_lat = Math.abs(Math.abs(lat) + delta); lower_lat = Math.abs(Math.abs(lat) - delta); Debug.message("proj", "upper_lat = " + upper_lat); Debug.message("proj", "lower_lat = " + lower_lat); lower_zone_extents[0] = 0f; lower_zone_extents[8] = 80f; upper_zone_extents[8] = 90f; // figure out new extents - from CADRG spec for (x = 0; x < CADRG_get_zone_old_extents.length - 1/* 8 */; x++) { pivot = ppd * CADRG_get_zone_old_extents[x] / 1536.0; pivot = Math.floor(pivot); Debug.message("proj", "pivot = " + pivot); lower_zone_extents[x + 1] = (float) (pivot * 1536.0 / ppd); // Can't go further than the equator. // if (x == 0) lower_zone_extents[x] = 0; pivot++; upper_zone_extents[x] = (float) (pivot * 1536.0 / ppd); Debug.message("proj", "lower_zone_extents[" + x + "] = " + lower_zone_extents[x]); Debug.message("proj", "upper_zone_extents[" + x + "] = " + upper_zone_extents[x]); if ((lower_lat <= (double) upper_zone_extents[x]) && (upper_lat <= (double) upper_zone_extents[x]) && ret == NOT_SET) ret = x + 1; } if (ret == NOT_SET) ret = CADRG_get_zone_old_extents.length - 1; return ret; } /** * Returns the x pixel constant of the projection. This was * calcuated when the projection was created. Represents the * number of pixels around the earth (360 degrees). */ public double getXPixConstant() { return x_pix_constant; } /** * Returns the y pixel constant of the projection. This was * calcuated when the projection was created. Represents the * number of pixels from 0 to 90 degrees. */ public double getYPixConstant() { return y_pix_constant; } /** * Returns the upper zone extent for the given zone at the current * scale. This only makes sense if the projection is at the same * scale as the chart data you are interested in. */ public float getUpperZoneExtent(int zone) { if (zone < 1) zone = 1; if (zone > 8) zone = 9; return upper_zone_extents[zone - 1]; } /** * Returns the lower zone extent for the given zone at the current * scale. This only makes sense if the projection is at the same * scale as the chart data you are interested in. */ public float getLowerZoneExtent(int zone) { if (zone < 1) zone = 1; if (zone > 8) zone = 9; return lower_zone_extents[zone - 1]; } /** * Return the number of horizontal frame files that will fit * around the world in the current zone. This only makes sense if * the projection is at the same scale as the chart data you are * interested in. * * @return number of frame columes in the current zone, to go * around the world. */ public int numHorizontalFrames() { return (int) Math.ceil(x_pix_constant / (1536.0)); } /** * Return the number of vertical frame files that will fit within * the current zone, overlaps included. This only makes sense if * the projection is at the same scale as the chart data you are * interested in. * * @return number of frame rows in the current zone. */ public int numVerticalFrames() { return (int) Math.round((upper_zone_extents[zone - 1] - lower_zone_extents[zone - 1]) * (y_pix_constant / 90.0) / (1536.0)); } /** * Figures out the number of pixels around the earth, for 360 * degrees. * <p> * * @param adrgscale The scale adjusted to 1:1M (1M/real scale) * @param zone ADRG zone * @return The number of pixels around the equator (360 degrees) */ private double CADRG_x_pix_constant(double adrgscale, int zone) { // E-W pixel constant double x_pix = (double) adrgscale * CADRG_ARC_A[zone - 1] / 512.0; // Increase, if necessary, to the next highest integer value x_pix = Math.ceil(x_pix); x_pix = x_pix * 1.33333;//(512*100)/(150*256); // Round the final result. x_pix = Math.round(x_pix); return x_pix * 256.0; } /** * Calculate the maximum allowable scale. * <p> * * @return float maxscale * */ private float CADRG_calc_maxscale() { // Why 1.5? It was 150/100? Why? return (1000000 * (float) CADRG_ARC_A[0]) / (width * 1.5f); } /** * Returns the number of pixels from the equator to a pole. * <p> * * @param adrgscale scale adjusted to 1:1M (1M/real scale) * @return number of pixels from 0 to 90 degrees * */ private double CADRG_y_pix_constant(double adrgscale) { final int CADRG_ARC_B = 400384; double y_pix = (double) adrgscale * CADRG_ARC_B / 512.0; // Increase, if necessary, to the next highest integer value y_pix = Math.ceil(y_pix); y_pix = y_pix * 0.33333;//(512*100)/(4*150*256); // Round the final result. y_pix = Math.round(y_pix); return y_pix * 256.0; } /** * Checks if a LatLonPoint is plot-able. * <p> * A point is plot-able in the CADRG projection if it is within * the North and South zone limits. * <p> * * @param lat float latitude in decimal degrees * @param lon float longitude in decimal degrees * @return boolean */ public boolean isPlotable(float lat, float lon) { lat = normalize_latitude(ProjMath.degToRad(lat)); return ((lat - epsilon < NORTH_LIMIT) && (lat + epsilon > SOUTH_LIMIT)); } /** * Projects a point from Lat/Lon space to X/Y space. * <p> * * @param pt LatLonPoint
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -