21. 1. 2014, Vladimír Klaus, přečteno 9414x
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.
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
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
Tweet