Zjišťujeme vzdálenost mezi dvěma GPS souřadnicemi, tentokrát v ASP.NET

21. 1. 2014, Vladimír Klaus, přečteno 6202x

ASP.NET/C#

K napsání tohoto článku mě vedla potřeba zjistit, jak daleko jsou od sebe dvě fotky. Přesněji řečeno, jak hodně špatně se určila poloha u jedné fotky, zatímco u druhé byla zcela korektní, přičemž obě byly pořízené jen pár metrů od sebe.

Zjišťujeme vzdálenost mezi dvěma GPS souřadnicemi, tentokrát v ASP.NET

Na webu se dá najít spousta (šílených) vzorečků, návodů a matematických vysvětlení, jak to celé funguje. Nebojte, takovými detaily se tu zabývat nebudu.

Pro výpočet budeme potřebovat goniometrické funkce. Drobnou komplikací je to, že v Math knihovně očekávají tyto funkce úhel v radiánech. Nejprve si tedy napíšeme jednoduchou převodní funkci.

    //pomocná funkce na převod stupňů na radiány
    double DegToRad(double uhel) {
        return uhel * Math.PI / 180.0;
    }

Pak už přijde na řadu vlastní výpočet, který vypadá docela sofistikovaně.

    //funkce, na výpočet přibližné vzdálenosti dvou míst zadaných
    //pomocí dvou zeměpisných šířek a délek
    double VzdalenostNaZemi1(double sirka1, double delka1,
                             double sirka2, double delka2) {
        //přibližný "průměrný" poloměr Země (není to koule, takže
        //to je na různých místech různé)
        var R = 6371;
        //zjistím rozdíl šířek a délek
        var rozdilSirek = DegToRad(sirka2-sirka1);
        var rozdilDelek = DegToRad(delka2-delka1);
        sirka1 = DegToRad(sirka1);
        sirka2 = DegToRad(sirka2);
        var a = Math.Sin(rozdilSirek/2) * Math.Sin(rozdilSirek/2) +
                Math.Sin(rozdilDelek/2) * Math.Sin(rozdilDelek/2) *
                Math.Cos(sirka1) * Math.Cos(sirka2); 
        var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1-a)); 
        var d = R * c;

        //vrátím vzdálenost v kilometrech
        return d;
    }

Je tu ale ještě jedna jednodušší funkce, jak určit vzdálenost na povrchu koule.

    //jednodušší, přesto přesná (srovnatelná) metoda
    double VzdalenostNaZemi2(double sirka1, double delka1,
                             double sirka2, double delka2)  {
        sirka1 = DegToRad(sirka1);
        delka1 = DegToRad(delka1);
        sirka2 = DegToRad(sirka2);
        delka2 = DegToRad(delka2);

        return 6371 * Math.Acos(
            Math.Sin(sirka1) * Math.Sin(sirka2)
            + Math.Cos(sirka1) * Math.Cos(sirka2)
            * Math.Cos(delka2 - delka1));
    }

Jako příklad můžeme vzít tyto souřadnice.

GPS 1 = 50.128328, 14.493012
GPS 2 = 50.126062, 14.443097

Výsledek obou funkcí je v podstatě identický.

vzdálenost 1 = 3,56712317650752
vzdálenost 2 = 3,56712317775145

Zjišťujeme vzdálenost mezi dvěma GPS souřadnicemi, tentokrát v ASP.NET

Obě funkce VzdalenostNaZemi() nám tedy vracejí 3,567 km, zatímco měření na mapy.cz ukáže 3,577 km. Rozdíl je tedy pouhých 10 m, což je myslím vynikající. Nemám ponětí o tom, jak Seznam určuje vzdálenosti a tak nelze říci, co je přesnější. Pro mě bylo a je důležité, že funkce splnila účel a její naprogramování nebylo náročné.

Pokud budete zadávat polohu ze západní/jižní polokoule, nezapomeňte, že hodnoty musí být záporné. Například New York je na severní polokouli (+40 st. severní šířky), ale zároveň je také na západní polokouli (-74 st. západní délky). Zde jsou údaje pro Sochu Svobody a Central Park.

GPS 1 = 40.68962, -74.045647
GPS 2 = 40.782361, -73.965996

Vzdálenost opět vychází stejně, při měření na Google mapách je výsledek 12,3175 km, tedy opět rozdíl jen asi 14 m.

vzdálenost 1 = 12,3037262216122
vzdálenost 2 = 12,3037262213739

Pro nadšené matematiky uvádím ještě odkaz na další povídání a pěkné vzorečky.

http://en.wikipedia.org/wiki/Great-circle_distance