Home > Allgemeines > Entfernungsberechnung (Update)

Entfernungsberechnung (Update)

Wie berechne ich die Entfernung (in Kilometern) zwischen zwei Orten? Sofern Längen- und Breitengrad für beide Punkte vorliegen, kann dies mit folgendem Code durchgeführt werden:

1
2
3
4
Function DegreeToRadian(angle As Double) As Double
  Const PI = 3.14159265358979323846264338327950
  Return angle / 180 * PI
End Function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Function GetDistance(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double
  Const EarthRadius = 6370
 
  Dim RadianLatitude1, RadianLongitude1 as Double
  Dim RadianLatitude2, RadianLongitude2 as Double
 
  RadianLatitude1 = DegreeToRadian( Latitude1 ) 
  RadianLongitude1 = DegreeToRadian( Longitude1 )
  RadianLatitude2 = DegreeToRadian( Latitude2 )
  RadianLongitude2 = DegreeToRadian( Longitude2 )
 
  Return ACos( Sin( RadianLatitude1 ) * Sin( RadianLatitude2 ) + _
  Cos( RadianLatitude1 ) * Cos( RadianLatitude2 ) * _
  Cos( RadianLongitude1 - RadianLongitude2 ) ) * _
  EarthRadius
End Function
1
2
3
4
5
6
7
8
9
10
11
12
'Frankfurt/Main, Germany
Dim Latitude1 as Double = 50.120578
Dim Longitude1 as Double = 8.681946
 
'Berlin, Germany
Dim Latitude2 as Double = 52.531261
Dim Longitude2 as Double = 13.410187
 
Dim Distance as Double
 
Distance = GetDistance( Latitude1, Longitude1, Latitude2, Longitude2 )
MsgBox Str(Distance) + " km"

Update:
Die obigen Funktionen berechnen den Abstand auf Basis einer Kugel. Da die Erde aber an den Polen leicht abgeflacht ist, benutzt man zur genaueren Berechnung der Abstände auf bis zu 50 Meter das WGS84-Ellipsoid. Die folgende Funktion bildet die Berechnung in Realbasic nach:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Function GetDistanceWGS84(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double
  Const EarthRadius = 6378.137
  Const Flattening = 0.003352811
 
  Dim F,G,l,S,C,w,R,D,H1,H2 as Double
  Dim SinF2,SinG2,Sinl2,CosF2,CosG2,Cosl2 as Double
 
  F = DegreeToRadian( (Latitude1 + Latitude2) / 2 )
  G = DegreeToRadian( (Latitude1 - Latitude2) / 2)
  l = DegreeToRadian( (Longitude1 - Longitude2) / 2)
 
  SinF2 = Sin(F)^2
  SinG2 = Sin(G)^2
  Sinl2 = Sin(l)^2
 
  CosF2 = Cos(F)^2
  CosG2 = Cos(G)^2
  Cosl2 = Cos(l)^2
 
  S = SinG2 * Cosl2 + CosF2 * Sinl2
  C = CosG2 * Cosl2 + SinF2 * Sinl2
 
  w = ATan( Sqrt( S / C ) )
  D = 2 * w * EarthRadius
  R = Sqrt( S * C ) / w
 
  H1 = (3 * R - 1) / (2 * C)
  H2 = (3* R + 1) / (2 * S)
 
  Return D * (1 + Flattening * H1 * SinF2 * CosG2 - Flattening * H2 * CosF2 * SinG2)
 
End Function

Update2:
Ergänzend zu der Kugel- und Ellipsoid-Berechnung noch eine sehr einfache Funktion mit der Pythagoras-Formel. Diese sollte allerdings nur für kurze Distanzen genutzt werden, da es hierbei aufgrund der Erdkrümmung zu Abweichungen kommt:

1
2
3
Function GetDistancePythagoras(Latitude1 As Double, Longitude1 As Double, Latitude2 As Double, Longitude2 As Double) As Double
  Return Sqrt( ((Latitude1 - Latitude2) * 111) ^ 2 + ((Longitude1 - Longitude2) * 71.5) ^ 2 )
End Function
  1. Thomas Tempelmann
    31. März 2011, 08:21 | #1

    Praktisch. Danke. Ich hatte es selbst damals mir einfacher gemacht und einfach die mittlere Entfernung zw. zwei Längen- und Breitengraden in km ermittelt anstatt diese korrektere Formel über den Erdradius zu verwenden. In meinem Fall, wo ich es für das iPhone brauchte, wäre deine komplexere Formel zu langsam geworden, weil dort die trigonometrischen Funktionen recht zeitaufwändig sind.

    Ach ja – auch in diesem Bsp. wären 2 Sachen zu verbessern:
    1. Anstatt „Sin(latitude1/180*PI) * Sin(latitude2/180*PI)“ zu schreiben, was zweimal die selbe Berechnung von Sin() usw. ausführt, sollten diese Werte einmal zuvor in Variablen berechnet werden. Spart Rechenzeit, falls davon viele Berechnungen angestellt werden.
    2. „km“, nicht „Km“. 🙂

    Ansonsten, weiter so! Wir brauchen mehr Tipps!

  2. 31. März 2011, 19:17 | #2

    Wenn die Berechnung schnell gehen muss, z.B. Umkreissuche auf dem iPhone, dann kann man auch den Satz des Pythagoras (a² + b² = c²) verwenden. Diese Methode ist zwar weniger genau, bei kleinen Entfernungen aber aufgrund der geringen Erdkrümmung trotzdem anwendbar.

    Ansonsten habe ich den Code einmal etwas übersichtlicher in Funktionen aufgeteilt. Was deinen ersten Verbesserungsvorschlag betrifft, so läßt sich wohl lediglich die Bogenmaßberechnung in einer Variablen zwischenspeichern, denn die Sinus / Cosinus-Berechnungen werden in der Formel nie doppelt ausgeführt. Wenn man die Koordinaten mehrfach bei Berechnungen benötigt, dann hast du natürlich Recht – oder habe ich da was übersehen? 😉

  3. Thomas Tempelmann
    31. März 2011, 20:07 | #3

    Was deinen ersten Verbesserungsvorschlag betrifft, so läßt sich wohl lediglich die Bogenmaßberechnung in einer Variablen zwischenspeichern, denn die Sinus / Cosinus-Berechnungen werden in der Formel nie doppelt ausgeführt

    Oh, Hoppla, stimmt. Ich hatte da gedacht, daß der Pythagoras da zur Anwendung kommt (so mache ich’s im iPhone), aber das ist bei dir ja gar nicht der Fall – sah nur so aus 🙂

  4. 31. März 2011, 21:34 | #4

    Thomas Tempelmann :

    Oh, Hoppla, stimmt. Ich hatte da gedacht, daß der Pythagoras da zur Anwendung kommt (so mache ich’s im iPhone), aber das ist bei dir ja gar nicht der Fall – sah nur so aus :)

    Du hattest dich bei den Optimierungen vermutlich auf die Berechnungen auf Grundlage eines Ellipsoid bezogen, denn dort wird häufiger Sinus / Cosinus in den Formeln genutzt. Ich habe dazu ergänzend mal eine genauere Funktion im Artikel eingefügt, welche auch deine Optimierungen beinhaltet 🙂

  1. Bisher keine Trackbacks