Christian Seiler: Entfernungsermittlung klappt - aber in welcher Himmelsrichtung?

Beitrag lesen

Hallo,

Ich habe lat1 und lon1 (Breite und Länge des Referenzortes) und möchte mit lat2 und lon2 (Breite und Länge des gefundenen Ortes) eine Gradzahl 0 .. 360 erhalten. Mit welcher "Weltformel" geht das?

Naja, kommt darauf an[tm], wie Du von Ort 1 zu Ort 2 kommen willst.

Du kannst nämlich entweder auf einem Großkreis auf der Kugel navigieren. Die Abstandsformel, die auf der von Dir verlinkten Seite angegeben ist, gilt für Großkreise. Großkreise sind bekanntermaßen die kürzesten Verbindungen zwischen zwei Punkten. Allerdings: dann ist Deine Richtung (im Kompass-Sinne) aber nie konstant, außer Du bewegst Dich gerade auf dem Äquator oder auf einem Großkreis der in Nord-Süd-Richtung geht. Beispiel:

Vorweg: 0° == Nord, 90° == Ost, 180° == Süd, 270° == West.

Wenn Du von New York nach Berlin willst, dann musst Du zuerst in Richtung 36° navigieren (also Nord-Nord-Ost). Wenn Du in Berlin ankommst hat Dein Kurs jedoch die Richtung 109° (also Ost-Süd-Ost!). Das klingt erst einmal seltsam, ist jedoch die kürzeste Route von New York nach Berlin.

Wenn Du dagegen eine konstante Peilung haben willst, kannst Du Dich an einer Loxodrome entlangbewegen. Dies führt dazu, dass Deine Peilung konstant ist, die Strecke aber im Zweifel länger wird. Eine Loxodrome zwischen zwei Punkten zu berechnen ist allerdings sehr kompliziert, man muss dazu irgend eine transzendente Gleichung lösen, die außerdem noch unendlich viele Lösungen hat und man muss sich dort die kürzeste herauspicken.

Da Du hier aber offensichtlich nur im 50km-Bereich bleiben willst, ist der Unterschied zwischen Loxodrome und Orthodrome (Großkreis) vernachlässigbar. Sprich: Du kannst genauso gut eine Orthodrome verwenden. Im folgenden als Beispiel eine kleine PHP-Klasse, die solche Berechnungen anstellt (lässt sich im Prinzip in jede andere Programmiersprache umsetzen, auch SQL, allerdings wäre es dort ziemlich eklig ohne CREATE FUNCTION, falls Dein DBMS das nicht kann [1]):

<?php  
  
class SphericalPosition {  
	private $lat;  
	private $lon;  
	  
	const EARTH_RADIUS = 6378.388;  
	  
	public function __construct ($lat, $lon) {  
		$this->lat = deg2rad ($lat);  
		$this->lon = deg2rad ($lon);  
	}  
	  
	private function sphericalAngleTo (SphericalPosition $other) {  
		return acos (sin ($this->lat) * sin ($other->lat) + cos ($this->lat) * cos ($other->lat) * cos (abs ($other->lon - $this->lon)));  
	}  
	  
	public function distanceTo (SphericalPosition $other) {  
		return $this->sphericalAngleTo ($other) * self::EARTH_RADIUS;  
	}  
	  
	public function initialBearingTo (SphericalPosition $other) {  
		if (abs (M_PI - $this->lat) < 1e-8 || abs (M_PI + $other->lat) < 1e-8) {  
			// Either we are extremely close to the north pole or the other is  
			// extremely close to the south pole. In that case, south.  
			return 180;  
		} else if (abs (M_PI + $this->lat) < 1e-8 || abs (M_PI - $other->lat) < 1e-8) {  
			// Either we are extremely close to the south pole or the other is  
			// extremely close to the north pole. In that case, north.  
			return 0;  
		}  
		  
		$sphAngle = $this->sphericalAngleTo ($other);  
		$cAngle = (sin ($other->lat) - sin ($this->lat) * cos ($sphAngle)) / (sin ($this->lat) * sin ($sphAngle));  
		  
		if ($other->lon - $this->lon >= 0 && $other->lon - $this->lon < M_PI) {  
			// East of us  
			return rad2deg (acos ($cAngle));  
		} else {  
			// West of us  
			return rad2deg (2 * M_PI - acos ($cAngle));  
		}  
	}  
	  
	public function getLat () { return rad2deg ($this->lat); }  
	public function getLon () { return rad2deg ($this->lon); }  
}

Die Formeln habe ich aus: http://www.students.uni-mainz.de/capraro/besteck.pdf (Ich habe ne kleine Abweichung wenn ich im letzten Beispiel die gleichen Zahlenwerte einsetze für Main und Mekka - aber ich wüßte nicht, wo hier mein Felher liegt, vielleicht haben die auch falsch eingesetzt. Und bevor jemand fragt: cos(90°-alpha) = sin(alpha) und sin(90°-alpha) = cos(alpha).)

[1] MySQL kann's z.B. erst ab 5.1.

Viele Grüße,
Christian

--
Mein "Weblog" [RSS]
Using XSLT to create JSON output (Saxon-B 9.0 for Java)
»I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
            -- Kommentar bei TDWTF