📄 geopoint.java
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2008, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// GPS latitude/longitude and algorithms to operate on such.// ----------------------------------------------------------------------------// Change History:// 2006/03/26 Martin D. Flynn// -Initial release// 2006/04/02 Martin D. Flynn// -Changed format of lat/lon to include 5 decimal places// 2006/06/30 Martin D. Flynn// -Repackaged// 2007/02/18 Martin D. Flynn// -Added static 'isValid' method// 2007/02/25 Martin D. Flynn// -Added 'String' constructor// 2007/05/06 Martin D. Flynn// -Added 'GeoBounds' class to calculate map bounding box and scale// 2008/01/10 Martin D. Flynn// -Modified 'decodeGeoPoint' to add 0.5 be raw lat/lon before decoding to// reduce rounding error (special thanks for B. Jansen for his input on this).// 2008/04/11 Martin D. Flynn// -Updated nautical-mile conversions and abbreviations// 2008/05/14 Martin D. Flynn// -Cleaned up, removed obsolete code// ----------------------------------------------------------------------------package org.opengts.util;import java.util.*;/***** A container for a single latitude/longitude value pair**/public class GeoPoint implements Cloneable, GeoPointProvider{ // ------------------------------------------------------------------------ private static boolean UseHaversineDistanceFormula = true; // ------------------------------------------------------------------------ protected static final double EPSILON = 1.0E-7; public static final double MAX_LATITUDE = 90.0; public static final double MIN_LATITUDE = -90.0; public static final double MAX_LONGITUDE = 180.0; public static final double MIN_LONGITUDE = -180.0; public static final String PointSeparator = "/"; public static final char PointSeparatorChar = '/'; // ------------------------------------------------------------------------ public static final int FORMAT_TYPE_MASK = 0x0F; // format type mask public static final int FORMAT_DEC = 0x01; // decimal format public static final String FORMAT_DEC_NAME = "Decimal"; // decimal format public static final int FORMAT_DMS = 0x02; // DMS format public static final String FORMAT_DMS_NAME = "Deg/Min/Sec"; // DMS format public static final int FORMAT_AXIS_MASK = 0xF0; // axis mask public static final int FORMAT_LATITUDE = 0x10; // latitude public static final int FORMAT_LONGITUDE = 0x20; // longitude // ------------------------------------------------------------------------ public static final String NORTH_NAME = "North"; public static final String NORTH_ABBR = "N"; public static final String SOUTH_NAME = "South"; public static final String SOUTH_ABBR = "S"; public static final String EAST_NAME = "East"; public static final String EAST_ABBR = "E"; public static final String WEST_NAME = "West"; public static final String WEST_ABBR = "W"; public static final String NE_ABBR = NORTH_ABBR + EAST_ABBR; public static final String NW_ABBR = NORTH_ABBR + WEST_ABBR; public static final String SE_ABBR = SOUTH_ABBR + EAST_ABBR; public static final String SW_ABBR = SOUTH_ABBR + WEST_ABBR; // ------------------------------------------------------------------------ /** *** A private function performing the 'square' of the argument *** @param X The argument to 'square' *** @return The square of X (ie. 'X' raised to the 2nd power) **/ private static double SQ(double X) { return X * X; } // ------------------------------------------------------------------------ // References: // http://www.jqjacobs.net/astro/geodesy.html // http://www.boeing-727.com/Data/fly%20odds/distance.html // http://mathforum.org/library/drmath/view/51785.html // http://mathforum.org/library/drmath/view/52070.html // http://en.wikipedia.org/wiki/Nautical_mile // http://en.wikipedia.org/wiki/Conversion_of_units // GPS Error Analysis: // http://edu-observatory.org/gps/gps_accuracy.html // http://users.erols.com/dlwilson/gps.htm // http://www.gisdevelopment.net/technology/gps/ma04123pf.htm public static final double PI = Math.PI; public static final double RADIANS = PI / 180.0; public static final double EARTH_EQUATORIAL_RADIUS_KM = 6378.1370; // Km: a public static final double EARTH_POLOR_RADIUS_KM = 6356.752314; // Km: b public static final double EARTH_MEAN_RADIUS_KM = 6371.0088; // Km: (2a + b)/3 public static final double EARTH_CIRCUMFERENCE_KM = 2.0 * PI * EARTH_MEAN_RADIUS_KM; // 40030 km public static final double EARTH_ANTIPODAL_KM = PI * EARTH_MEAN_RADIUS_KM; // 20015 km public static final double FEET_PER_MILE = 5280.0; // (exact) public static final double KILOMETERS_PER_MILE = 1.609344; // (exact) public static final double MILES_PER_KILOMETER = 1.0 / KILOMETERS_PER_MILE; // 0.621371192; public static final double METERS_PER_MILE = KILOMETERS_PER_MILE * 1000.0; // 1609.344 public static final double METERS_PER_FOOT = METERS_PER_MILE / FEET_PER_MILE; // 0.30480 public static final double FEET_PER_METER = 1.0 / METERS_PER_FOOT; // 3.280839895 public static final double FEET_PER_KILOMETER = FEET_PER_METER * 1000.0; // 3280.84 public static final double KILOMETERS_PER_NAUTICAL_MILE = 1.852; // (exact) public static final double NAUTICAL_MILES_PER_KILOMETER = 1.0 / KILOMETERS_PER_NAUTICAL_MILE; // 0.539956803 public static final double MILES_PER_NAUTICAL_MILE = MILES_PER_KILOMETER * KILOMETERS_PER_NAUTICAL_MILE; // 1.150779 public static final double NAUTICAL_MILES_PER_MILE = 1.0 / MILES_PER_NAUTICAL_MILE; // 0.868976 // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /** *** DistanceUnits enumerated type **/ public enum DistanceUnits { KILOMETERS (0, "km" , "kph" , 1.0 ), METERS (1, "meters", null , 1000.0 ), MILES (2, "miles" , "mph" , MILES_PER_KILOMETER ), FEET (3, "feet" , null , FEET_PER_KILOMETER ), NAUTICAL_MILES (4, "knots" , "knots", NAUTICAL_MILES_PER_KILOMETER ); int vv = -1; String nn = ""; String ss = ""; double mm = 1.0; DistanceUnits(int v, String n, String s, double m) { vv=v; nn=n; ss=s; mm=m; } public boolean isValue(String v) { return nn.equals(v) || this.name().equals(v) || (vv==StringTools.parseInt(v,-1)); } public int getValue() { return vv; } public String toDistanceAbbr() { return nn; } public String toSpeedAbbr() { return ss; } public double toKilometers( double v) { return v / mm; } public double fromKilometers(double v) { return v * mm; } }; // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ /** *** Returns true if the specified latitude/longitude are valid, false otherwise *** @param lat The latitude *** @param lon The longitude *** @return True if the specified latitude/longitude are valid, false otherwise **/ public static boolean isValid(double lat, double lon) { double latAbs = Math.abs(lat); double lonAbs = Math.abs(lon); if (latAbs >= MAX_LATITUDE) { // valid latitude return false; } else if (lonAbs >= MAX_LONGITUDE) { // invalid longitude return false; } else if ((latAbs <= 0.0002) && (lonAbs <= 0.0002)) { // small square off the coast of Africa (Ghana) return false; } else { return true; } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ private double latitude = 0.0; private double longitude = 0.0; /** *** Constructor. *** This creates a GeoPoint with latitude=0.0, and longitude=0.0 **/ public GeoPoint() { super(); this.latitude = 0.0; this.longitude = 0.0; } /** *** Copy Constructor. *** This copies the specified argument GeoPoint to this constructed GeoPoint *** @param gp The GeoPoint to copy to this constructed GeoPoint **/ public GeoPoint(GeoPoint gp) { this(); this.setLatitude(gp.getLatitude()); this.setLongitude(gp.getLongitude()); } /** *** Constructor. *** This creates a new GeoPoint with the specified latitude/longitude. *** @param latitude The latitude *** @param longitude The longitude **/ public GeoPoint(double latitude, double longitude) { this(); this.setLatitude(latitude); this.setLongitude(longitude); } /** *** Constructor. *** This creates a new GeoPoint with the specified latitude/longitude. *** @param latDeg The latitude degrees *** @param latMin The latitude minutes *** @param latSec The latitude seconds *** @param lonDeg The longitude degrees *** @param lonMin The longitude minutes *** @param lonSec The longitude seconds **/ public GeoPoint( double latDeg, double latMin, double latSec, double lonDeg, double lonMin, double lonSec) { this(); this.setLatitude( latDeg, latMin, latSec); this.setLongitude(lonDeg, lonMin, lonSec); } /** *** Constructor. *** This creates a new GeoPoint with the latitude/longitude parsed from the specified String *** @param gp The String containing the GeoPoint to parse ("latitude/longitude") **/ public GeoPoint(String gp) { this(gp, PointSeparatorChar); } /** *** Constructor. *** This creates a new GeoPoint with the latitude/longitude parsed from the specified String *** @param gp The String containing the GeoPoint to parse ("latitude/longitude") *** @param sep The character which separates the latitude from longitude **/ public GeoPoint(String gp, char sep) { // Parse "21.1234/-141.1234" this(); if (gp != null) { int p = gp.indexOf(sep); if (p >= 0) { this.setLatitude( StringTools.parseDouble(gp.substring(0,p),0.0)); this.setLongitude(StringTools.parseDouble(gp.substring(p+1),0.0)); } } } // ------------------------------------------------------------------------ /** *** Retruns a clone of this GeoPoint instance *** @return A clone of this GeoPoint **/ public Object clone() { return new GeoPoint(this); } // ------------------------------------------------------------------------ /** *** GeoPointProvider interface inplementation.<br> *** Returns this GeoPoint *** @return This GeoPoint **/ public GeoPoint getGeoPoint() { return this; } // ------------------------------------------------------------------------ /** *** Returns true if the latitude/longitude contained by the GeoPoint is valid *** @return True if the latitude/longitude contained by the GeoPoint is valid **/ public boolean isValid() { return GeoPoint.isValid(this.getLatitude(), this.getLongitude()); } // ------------------------------------------------------------------------ /** *** Sets the Latitude in degrees/minutes/seconds *** @param deg The degrees *** @param min The minutes *** @param sec The seconds **/ public void setLatitude(double deg, double min, double sec) { this.setLatitude(GeoPoint.convertDmsToDec(deg, min, sec)); } /** *** Sets the Latitude in degrees *** @param lat The Latitude **/ public void setLatitude(double lat) { this.latitude = lat; } /** *** Gets the Latitude in degrees *** @return The Latitude in degrees **/ public double getLatitude() { return this.latitude; } /** *** Gets the 'Y' coordinate (same as Latitude)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -