1157 Stimmen

Die Distanz zwischen zwei Breitengrad-Längengrad-Punkten berechnen? (Haversine-Formel)

Wie berechne ich die Entfernung zwischen zwei Punkten, die durch Breiten- und Längengrad angegeben sind?

Zur Klarstellung möchte ich die Entfernung in Kilometern; die Punkte verwenden das WGS84-System und ich möchte die relativen Genauigkeiten der verfügbaren Methoden verstehen.

0 Stimmen

Für eine bessere Genauigkeit - siehe stackoverflow.com/questions/1420045/…

4 Stimmen

Beachten Sie, dass Sie die Haversine-Formel nicht auf einem Rotationsellipsoid wie WGS 84 anwenden können. Sie können diese Methode nur auf einer Kugel mit einem Radius anwenden.

8 Stimmen

Die meisten Antworten hier verwenden einfache sphärische Trigonometrie, daher sind die Ergebnisse im Vergleich zu den WGS84-Ellipsoidentfernungen, die im GPS-System verwendet werden, ziemlich grob. Einige der Antworten beziehen sich zwar auf die Vincenty-Formel für Ellipsoide, aber dieser Algorithmus wurde für die Verwendung auf Schreibtischrechnern aus den 1960er Jahren entwickelt und weist Stabilitäts- und Genauigkeitsprobleme auf; wir haben jetzt bessere Hardware und Software. Bitte sehen Sie GeographicLib für eine hochwertige Bibliothek mit Implementierungen in verschiedenen Sprachen.

9voto

invoketheshell Punkte 3621

pip install haversine

Python Implementierung

Der Ursprung ist das Zentrum der zusammenhängenden Vereinigten Staaten.

from haversine import haversine, Unit
origin = (39.50, 98.35)
paris = (48.8567, 2.3508)
haversine(origin, paris, unit=Unit.MILES)

Um die Antwort in Kilometern zu erhalten, setzen Sie einfach unit=Unit.KILOMETERS (das ist der Standard).

4 Stimmen

Du importierst ein nicht standardisiertes Paket, das die gesamte Arbeit erledigt. Ich weiß nicht, ob das wirklich nützlich ist.

0 Stimmen

Das Paket befindet sich im PyPI, Python Package Index, als ein Python 3-Paket zusammen mit numpy und scikit-learn. Nicht sicher, warum jemand Paketen gegenüber abgeneigt ist. Sie neigen dazu, ziemlich nützlich zu sein. Als Open Source könnte man auch die enthaltenen Methoden überprüfen. Ich denke, viele würden dieses Paket nützlich finden, daher werde ich den Beitrag trotz des Downvotes stehen lassen. Prost. :)

0 Stimmen

Es sieht nützlich aus, aber ich würde gerne den genauen Pip-Befehl angeben, um dieses Paket zu installieren.

9voto

Meymann Punkte 2510

Es könnte eine einfachere und korrektere Lösung geben: Der Erdumfang beträgt am Äquator 40.000 km und etwa 37.000 km am Nullmeridian (oder jedem anderen Längengrad). Also:

pythagoras = function (lat1, lon1, lat2, lon2) {
   function sqr(x) {return x * x;}
   function cosDeg(x) {return Math.cos(x * Math.PI / 180.0);}

   var earthCyclePerimeter = 40000000.0 * cosDeg((lat1 + lat2) / 2.0);
   var dx = (lon1 - lon2) * earthCyclePerimeter / 360.0;
   var dy = 37000000.0 * (lat1 - lat2) / 360.0;

   return Math.sqrt(sqr(dx) + sqr(dy));
};

Ich stimme zu, dass es feinabgestimmt werden sollte, wie ich selbst gesagt habe, dass es sich um einen Ellipsoiden handelt, sodass der Radius, der mit dem Kosinus multipliziert werden muss, variiert. Aber es ist etwas genauer. Im Vergleich zu Google Maps hat es den Fehler signifikant reduziert.

0 Stimmen

Ist diese Funktion gibt die Entfernung in km zurück?

0 Stimmen

Es ist so, einfach weil der Äquator und die Längenkreise in Km sind. Für Meilen teilen Sie einfach 40000 und 37000 durch 1,6. Wenn Sie sich geeky fühlen, können Sie es in Ries umrechnen, indem Sie es mit etwa 7 multiplizieren oder in Parasang umrechnen, indem Sie es durch 2,2 teilen ;-)

0 Stimmen

Dies scheint die beste hier angebotene Antwort zu sein. Ich möchte sie verwenden, aber ich frage mich nur, ob es eine Möglichkeit gibt, die Richtigkeit dieses Algorithmus zu überprüfen. Ich habe f(50,5,58,3) getestet. Es gibt 832km, während movable-type.co.uk/scripts/latlong.html unter Verwendung der 'haversine'-Formel 899km gibt. Gibt es einen so großen Unterschied?

8voto

Chong Lip Phang Punkte 7584

Wie bereits erwähnt, sollte eine genaue Berechnung berücksichtigen, dass die Erde keine perfekte Kugel ist. Hier sind einige Vergleiche der verschiedenen hier angebotenen Algorithmen:

geoDistance(50,5,58,3)
Haversine: 899 km
Maymenn: 833 km
Keerthana: 897 km
google.maps.geometry.spherical.computeDistanceBetween(): 900 km

geoDistance(50,5,-58,-3)
Haversine: 12030 km
Maymenn: 11135 km
Keerthana: 10310 km
google.maps.geometry.spherical.computeDistanceBetween(): 12044 km

geoDistance(.05,.005,.058,.003)
Haversine: 0,9169 km
Maymenn: 0,851723 km
Keerthana: 0,917964 km
google.maps.geometry.spherical.computeDistanceBetween(): 0,917964 km

geoDistance(.05,80,.058,80.3)
Haversine: 33,37 km
Maymenn: 33,34 km
Keerthana: 33,40767 km
google.maps.geometry.spherical.computeDistanceBetween(): 33,40770 km

Über kurze Entfernungen scheint der Algorithmus von Keerthana mit dem von Google Maps übereinzustimmen. Google Maps folgt anscheinend keinem einfachen Algorithmus, was darauf hinweist, dass es möglicherweise die genaueste Methode hier ist.

Wie auch immer, hier ist eine JavaScript-Implementierung des Algorithmus von Keerthana:

function geoDistance(lat1, lng1, lat2, lng2){
    const a = 6378,137; // Äquatorradius in km
    const b = 6356,752; // Polradius in km

    var sq = x => (x*x);
    var sqr = x => Math.sqrt(x);
    var cos = x => Math.cos(x);
    var sin = x => Math.sin(x);
    var radius = lat => sqr((sq(a*a*cos(lat))+sq(b*b*sin(lat)))/(sq(a*cos(lat))+sq(b*sin(lat))));

    lat1 = lat1 * Math.PI / 180;
    lng1 = lng1 * Math.PI / 180;
    lat2 = lat2 * Math.PI / 180;
    lng2 = lng2 * Math.PI / 180;

    var R1 = radius(lat1);
    var x1 = R1*cos(lat1)*cos(lng1);
    var y1 = R1*cos(lat1)*sin(lng1);
    var z1 = R1*sin(lat1);

    var R2 = radius(lat2);
    var x2 = R2*cos(lat2)*cos(lng2);
    var y2 = R2*cos(lat2)*sin(lng2);
    var z2 = R2*sin(lat2);

    return sqr(sq(x1-x2)+sq(y1-y2)+sq(z1-z2));
}

8voto

Ich mag es nicht, noch eine Antwort hinzuzufügen, aber die Google Maps API v.3 verfügt über sphärische Geometrie (und mehr). Nachdem Sie Ihre WGS84 in Dezimalgrade umgewandelt haben, können Sie dies tun:

distance = google.maps.geometry.spherical.computeDistanceBetween(
    new google.maps.LatLng(fromLat, fromLng), 
    new google.maps.LatLng(toLat, toLng));

Kein Wort darüber, wie genau die Berechnungen von Google sind oder welches Modell verwendet wird (obwohl es "sphärisch" statt "Geoid" sagt. Übrigens wird die "Luftlinie" -Entfernung offensichtlich von der Entfernung abweichen, wenn man auf der Erdoberfläche reist, was jeder zu vermuten scheint.

0 Stimmen

Abstand ist in Metern. Alternativ kann man computeLength() verwenden.

7voto

Andre Cytryn Punkte 2296

Sie können die integrierte CLLocationDistance verwenden, um dies zu berechnen:

CLLocation *location1 = [[CLLocation alloc] initWithLatitude:latitude1 longitude:longitude1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:latitude2 longitude:longitude2];
[self distanceInMetersFromLocation:location1 toLocation:location2]

- (int)distanceInMetersFromLocation:(CLLocation*)location1 toLocation:(CLLocation*)location2 {
    CLLocationDistance distanceInMeters = [location1 distanceFromLocation:location2];
    return distanceInMeters;
}

In Ihrem Fall, wenn Sie Kilometer möchten, einfach durch 1000 teilen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X