Odległość między punktami lat / long

10

Próbuję obliczyć odległość między dwoma punktami szerokość / długość geograficzna. Mam kawałek kodu, który w większości działa, który wyrwałem z tego postu, ale tak naprawdę nie rozumiem, jak to działa.

Oto kod:

<?php
// POINT 1
$thisLat = deg2rad(44.638);
$thisLong = deg2rad(-63.587);

// POINT 2
$otherLat = deg2rad(44.644);
$otherLong = deg2rad(-63.911);

$MeanRadius = 6378 - 21 * sin($lat1);

$xa = (Cos($thisLat)) * (Cos($thisLong));
$ya = (Cos($thisLat)) * (Sin($thisLong));
$za = (Sin($thisLat));

$xb = (Cos($otherLat)) * (Cos($otherLong));
$yb = (Cos($otherLat)) * (Sin($otherLong));
$zb = (Sin($otherLat));

$distance = $MeanRadius * Acos($xa * $xb + $ya * $yb + $za * $zb);

echo $distance;
?>

Mam kilka pytań:

  1. jakie są xa, ya, za? Rozumiem, że są to punkty na kartezjańskiej płaszczyźnie 3D, ale gdzie się odnoszą? Centrum ziemi?
  2. Jak to cos($xa * $xb + $ya * $yb + $za * $zb)oblicza odległość między punktami? Wiem, że w 2D zrobiłbym to:

alternatywny tekst

Pythagorean Theorem 
distance^2 = b^2 + a^2
distance = sqr((y2-y1)^2 + (x2 - x1)^2)
  1. Jak dokładne to będzie? Na drugiej stronie była dyskusja na ten temat. Ale szczególnie chcę użyć odległości, aby stwierdzić, czy użytkownicy znajdują się w odległości około 10, 20 lub 50 metrów od siebie. Czy będę w stanie to zrobić z dobrą dokładnością?
  2. Do czego mam używać $MeanRadius? Czy to rozsądna wartość? Myślę, że ta wartość zakłada, że ​​Ziemia jest elipsą.
sześćdziesiąt stóp
źródło

Odpowiedzi:

17

Jest to okropny kod do użytku ogólnego, ponieważ może dawać błędne wyniki lub nawet całkowicie zawieść na krótkich dystansach. Zamiast tego użyj formuły Haversine .

(Wzór, na którym opiera się Twój kod, konwertuje dwa punkty na kuli (nie elipsę) na ich współrzędne kartezjańskie 3D (xa, ya, za) i (xb, yb, zb) na jednostcekula i tworzy iloczyn iloczynu, który będzie równy cosinus kąta między nimi. Funkcja ACos zwraca ten kąt, który po skalowaniu według promienia ziemi oszacuje odległość. Problem polega na tym, że cosinus małego kąta, powiedzmy wielkości „e” w radianach, różni się od 1 o wartość zbliżoną do e ^ 2/2. Znika w chmurze błędów zmiennoprzecinkowych, gdy e jest mniejsze niż pierwiastek kwadratowy z dwukrotności precyzji zmiennoprzecinkowej. Jeśli obliczasz z pojedynczą precyzją, oznacza to, że wartości e mniejsze niż 0,001 - około jednego kilometra - zostaną pomylone z zerem! W podwójnej precyzji wartość graniczna wynosi około e = 10 ^ -8, ale do czasu e = 10 ^ -4 lub mniej więcej (około 10 metrów) potencjalnie możesz stracić tyle precyzji, że musisz się martwić,, ma wbudowane kilka bardzo precyzyjnych obliczeń wewnętrznych)).

Whuber
źródło
7

Zajrzyj na tę stronę, http://www.movable-type.co.uk/scripts/latlong.html

Jeśli go zaimplementujesz i otrzymasz błędne odpowiedzi, prawdopodobnie masz złe jednostki. Myślę, że w tym miejscu większość operacji wykonywana jest w radianach zamiast stopni dziesiętnych.

Patrick
źródło