📄 geopoint.java
字号:
return !Double.isNaN(radians)? ((EARTH_MEAN_RADIUS_KM * 1000.0) * radians) : Double.NaN; } // ------------------------------------------------------------------------ /** *** Returns a GeoPoint object containing 'delta' Latitude/Longitude values which *** represent a 'bounding-box' for this GeoPoint with the specified radius (in meters). *** That is, this GeoPoint Latitude/Longitude +/- the returned 'delta' Latitude/Longitude, *** represent a bounding area for this GeoPoint and the specified meter radius. *** @param radiusMeters The radius in meters *** @return The 'delta' Latitude/Longitude GeoPoint **/ public GeoPoint getRadiusDeltaPoint(double radiusMeters) { double a = EARTH_EQUATORIAL_RADIUS_KM * 1000.0; double b = EARTH_POLOR_RADIUS_KM * 1000.0; double lat = this.getLatitudeRadians(); // r(T) = (a^2) / sqrt((a^2)*(cos(T)^2) + (b^2)*(sin(T)^2)) double r = SQ(a) / Math.sqrt((SQ(a) * SQ(Math.cos(lat))) + (SQ(b) * SQ(Math.sin(lat)))); // dlat = (180 * R) / (PI * r); double dlat = (180.0 * radiusMeters) / (Math.PI * r); // dlon = dlat / cos(lat); double dlon = dlat / Math.cos(lat); return new GeoPoint(dlat, dlon); } // ------------------------------------------------------------------------ private static String DIRECTION[] = { NORTH_ABBR, NE_ABBR, EAST_ABBR, SE_ABBR, SOUTH_ABBR, SW_ABBR, WEST_ABBR, NW_ABBR }; /** *** Returns a String representation of the spedified compass heading value *** @param heading The compass heading value to convert to a String representation *** @return A Strinng representation of the compas heading (ie. "N", "NE", "E", "SE", "S", "SW", "W", "NW") **/ public static String GetHeadingString(double heading) { if (!Double.isNaN(heading) && (heading >= 0.0)) { int h = (int)Math.round(heading / 45.0) % 8; return DIRECTION[(h > 7)? 0 : h]; } else { return ""; } } /** *** Returns the compass heading that would be followed if travelling from this GeoPoint to *** the specified GeoPoint **/ public double headingToPoint(GeoPoint dest) { // Assistance from: // http://mathforum.org/library/drmath/view/55417.html // http://williams.best.vwh.net/avform.htm try { double lat1 = this.getLatitudeRadians(), lon1 = this.getLongitudeRadians(); double lat2 = dest.getLatitudeRadians(), lon2 = dest.getLongitudeRadians(); double dist = this.radiansToPoint(dest); double rad = Math.acos((Math.sin(lat2) - (Math.sin(lat1) * Math.cos(dist))) / (Math.sin(dist) * Math.cos(lat1))); if (Math.sin(lon2 - lon1) < 0) { rad = (2.0 * Math.PI) - rad; } double deg = rad / RADIANS; return deg; } catch (Throwable t) { // trap any Math error Print.logException("headingToPoint", t); return 0.0; } } // ------------------------------------------------------------------------ /** *** Returns a String representation of this GeoPoint *** @return A String representation of this GeoPoint **/ public String toString() { return this.toString(PointSeparatorChar); } /** *** Returns a String representation of this GeoPoint *** @param sep The character used to separate the Latitude from the Longitude *** @return A String representation of this GeoPoint **/ public String toString(char sep) { return this.getLatitudeString() + sep + this.getLongitudeString(); } /** *** Returns a String representation of this GeoPoint *** @param decFormat The output format of the Latitude/Longitude values *** @return A String representation of this GeoPoint **/ public String toString(String decFormat) { return this.toString(decFormat, PointSeparatorChar); } /** *** Returns a String representation of this GeoPoint *** @param decFormat The output format of the Latitude/Longitude values *** @param sep The character used to separate the Latitude from the Longitude *** @return A String representation of this GeoPoint **/ public String toString(String decFormat, char sep) { return this.getLatitudeString(decFormat) + sep + this.getLongitudeString(decFormat); } /** *** Returns a String representation of this GeoPoint *** @param dms True to output the Latitude/Longitude values in degrees/minutes/seconds *** @return A String representation of this GeoPoint **/ public String toString(boolean dms) { return this.toString(dms, PointSeparatorChar); } /** *** Returns a String representation of this GeoPoint *** @param dms True to output the Latitude/Longitude values in degrees/minutes/seconds *** @param sep The character used to separate the Latitude from the Longitude *** @return A String representation of this GeoPoint **/ public String toString(boolean dms, char sep) { return this.getLatitudeString(dms) + sep + this.getLongitudeString(dms); } // ------------------------------------------------------------------------ /** *** Returns true if this GeoPoint is equivalent to the other Object *** @return True if this GeoPoint is equivalent to the other Object **/ public boolean equals(Object other) { if (other instanceof GeoPoint) { GeoPoint gp = (GeoPoint)other; double deltaLat = Math.abs(gp.getLatitude() - this.getLatitude() ); double deltaLon = Math.abs(gp.getLongitude() - this.getLongitude()); return ((deltaLat < EPSILON) && (deltaLon < EPSILON)); } else { return false; } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /** *** Converts the specified degrees/minutes/seconds into degrees *** @param deg The degrees *** @param min The minutes *** @param sec The seconds *** @return Decimal degrees **/ public static double convertDmsToDec(int deg, int min, int sec) { return GeoPoint.convertDmsToDec((double)deg, (double)min, (double)sec); } /** *** Converts the specified degrees/minutes/seconds into degrees *** @param deg The degrees *** @param min The minutes *** @param sec The seconds *** @return Decimal degrees **/ public static double convertDmsToDec(double deg, double min, double sec) { double sign = (deg >= 0.0)? 1.0 : -1.0; double d = Math.abs(deg); double m = Math.abs(min / 60.0); double s = Math.abs(sec / 3600.0); return sign * (d + m + s); } // ------------------------------------------------------------------------ /** *** Formats the specified coordinate based on the default decimal format value. *** @param location The coordinate to format *** @return The String formatted coordinate **/ public static String formatCoord(double location) { return GeoPoint.formatCoord(location, FORMAT_DEC); } /** *** Formats the specified coordinate based on the default decimal format value. *** @param loc The coordinate to format *** @param fmt A degrees/minutes/seconds formatting mask. (logically 'or'ed: ** 'FORMAT_DMS' to format in degrees/minutes/seconds format, *** 'FORMAT_LATITUDE' to include N/S specification on Latitude, *** 'FORMAT_LONGITUDE' to include E/W specification on Latitude.) *** @return The String formatted coordinate **/ public static String formatCoord(double loc, int fmt) { if ((fmt & FORMAT_TYPE_MASK) == FORMAT_DMS) { int sgn = (loc >= 0.0)? 1 : -1; double abs = Math.abs(loc); int deg = (int)abs; double accum = (abs - (double)deg) * 60.0; int min = (int)accum; accum = (accum - (double)min) * 60.0; int sec = (int)accum; StringBuffer sb = new StringBuffer(); sb.append(StringTools.format(deg,"##0")).append("-"); sb.append(StringTools.format(min,"00")).append("'"); sb.append(StringTools.format(sec,"00")).append("\""); if ((fmt & FORMAT_AXIS_MASK) == FORMAT_LATITUDE) { sb.append((sgn >= 0)? NORTH_ABBR : SOUTH_ABBR); } else if ((fmt & FORMAT_AXIS_MASK) == FORMAT_LONGITUDE) { sb.append((sgn >= 0)? EAST_ABBR : WEST_ABBR); } return sb.toString(); } else { // NOTE: European locale may attempt to format this value with "," instead of "." // This needs to be "." in order to work for CSV files, etc. return StringTools.format(loc, "###0.00000"); } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /** *** GeoBounds class **/ public static class GeoBounds { private GeoPoint centerGP = null; private double vertMeters = 0.0; private double horzMeters = 0.0; private double scale = -1.0; public GeoBounds(GeoPointProvider gpp[]) { if ((gpp == null) || (gpp.length == 0)) { this.centerGP = new GeoPoint(); this.scale = 0.0; } else if (gpp.length == 1) { this.centerGP = gpp[0].getGeoPoint(); this.scale = 1.0; } else { double maxLat = -90.0, maxLon = -180.0; double minLat = 90.0, minLon = 180.0; for (int i = 0; i < gpp.length; i++) { GeoPoint gp = gpp[i].getGeoPoint(); double lat = gp.getLatitude(); double lon = gp.getLongitude(); if (lat > maxLat) { maxLat = lat; } if (lat < minLat) { minLat = lat; } if (lon > maxLon) { maxLon = lon; } if (lon < minLon) { minLon = lon; } } this.centerGP = new GeoPoint((minLat + maxLat) / 2.0, (minLon + maxLon) / 2.0); GeoPoint baseGP = new GeoPoint(minLat,minLon); this.vertMeters = baseGP.metersToPoint(new GeoPoint(maxLat,minLon)); this.horzMeters = baseGP.metersToPoint(new GeoPoint(minLat,maxLon)); } } public GeoPoint getCenter() { return this.centerGP; } public double getMetersPerPixel(int pixelW, int pixelH) { double vertMPP = this.vertMeters / (double)pixelH; double horzMPP = this.horzMeters / (double)pixelW; return (vertMPP > horzMPP)? vertMPP : horzMPP; } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ private static GeozoneChecker geozoneCheck = null; /** *** Returns an object that implements the GeozoneChecker interface implementing a point/radius *** geozone check. *** @return A object implementing the GeozoneChecker interface. **/ public static GeozoneChecker getGeozoneChecker() { if (geozoneCheck == null) { geozoneCheck = new GeozoneChecker() { public boolean containsPoint(GeoPoint gpTest, GeoPoint gpList[], double radiusKM) { if ((gpList != null) && (gpTest != null)) { for (int i = 0; i < gpList.length; i++) { double km = gpList[i].kilometersToPoint(gpTest); //Print.logInfo("Inside? (" + km + " <= " + radiusKM + ")?"); if (km <= radiusKM) { return true; } } } return false; } }; } return geozoneCheck; } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /** *** Testing/debugging command-line entry point *** @param argv The command-line arguments. **/ public static void main(String argv[]) { RTConfig.setCommandLineArgs(argv); /* encode/decode test */ GeoPoint gp = new GeoPoint(RTConfig.getString("gp","")); if (gp.isValid()) { byte gpEnc[] = new byte[8]; encodeGeoPoint(gp, gpEnc, 0, 8); GeoPoint gp8 = decodeGeoPoint(gpEnc, 0, 8); Print.logInfo("8-byte encoded/decoded GeoPoint = " + gp8); encodeGeoPoint(gp, gpEnc, 0, 6); GeoPoint gp6 = decodeGeoPoint(gpEnc, 0, 6); Print.logInfo("6-byte encoded/decoded GeoPoint = " + gp6); System.exit(0); } /* distance between points */ GeoPoint gp1 = new GeoPoint(RTConfig.getString("gp1","")); GeoPoint gp2 = new GeoPoint(RTConfig.getString("gp2","")); if (gp1.isValid() && gp2.isValid()) { double km = gp1.kilometersToPoint(gp2); Print.logInfo("Distance = " + km + " km"); long deltaSec = RTConfig.getLong("deltaSec", 0L); if (deltaSec > 0L) { double kph = km / ((double)deltaSec / 3600.0); Print.logInfo("Speed = " + kph + " kph [" + (kph * MILES_PER_KILOMETER) + " mph]"); } System.exit(0); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -