Výpočet vzdálenosti z GPS souřadnic

Při práci se souřadnicemi často narazíte na úkol určit vzdálenost dvou míst. Poradíme vám jak na to.

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 Pythagorovo 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 ve stupních. Pro výpočet v radiánech je třeba konstantu poloměru Země 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 * 111.19;
}

 

 

Mohlo by vás také zajímat

Sentry Performance, PHP a GraphQL

Jak využít Sentry Performance pro monitoring výkonu PHP aplikace včetně výkonu GraphQL API.

Číst více

PHP8.1, Enum třídy a Doctrine

Jednou z novinek PHP8.1 je i podpora Enum tříd. Tento zápisek vznikl jako stručné intro k tomu, jak lze tuto novinku používat ve spojení s Doctrine.

Číst více

Symfony, lokální server a důvěryhodný SSL certifikát v Chrome

Nastavte si důvěryhodný certifikát v Chrome i pro vývoj Symfony aplikací

Číst více

nám. Republiky 28
301 00 Plzeň
Česká republika
IČ: 28006402
DIČ: CZ28006402

© 2002 - 2024 iD-SIGN BRANDS MENTIONED ABOVE ARE PROPERTY OF THEIR RESPECTIVE OWNER.