Entfernungsmessung mit geographischen Koordinaten

Kürzlich stand ich vor dem hausgemachten Problem die Entfernung von zwei geographischen Koordinaten zu berechnen. Mit etwas Mathematik ist die Lösung denkbar einfach und das Ergebnis kann für viele Zwecke verwendet werden.

Ich richte meine Aufmerksamkeit hier auf geographische Koordinaten in Dezimalgrad.

Halbwissen im Hintergrund

Koordinaten in Dezimalgrad bestehen aus zwei Fließkomma Werten: dem Breitengrad (Latitude) und dem Längengrad (Longitude). Der Ursprung (0, 0) dieses Koordinatensystems ist der Äquator auf dem ungefähren Längengrad von Greenwich (London, GB) (WGS 84).

Der Greifswalder Markt hat in diesem Koordinatensystem beispielsweise die Koordinaten 54.095828, 13.381533.

Positive Angaben beim Breitengrad bedeuten, dass der Ort auf der Nordhalbkugel der Erde liegt. Ein positiver Längengrad sagt aus, dass der Ort östlich von Greenwich liegt. Jeweils negative Werte lassen sich auf der Südhalbkugel (Breitengrad) oder westlich von Greenwich (Längengrad) verorten. Die Maximalwerte für den Breitengrad sind 90 bzw. -90 (Nord- und Südpol) und für den Längengrad 180 bzw. -180 (Datumsgrenze im Pazifischen Ozean (?)).

Mathematik und "Programmierung"

Die Aufgabe ist die Berechnung des Abstandes zweier Punkte in diesem Koordinatensystem. Im weiteren Verlauf werde ich die Koordinatenwerte der Einfachheit halber als lat1 und lon1 (Breitengrad und Längengrad des ersten Ortes) und lat2 und lon2 (Breitengrad und Längengrad des zweiten Ortes) bezeichnen.

Um den Abstand d von zwei Orten auf der Erde zu berechnen, müssen die Koordinaten im Bogenmaß (rad) vorliegen. Die eigentliche Mathematik besteht dann aus der Ermittlung der Orthodrome - der kürzesten Entfernung auf einer Kugeloberfläche.

In PHP kann die Formel dann so aussehen:

$d = acos(
    sin(deg2rad($lat2)) * sin(deg2rad($lat1)) + 
    cos(deg2rad($lat2)) * cos(deg2rad($lat1)) * 
    cos(deg2rad($lon2) - deg2rad($lon1))
) * 6371;

Die Zahl 6371 entspricht dem Mittelwert des Erdradius in Kilometern.

Das Ergebnis der Berechnung ist also der Abstand d (in Kilometern) zweier Orte (in Dezimalgrad) auf der Erdoberfläche: die Luftlinie.

Das Ergebnis dieser Aneinanderreihung von Winkelfunktionen konnte ich erst gar nicht glauben (Mathematik Grundkurs mit 5 Punkten). Aber nach mehrfacher Kontrolle gegen andere Werkzeuge im Internet (Bsp.: https://www.luftlinie.org/) stimmt die Formel.

Anwendungsbeispiel

Die Luftlinie hilft in alltäglichen Anwendungen nicht wirklich weiter. Ich möchte nun herausfinden, wie lange verschiedene Arten der Fortbewegung benötigen, um diese Strecke im realen Straßenverkehr zu bewältigen.

Luftlinie vs. Fahrstrecke

Für verschiedene Strecken innerhalb der Stadt Greifswald habe ich auf luftlinie.org die Luftlinie mit der Fahrstrecke ins Verhältnis (Faktor = Fahrstrecke / Luftlinie) gesetzt und so verschiedene Faktoren ermittelt.

Mittelwerte Fahrstrecken-Luftlinien-Verhältnis

1.331797235023041, 1.508379888268156, 
1.283216783216783, 1.36144578313253, 
1.409090909090909, 1.704545454545455, 
1.197727272727273

Aus diesen einzelnen Werten bilde ich einen Mittelwert. Wenn dieser Mittelwert mit der Luftlinie multipliziert wird kommt das schon sehr nahe an die Streckenangaben verschiedener Routenplaner heran (Im Dreisatz bin ich sattelfest).

Die Luftlinie vom Greifswalder Markt [54.095828, 13.381533] zur Klappbrücke in Wieck [54.093281599309236,13.448821306228638] beträgt 4,4 km. Meine errechnete Fahrstrecke ist 6,15 km. Für meine Zwecke reicht das aus!

Fortbewegung

In Greifswald heißt es, dass man für alle Wege nicht länger als 20 Minuten unterwegs ist. Das kommt natürlich auf das Fortbewegungsmittel an. Für die Stadt arbeite ich mit folgenden angenommenen durchschnittlichen Geschwindigkeiten:

 Fußgänger: 4,5 km/h
 Fahrrad: 12,5 km/h
 Auto: 30 km/h

Rote Ampeln, klapprige Fahrräder und die doofen anderen Verkehrsteilnehmer spiegeln sich in diesen niedrigen Durchschnittsgeschwindigkeiten wider.

Nach einer weiteren kleinen Multiplikation der Fahrstrecke mit meinen Geschwindigkeiten erhalte ich für den Weg von der Greifswalder Innenstadt nach Wieck folgende Zeiten:

Fußgänger: 82 Minuten
Fahrrad: 30 Minuten
Auto: 12 Minuten

Und ich kann sagen: "Ja, das kommt in etwa hin!".

Wie geht's weiter?

Mit dem Wissen um die Berechnung der Luftlinie zwischen zwei Orten und die Anwendung empirischer Werte aus dem Greifswalder Straßenverkehr könnte man die Wegezeiten zwischen verschiedenen Gebäuden der Universität Greifswald berechnen und diese in der Planung der Veranstaltungen berücksichtigen.

Da die Universität Greifswald über die gesamte Stadt verteilt ist, sollten Wegezeiten bei der Semesterplanung berücksichtigt werden. Dass sich Studierende nicht innerhalb von 10 Minuten quer durch die ganze Stadt bewegen können sollte jedem klar sein. Mit einem entsprechenden Werkzeug könnte dies in der Organisation automatisch berücksichtigt werden.

PHP-Code

Zum Abschluss noch mein frickeliger PHP-Code für die ganzen Berechnungen.

<?php
// Lat = Breite
// Lon = Länge
$coords = [ // Dezimalgrad; Markt, Wieck
    ['lat' => 54.095828, 'lon' => 13.381533],
    ['lat' => 54.093281599309236, 'lon' => 13.448821306228638]
];

$factors = [  
    'streets' => [ // Faktoren (Fahrtweg / Luftlinie) verschiedener Strecken in Greifswald
        1.331797235023041, 
        1.508379888268156, 
        1.283216783216783,
        1.36144578313253,
        1.409090909090909,
        1.704545454545455,
        1.197727272727273,
    ], 
];

$speed = [
    'walking' => 4.5,
    'bike' => 12.5,
    'car' => 30,
];

// Bogenmaß berechnen (km); Quelle: http://www.csv-geodaten.de/entfernung-berechnen.php
$d_direct = acos(
    sin(deg2rad($coords[1]['lat'])) * sin(deg2rad($coords[0]['lat'])) + 
    cos(deg2rad($coords[1]['lat'])) * cos(deg2rad($coords[0]['lat'])) * 
    cos(deg2rad($coords[1]['lon']) - deg2rad($coords[0]['lon'])))
    * 6371; // Erdrasius (Mittelwert) = 6371 km

$d_street = $d_direct * (array_sum($factors['streets']) / count($factors['streets'])); // Luftlinie multipliziert mit Mittelwerten der Entfernungsfaktoren

echo '<a href="https://www.luftlinie.org/' . $coords[0]['lat'] . ',' . $coords[0]['lon'] . '/' . $coords[1]['lat'] . ',' . $coords[1]['lon'] . '">Grafische Darstellung auf Luftlinie.de</a><br />';
echo '<br />Entfernungen:<br />';   
echo 'Luftlinie: ' . round($d_direct, 2) . ' km<br />';
echo 'Weg: ' . round($d_street, 2) . ' km<br /><br />';
echo 'Wegezeiten: <br />';
echo 'Fußgänger: ' . round(($d_street / $speed['walking']) * 60) . ' Minuten / ' . roundUpToAny(round(($d_street / $speed['walking']) * 60)). ' Minuten (bei ' . $speed['walking'] . ' km/h)<br />';
echo 'Fahrrad: ' . round(($d_street / $speed['bike']) * 60) . ' Minuten / ' . roundUpToAny(round(($d_street / $speed['bike']) * 60)). ' Minuten (bei ' . $speed['bike'] . ' km/h)<br />';
echo 'Auto: ' . round(($d_street / $speed['car']) * 60) . ' Minuten / ' . roundUpToAny(round(($d_street / $speed['car']) * 60)). ' Minuten (bei ' . $speed['car'] . ' km/h)<br />';

function roundUpToAny($n, $x=5) {
    return round(($n + $x / 2) / $x) * $x;
}
?>

Quellen