📄 projmath.java
字号:
return rads; } /** * Normalizes radian latitude. Normalizes latitude if at or exceeds epsilon * distance from a pole. * * @param lat float latitude in radians * @param epsilon epsilon (>= 0) radians distance from pole * @return float latitude (-PI/2 <= phi <= PI/2) * @see Proj#normalize_latitude(float) * @see com.bbn.openmap.LatLonPoint#normalize_latitude(float) */ public final static float normalize_latitude(float lat, float epsilon) { if (lat > NORTH_POLE_F - epsilon) { return NORTH_POLE_F - epsilon; } else if (lat < SOUTH_POLE_F + epsilon) { return SOUTH_POLE_F + epsilon; } return lat; } /** * Normalizes radian latitude. Normalizes latitude if at or exceeds epsilon * distance from a pole. * * @param lat double latitude in radians * @param epsilon epsilon (>= 0) radians distance from pole * @return double latitude (-PI/2 <= phi <= PI/2) * @see Proj#normalize_latitude(float) * @see com.bbn.openmap.LatLonPoint#normalize_latitude(float) */ public final static double normalize_latitude(double lat, double epsilon) { if (lat > NORTH_POLE_D - epsilon) { return NORTH_POLE_D - epsilon; } else if (lat < SOUTH_POLE_D + epsilon) { return SOUTH_POLE_D + epsilon; } return lat; } /** * Sets radian longitude to something sane. * * @param lon float longitude in radians * @return float longitude (-PI <= lambda < PI) * @see com.bbn.openmap.LatLonPoint#wrap_longitude(float) */ public final static float wrap_longitude(float lon) { if ((lon < -DATELINE_F) || (lon > DATELINE_F)) { lon += DATELINE_F; lon = (lon % LON_RANGE_F); lon += (lon < 0) ? DATELINE_F : -DATELINE_F; } return lon; } /** * Sets radian longitude to something sane. * * @param lon double longitude in radians * @return double longitude (-PI <= lambda < PI) * @see #wrap_longitude(float) */ public final static double wrap_longitude(double lon) { if ((lon < -DATELINE_D) || (lon > DATELINE_D)) { lon += DATELINE_D; lon = (lon % LON_RANGE_D); lon += (lon < 0) ? DATELINE_D : -DATELINE_D; } return lon; } /** * Converts units (km, nm, miles, etc) to decimal degrees for a spherical * planet. This does not check for arc distances > 1/2 planet * circumference, which are better represented as (2pi - calculated arc). * * @param u units float value * @param uCircumference units circumference of planet * @return float decimal degrees */ public final static float sphericalUnitsToDeg(float u, float uCircumference) { return 360f * (u / uCircumference); } /** * Converts units (km, nm, miles, etc) to arc radians for a spherical * planet. This does not check for arc distances > 1/2 planet * circumference, which are better represented as (2pi - calculated arc). * * @param u units float value * @param uCircumference units circumference of planet * @return float arc radians */ public final static float sphericalUnitsToRad(float u, float uCircumference) { return MoreMath.TWO_PI * (u / uCircumference); } /** * Calculate the geocentric latitude given a geographic latitude. According * to John Synder: <br> * "The geographic or geodetic latitude is the angle which a line * perpendicular to the surface of the ellipsoid at the given point makes * with the plane of the equator. ...The geocentric latitude is the angle * made by a line to the center of the ellipsoid with the equatorial plane". ( * <i>Map Projections --A Working Manual </i>, p 13) * <p> * Translated from Ken Anderson's lisp code <i>Freeing the Essence of * Computation </i> * * @param lat float geographic latitude in radians * @param flat float flatening factor * @return float geocentric latitude in radians * @see #geographic_latitude */ public final static float geocentric_latitude(float lat, float flat) { float f = 1.0f - flat; return (float) Math.atan((f * f) * (float) Math.tan(lat)); } /** * Calculate the geographic latitude given a geocentric latitude. Translated * from Ken Anderson's lisp code <i>Freeing the Essence of Computation </i> * * @param lat float geocentric latitude in radians * @param flat float flatening factor * @return float geographic latitude in radians * @see #geocentric_latitude */ public final static float geographic_latitude(float lat, float flat) { float f = 1.0f - flat; return (float) Math.atan((float) Math.tan(lat) / (f * f)); } /** * 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 projection the projection to use for other projection parameters, * like map width and map height. */ public static float getScale(com.bbn.openmap.LatLonPoint ll1, com.bbn.openmap.LatLonPoint ll2, Projection projection) { if (projection == null) { return Float.MAX_VALUE; } java.awt.Point point1 = projection.forward(ll1); java.awt.Point point2 = projection.forward(ll2); return getScale(ll1, ll2, point1, point2, projection); } /** * 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 point1 a java.awt.Point reflecting a pixel spot on the projection, * usually the upper left corner of the area of interest. * @param point2 a java.awt.Point reflecting a pixel spot on the projection, * usually the lower right corner of the area of interest. * @param projection the projection to use for other projection parameters, * like map width and map height. */ public static float getScale(java.awt.Point point1, java.awt.Point point2, Projection projection) { if (projection == null) { return Float.MAX_VALUE; } com.bbn.openmap.LatLonPoint ll1 = projection.inverse(point1); com.bbn.openmap.LatLonPoint ll2 = projection.inverse(point2); return getScale(ll1, ll2, point1, point2, projection); } /** * 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 projection the projection to use to query to get the scale for, * for projection type and height and width. */ protected static float getScale(com.bbn.openmap.LatLonPoint ll1, com.bbn.openmap.LatLonPoint ll2, java.awt.Point point1, java.awt.Point point2, Projection projection) { return projection.getScale(ll1, ll2, point1, point2); } /* * public static void main(String[] args) { float degs = * sphericalUnitsToRad( Planet.earthEquatorialRadius/2, * Planet.earthEquatorialRadius); Debug.output("degs = " + degs); float * LAT_DEC_RANGE = 90.0f; float LON_DEC_RANGE = 360.0f; float lat, lon; for * (int i = 0; i < 100; i++) { lat = * com.bbn.openmap.LatLonPoint.normalize_latitude( * (float)Math.random()*LAT_DEC_RANGE); lon = * com.bbn.openmap.LatLonPoint.wrap_longitude( * (float)Math.random()*LON_DEC_RANGE); Debug.output( "(" + lat + "," + lon + ") : (" + * degToRad(lat) + "," + degToRad(lon) + ") : (" + radToDeg(degToRad(lat)) + * "," + radToDeg(degToRad(lon)) + ")"); } } */ /** * Generic test for seeing if an left longitude value and a right longitude * value seem to constitute crossing the dateline. * * @param leftLon the leftmost longitude, in decimal degrees. Expected to * represent the location of the left side of a map window. * @param rightLon the rightmost longitude, in decimal degrees. Expected to * represent the location of the right side of a map window. * @param projScale the projection scale, considered if the two values are * very close to each other and leftLon less than rightLon. * @return true if it seems like these two longitude values represent a * dateline crossing. */ public static boolean isCrossingDateline(double leftLon, double rightLon, float projScale) { // if the left longiude is greater than the right, we're obviously // crossing the dateline. If they are approximately equal, we could be // showing the whole earth, but only if the scale is significantly // large. If the scale is small, we could be really zoomed in. return ((leftLon > rightLon) || (MoreMath.approximately_equal(leftLon, rightLon, .001f) && projScale > 1000000f)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -