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.

43voto

tony gil Punkte 9305

Dies ist eine einfache PHP-Funktion, die eine sehr vernünftige Näherung (unter einer Fehlermarge von +/-1%) liefert.

'.$km;
    return $km;
}
?>

Wie bereits gesagt, ist die Erde KEINE Kugel. Sie ist wie ein alter, alter Baseball, mit dem Mark McGwire trainiert hat - voller Dellen und Beulen. Einfache Berechnungen (wie diese) behandeln sie wie eine Kugel.

Verschiedene Methoden können genauer oder ungenauer sein, je nachdem, wo Sie sich auf diesem unregelmäßigen Eiform befinden und wie weit Ihre Punkte voneinander entfernt sind (je näher sie beieinander liegen, desto kleiner ist die absolute Fehlermarge). Je genauer Ihre Erwartung, desto komplexer die Mathematik.

Weitere Informationen: Wikipedia geografische Entfernung

4 Stimmen

Dies funktioniert perfekt! Ich habe einfach $distance_miles = $km * 0.621371; hinzugefügt und das war alles, was ich für die ungefähre Entfernung in Meilen brauchte! Danke Tony.

32voto

conualfy Punkte 647

Ich veröffentliche hier mein Arbeitsbeispiel.

Listen Sie alle Punkte in der Tabelle auf, die einen Abstand zu einem bestimmten Punkt haben (wir verwenden einen zufälligen Punkt - lat: 45.20327, long: 23.7806), der kleiner als 50 KM ist, mit Breiten- und Längengrad, in MySQL (die Tabellenfelder sind coord_lat und coord_long):

Liste alle mit DISTANZ<50, in Kilometern (Erdradius 6371 KM):

SELECT denumire, (6371 * acos( cos( radians(45.20327) ) * cos( radians( coord_lat ) ) * cos( radians( 23.7806 ) - radians(coord_long) ) + sin( radians(45.20327) ) * sin( radians(coord_lat) ) )) AS distanta 
FROM obiective 
WHERE coord_lat<>'' 
    AND coord_long<>'' 
HAVING distanta<50 
ORDER BY distanta desc

Das obige Beispiel wurde in MySQL 5.0.95 und 5.5.16 (Linux) getestet.

0 Stimmen

Ich denke, ein guter Ansatz könnte sein, die Ergebnisse vorzufiltern, indem eine Annäherung verwendet wird, damit die komplexe Formel nur für einige Fälle angewendet wird. Besonders nützlich, wenn Sie andere Bedingungen haben. Ich verwende dies für die erste Annäherung: stackoverflow.com/questions/1253499/…

32voto

Jaap Punkte 76587

In den anderen Antworten fehlt eine Implementierung in r.

Die Berechnung der Entfernung zwischen zwei Punkten ist recht einfach mit der distm Funktion aus dem geosphere Paket:

distm(p1, p2, fun = distHaversine)

wo:

p1 = Längen- / Breitengrad für Punkt(e)
p2 = Längen- / Breitengrad für Punkt(e)
# Art der Entfernungsberrechnung
fun = distCosine / distHaversine / distVincentySphere / distVincentyEllipsoid 

Da die Erde nicht perfekt kugelförmig ist, ist die Vincenty-Formel für Ellipsoide wahrscheinlich der beste Weg, um Entfernungen zu berechnen. Daher verwenden Sie im geosphere Paket dann:

distm(p1, p2, fun = distVincentyEllipsoid)

Natürlich müssen Sie nicht unbedingt das geosphere Paket verwenden, Sie können die Entfernung auch in base R mit einer Funktion berechnen:

hav.dist <- function(long1, lat1, long2, lat2) {
  R <- 6371
  diff.long <- (long2 - long1)
  diff.lat <- (lat2 - lat1)
  a <- sin(diff.lat/2)^2 + cos(lat1) * cos(lat2) * sin(diff.long/2)^2
  b <- 2 * asin(pmin(1, sqrt(a))) 
  d = R * b
  return(d)
}

0 Stimmen

Um sicherzustellen, dass ich verstehe, was Sie gesagt haben: Der Code, den Sie am Ende des Beitrags geben: Ist das eine Implementierung der Vincenty-Formel? Soweit Sie wissen, sollte es dieselbe Antwort geben wie der Aufruf von Vincenty in Geosphäre? [Ich habe keine Geosphäre oder andere Bibliothek; ich suche nur nach einem Code, den ich in einer plattformübergreifenden App verwenden kann. Ich würde natürlich einige Testfälle gegen einen bekannten guten Taschenrechner überprüfen.]

1 Stimmen

@ToolmakerSteve die Funktion am Ende meiner Antwort ist eine Implementierung der Haversine-Methode.

0 Stimmen

Hallo @Jaap, könnte ich fragen, welche Maßeinheit für die Formel verwendet wird? Ist es in Metern?

13voto

Arturo Hernandez Punkte 2439

Die Haversine ist definitiv eine gute Formel für wahrscheinlich die meisten Fälle, andere Antworten beinhalten sie bereits, daher werde ich den Platz nicht einnehmen. Aber es ist wichtig zu beachten, dass egal welche Formel verwendet wird (ja nicht nur eine). Aufgrund der großen Genauigkeitsbereiche, die möglich sind, sowie der benötigten Rechenzeit. Die Wahl der Formel erfordert etwas mehr Nachdenken als eine einfache Antwort ohne viel Überlegung.

Dieser Beitrag von einer Person bei der NASA ist der beste, den ich gefunden habe, der die Optionen diskutiert

http://www.cs.nyu.edu/visual/home/proj/tiger/gisfaq.html

Zum Beispiel, wenn Sie nur Zeilen nach Entfernung in einem 100-Meilen-Radius sortieren. Wird die flache-Erde-Formel viel schneller als die Haversine sein.

HalfPi = 1.5707963;
R = 3956; /* der Radius gibt Ihnen die Maßeinheit*/

a = HalfPi - latoriginrad;
b = HalfPi - latdestrad;
u = a * a + b * b;
v = - 2 * a * b * cos(longdestrad - longoriginrad);
c = sqrt(abs(u + v));
return R * c;

Beachten Sie, dass es nur ein Cosinus und eine Quadratwurzel gibt. Im Vergleich zu neun von ihnen in der Haversine-Formel.

2 Stimmen

Es ist eine schöne Möglichkeit. Seien Sie einfach darauf aufmerksam, dass die empfohlene maximale Entfernung in der Diskussion 12 Meilen beträgt, nicht 100, und dass dennoch Fehler von bis zu 30 Metern (100 Fuß) auftreten können, je nach Position des Globus.

10voto

Es gibt einige Fehler im bereitgestellten Code, ich habe sie unten behoben.

Alle oben genannten Antworten gehen davon aus, dass die Erde eine Kugel ist. Eine genauere Annäherung wäre jedoch die eines abgeflachten Sphäroids.

a= 6378.137#Äquatorialradius in km
b= 6356.752#Polarradius in km

def Entfernung(lat1, lons1, lat2, lons2):
    lat1=math.radians(lat1)
    lons1=math.radians(lons1)
    R1=(((((a**2)*math.cos(lat1))**2)+(((b**2)*math.sin(lat1))**2))/((a*math.cos(lat1))**2+(b*math.sin(lat1))**2))**0.5 #Erdradius bei lat1
    x1=R1*math.cos(lat1)*math.cos(lons1)
    y1=R1*math.cos(lat1)*math.sin(lons1)
    z1=R1*math.sin(lat1)

    lat2=math.radians(lat2)
    lons2=math.radians(lons2)
    R2=(((((a**2)*math.cos(lat2))**2)+(((b**2)*math.sin(lat2))**2))/((a*math.cos(lat2))**2+(b*math.sin(lat2))**2))**0.5 #Erdradius bei lat2
    x2=R2*math.cos(lat2)*math.cos(lons2)
    y2=R2*math.cos(lat2)*math.sin(lons2)
    z2=R2*math.sin(lat2)

    return ((x1-x2)**2+(y1-y2)**2+(z1-z2)**2)**0.5

0 Stimmen

Könnten Sie Quellen zu Ihren Formeln hinzufügen?

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