📄 gnomonic.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/Gnomonic.java,v $// $RCSfile: Gnomonic.java,v $// $Revision: 1.5.2.2 $// $Date: 2004/10/14 18:27:36 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.proj;import java.awt.*;import com.bbn.openmap.LatLonPoint;import com.bbn.openmap.MoreMath;import com.bbn.openmap.util.Debug;/** * Implements the Gnomonic projection. */public class Gnomonic extends Azimuth { /** * The Gnomonic name. */ public final static transient String GnomonicName = "Gnomonic"; /** * The Gnomonic type of projection. */ public final static transient int GnomonicType = 12; protected int hy, wx; // almost constant projection parameters protected float cosCtrLat; protected float sinCtrLat; public final static transient float epsilon = 0.0001f; public final static transient float HEMISPHERE_EDGE = (float) ((Math.PI / 180d) * 80d);//80degrees public final static transient float hPrime = 1f / (float) Math.pow(Math.cos(HEMISPHERE_EDGE), 2d); protected final static float NORTH_BOUNDARY = NORTH_POLE - epsilon; protected final static float SOUTH_BOUNDARY = -NORTH_BOUNDARY; /** * Construct a Mercator projection. * * @param center LatLonPoint center of projection * @param scale float scale of projection * @param width width of screen * @param height height of screen * */ public Gnomonic(LatLonPoint center, float scale, int width, int height) { super(center, scale, width, height, GnomonicType); setMinScale(1000.0f); } /** * Return stringified description of this projection. * * @return String * @see Projection#getProjectionID * */ public String toString() { return "Gnomonic[" + super.toString(); } /** * 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() { Debug.message("proj", "Gnomonic.computeParameters()"); super.computeParameters(); // minscale is the minimum scale allowable (before integer // wrapping // can occur) minscale = (float) Math.ceil((2 * hPrime * planetPixelRadius) / (int) Integer.MAX_VALUE); if (minscale < 1) minscale = 1; if (scale < minscale) scale = minscale; // maxscale = scale at which a world hemisphere fits in the // window maxscale = (width < height) ? (float) (planetPixelRadius * 2 * hPrime) / (float) width : (float) (planetPixelRadius * 2 * hPrime) / (float) height; if (maxscale < minscale) { maxscale = minscale; } if (scale > maxscale) { scale = maxscale; } scaled_radius = planetPixelRadius / scale; // width of the world in pixels at current scale. We see only // one hemisphere. world.x = (int) ((planetPixelRadius * 2 * hPrime) / scale); // calculate cutoff scale for XWindows workaround XSCALE_THRESHOLD = (int) ((planetPixelRadius * 2 * hPrime) / 64000);//fudge // it a // little // bit // do some precomputation of stuff cosCtrLat = (float) Math.cos(ctrLat); sinCtrLat = (float) Math.sin(ctrLat); // compute the offsets hy = height / 2; wx = width / 2; } /** * Draw the background for the projection. * * @param g Graphics2D * @param paint java.awt.Paint to use for the background */ public void drawBackground(Graphics2D g, java.awt.Paint paint) { g.setPaint(paint); drawBackground(g); } /** * Assume that the Graphics has been set with the Paint/Color * needed, just render the shape of the background. */ public void drawBackground(Graphics g) { g.fillRect(0, 0, getWidth(), getHeight()); } /** * Sets radian latitude to something sane. This is an abstract * function since some projections don't deal well with extreme * latitudes. * <p> * * @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_BOUNDARY) { return NORTH_BOUNDARY; } else if (lat < SOUTH_BOUNDARY) { return SOUTH_BOUNDARY; } return lat; } /** * Get the distance c of the point from the center of the * hemisphere. * * @param phi1 latitude * @param lambda0 longitude * @param phi latitude * @param lambda longitude * @return float c angular distance in radians * */ final public static float hemisphere_distance(float phi1, float lambda0, float phi, float lambda) { return GreatCircle.spherical_distance(phi1, lambda0, phi, lambda)/*-epsilon*/; } /** * Check if a given lat/lon is within the visible hemisphere. * * @param phi1 latitude * @param lambda0 longitude * @param phi latitude * @param lambda longitude * @return boolean true if within the visible hemisphere, false if * not * */ final public static boolean hemisphere_clip(float phi1, float lambda0, float phi, float lambda) { return (GreatCircle.spherical_distance(phi1, lambda0, phi, lambda)/*-epsilon*/<= HEMISPHERE_EDGE); } /** * Calculate point along edge of hemisphere (using center point * and current azimuth). * <p> * This is invoked for points that aren't visible in the current * hemisphere. * * @param p Point * @return Point p * */ private Point edge_point(Point p, float current_azimuth) { float c = HEMISPHERE_EDGE; LatLonPoint tmpll = GreatCircle.spherical_between(ctrLat, ctrLon, c/*-epsilon*/, current_azimuth); float phi = tmpll.radlat_; float lambda = tmpll.radlon_; float kPrime = 1f / (float) Math.cos(c); float cosPhi = (float) Math.cos(phi); float sinPhi = (float) Math.sin(phi); float lambdaMinusCtrLon = (float) (lambda - ctrLon); float cosLambdaMinusCtrLon = (float) Math.cos(lambdaMinusCtrLon); float sinLambdaMinusCtrLon = (float) Math.sin(lambdaMinusCtrLon); p.x = (int) (scaled_radius * kPrime * cosPhi * sinLambdaMinusCtrLon) + wx; p.y = hy - (int) (scaled_radius * kPrime * (cosCtrLat * sinPhi - sinCtrLat * cosPhi * cosLambdaMinusCtrLon)); return p; } /** * Checks if a LatLonPoint is plot-able. * <p> * A point is plot-able if it is within the visible hemisphere. * * @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)); lon = wrap_longitude(ProjMath.degToRad(lon)); return hemisphere_clip(ctrLat, ctrLon, lat, lon); } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -