Wie kann ich die Entfernung messen und eine Bounding-Box basierend auf zwei Breiten- und Längengradpunkten in Java erstellen?

Ich möchte die Entfernung zwischen zwei verschiedenen Punkten finden. Das weiß ich kann man mit der Großkreisdistanz erreichen. http://www.meridianworlddata.com/Distance-calculation.asp

Sobald ich fertig bin, möchte ich mit einem Punkt und einer Entfernung den Punkt, den Norden, und den Osten finden, um eine Kiste um den Punkt zu erstellen.

Mit OpenMap konnten wir eine Menge Positionsdaten grafisch darstellen. Es gibt eine LatLonPoint- class, die einige grundlegende functionen einschließlich der Entfernung bietet.

Hier ist eine Java-Implementierung der Haversine- Formel. Ich verwende das in einem Projekt, um die Entfernung in Meilen zwischen Breitengrad und Länge zu berechnen.

public static double distFrom(double lat1, double lng1, double lat2, double lng2) { double earthRadius = 3958.75; // miles (or 6371.0 kilometers) double dLat = Math.toRadians(lat2-lat1); double dLng = Math.toRadians(lng2-lng1); double sindLat = Math.sin(dLat / 2); double sindLng = Math.sin(dLng / 2); double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2) * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); double dist = earthRadius * c; return dist; } 

Oder Sie könnten SimpleLatLng verwenden . Apache 2.0 lizenziert und in einem Produktionssystem verwendet, das ich kenne: meins.

Kurzgeschichte:

Ich suchte nach einer einfachen Geo-Bibliothek und konnte keine finden, die meinen Bedürfnissen entsprach. Und wer möchte diese kleinen Geo-Tools in jeder Anwendung immer wieder schreiben und testen? Es muss einen besseren Weg geben!

So wurde SimpleLatLng als eine Möglichkeit geboren, um Längen- und Breitengrade zu speichern, Distanzberechnungen durchzuführen und geformte Grenzen zu erzeugen.

Ich weiß, dass ich zwei Jahre zu spät bin, um dem ursprünglichen Poster zu helfen, aber mein Ziel ist es, Leuten wie mir zu helfen, die diese Frage bei einer Suche finden. Ich würde es sehr gerne haben, wenn einige Leute es benutzen und zur Erprobung und Vision dieses kleinen, leichten Hilfsprogramms beitragen würden.

Für einen genaueren Abstand (0,5 mm) können Sie auch die Vincenty-Approximation verwenden:

 /** * Calculates geodetic distance between two points specified by latitude/longitude using Vincenty inverse formula * for ellipsoids * * @param lat1 * first point latitude in decimal degrees * @param lon1 * first point longitude in decimal degrees * @param lat2 * second point latitude in decimal degrees * @param lon2 * second point longitude in decimal degrees * @returns distance in meters between points with 5.10-4 precision * @see Originally posted here */ public static double distVincenty(double lat1, double lon1, double lat2, double lon2) { double a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params double L = Math.toRadians(lon2 - lon1); double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1))); double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2))); double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); double sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM; double lambda = L, lambdaP, iterLimit = 100; do { sinLambda = Math.sin(lambda); cosLambda = Math.cos(lambda); sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) return 0; // co-incident points cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.atan2(sinSigma, cosSigma); sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (Double.isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6) double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0); if (iterLimit == 0) return Double.NaN; // formula failed to converge double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); double dist = b * A * (sigma - deltaSigma); return dist; } 

Dieser Code wurde frei von http://www.movable-type.co.uk/scripts/latlong-vincenty.html angepasst

Korrigierte Haversine Distanz Formel ….

 public static double HaverSineDistance(double lat1, double lng1, double lat2, double lng2) { // mHager 08-12-2012 // http://en.wikipedia.org/wiki/Haversine_formula // Implementation // convert to radians lat1 = Math.toRadians(lat1); lng1 = Math.toRadians(lng1); lat2 = Math.toRadians(lat2); lng2 = Math.toRadians(lng2); double dlon = lng2 - lng1; double dlat = lat2 - lat1; double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return EARTH_RADIUS * c; } 

http://www.movable-type.co.uk/scripts/latlong.html

 public static Double distanceBetweenTwoLocationsInKm(Double latitudeOne, Double longitudeOne, Double latitudeTwo, Double longitudeTwo) { if (latitudeOne == null || latitudeTwo == null || longitudeOne == null || longitudeTwo == null) { return null; } Double earthRadius = 6371.0; Double diffBetweenLatitudeRadians = Math.toRadians(latitudeTwo - latitudeOne); Double diffBetweenLongitudeRadians = Math.toRadians(longitudeTwo - longitudeOne); Double latitudeOneInRadians = Math.toRadians(latitudeOne); Double latitudeTwoInRadians = Math.toRadians(latitudeTwo); Double a = Math.sin(diffBetweenLatitudeRadians / 2) * Math.sin(diffBetweenLatitudeRadians / 2) + Math.cos(latitudeOneInRadians) * Math.cos(latitudeTwoInRadians) * Math.sin(diffBetweenLongitudeRadians / 2) * Math.sin(diffBetweenLongitudeRadians / 2); Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return (earthRadius * c); } 

Sie können die Java Geodäsie-Bibliothek für GPS verwenden , sie verwendet die Formeln von Vincenty, die die Krümmung der Erdoberfläche berücksichtigen.

Die Implementierung läuft so:

 import org.gavaghan.geodesy.*; ... GeodeticCalculator geoCalc = new GeodeticCalculator(); Ellipsoid reference = Ellipsoid.WGS84; GlobalPosition pointA = new GlobalPosition(latitude, longitude, 0.0); GlobalPosition userPos = new GlobalPosition(userLat, userLon, 0.0); double distance = geoCalc.calculateGeodeticCurve(reference, userPos, pointA).getEllipsoidalDistance(); 

Die resultierende Entfernung ist in Metern.

Ich weiß, dass es viele Antworten gibt, aber wenn ich etwas zu diesem Thema recherchiere, fand ich, dass die meisten Antworten hier die Haversine-Formel verwenden, aber die Vincenty-Formel ist tatsächlich genauer. Es gab einen Beitrag, der die Berechnung von einer Javascript-Version anpasste, aber es ist sehr unhandlich. Ich habe eine bessere Version gefunden, weil:

  1. Es hat auch eine offene Lizenz.
  2. Es verwendet OOP-Prinzipien.
  3. Es ist flexibler, das gewünschte Ellipsoid auszuwählen.
  4. Es hat mehr Methoden, um in Zukunft andere Berechnungen zu ermöglichen.
  5. Es ist gut dokumentiert.

VincentyDistanceCalculator

Mit dieser Methode können Sie die Entfernung zwischen dem geografischen Standort in km ermitteln.

 private double getDist(double lat1, double lon1, double lat2, double lon2) { int R = 6373; // radius of the earth in kilometres double lat1rad = Math.toRadians(lat1); double lat2rad = Math.toRadians(lat2); double deltaLat = Math.toRadians(lat2-lat1); double deltaLon = Math.toRadians(lon2-lon1); double a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + Math.cos(lat1rad) * Math.cos(lat2rad) * Math.sin(deltaLon/2) * Math.sin(deltaLon/2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); double d = R * c; return d; } 

Ich verwende MATLAB normalerweise mit der Mapping Toolbox und verwende dann den Code in meinem Java mit MATLAB Builder JA. Es macht mein Leben viel einfacher. Angesichts der Tatsache, dass die meisten Schulen kostenlosen Zugang zu den Studenten haben, können Sie es ausprobieren (oder erhalten Sie die Testversion, um über Ihre Arbeit zu kommen).