Dlouhou dobu jsme pro tento případ používali jednoduchý vzoreček okořeněný magickou konstantou:
dist = sqrt( (lat1 - lat2) ^ 2 + (lng1 - lng2) ^ 2 ) * 0.012
kde lat1, lat2, lng1, lng2 jsou souřadnice bodů jejichž vzdálenost máme určit a 0.012 je magická konstanta, která v našich zeměpisných šířkách upravuje výsledek tak, aby udával vzdálenost v kilometrech.
Bohužel předchozí věta není úplně pravdivá: výsledek se tu více, tu méně skutečné vzdálenosti pouze blíží. To podle toho, kterým směrem jsou od sebe body položeny a v jaké se pohybujeme zeměpisné šířce. Když pak přišla potřeba výpočet zpřesnit, museli jsme používaný vztah změnit.
Problém se vztahem je asi každému zřejmý. Bohužel nežijeme na placce, ale na kouli (zhruba) a tak nevystačíme s rovinnou geometrií a Pythagorovou větou, ale musíme počítat s geometrií sférickou. Nepotřebujeme dostat přímou vzdálenost mezi body (pokud nejste krtek a nepočítáte tunel). Zajímá nás vzdálenost mezi body po obvodu kružnice, jejíž poloměr je dán poloměrem Země.
Pro tento případ lze odvodit tzv. haversine vzorec, který lze s nevelkou chybou zjednodušit na následující vztah:
dist = acos (sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(lng1 - lng2) ) * 6371
kde lat1, lat2, lng1, lng2 jsou souřadnice bodů a 6371 poloměr Země v km, výsledkem je vzdálenost v kilometrech. Pozor: předpokládáme zde výpočet v radiánech – úhel, který vrátí acos, se násobí poloměrem Země. Kdybychom úhel počítali ve stupních, je třeba konstantu náležitě upravit (na 6371 / 360 * 2 * Pi = 111.19).
Protože souřadnice udáváme nejčastěji ve stupních, je nutné i tyto nejprve převést na radiány. Výsledný kód funkce pro výpočet vzdálenosti v PHP je pak následující:
function distance($lat1, $lng1, $lat2, $lng2)
{
$theta = $lng1 - $lng2;
$dist = acos(
sin(deg2rad($lat1)) * sin(deg2rad($lat2))
+ cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta))
);
return $dist * 6371;
}