Eszköztár
128 Kezdőlap - Webszerkesztés - PHP - Távolság API
ujdomainek.hu

Távolság API

Ha nincs, akkor készítsünk!

Jegyzet

Kézenfekvő gondolatnak tűnik, hogy ha a Google-nek van szabadon használható térképe, amelyen meg lehet határozni két földrajzi hely között a távolságot (sőt az utazási időt is), akkor mindezt egy API-n keresztül is lehetőség van lekérdezni. Valóban így van: erre való a Google Distance Matrix API, de ez sem nem ingyenes, sem nem használható általánosan, anonim módon.

Mi tehetünk ilyenkor? Esetleg mi is készíthetnénk egy sajátot?

1.AEgy földrajzi hely GPS koordinátáinak meghatározása

Vajon létezik-e más, ingyenes, nyílt forráskódú térkép, melynek alapján vélelmezhetünk API-t, ami lehetővé teszi a távolságmérést? Vagy legalább azt, hogy egy földrajzi név esetén megtudhassuk a hozzá tartozó GPS koordinátákat. Eszünkbe juthat az openstreetmap.org weboldal, aminek a nevét összekombinálva az API szóval rákereshetünk az openstreetmap API kifejezésre. Innen már hamar eljutunk a nominatim.org oldalra, mely egészen hasznos információkat kínál számunkra: éppen az OpenStreetMap API-jának elérhetőségét és leírását. Ez alapján ha rá szeretnénk keresni pl. Velence településre, akkor azt ekképpen tehetjük meg: https://nominatim.openstreetmap.org/search?q=velence&format=jsonv2 ami olvashatóbban megjelenítve így néz ki.

Két tapasztalattal azonnal gazdagabbak lehetünk: Érdemes tesztelni az API-t: mit mond, ha a keresett település pl. Visegrád, vagy éppen Verőce! És vajon csak településeket ismer az API? Vagy egyéb helyeket is megtalál? Mint kipróbálható, az openstreetmap.org API-ja valóban jól vizsgázik a fenti keresések esetén is. Épp úgy be tud azonosítani intézményneveket, vagy turisztikai látványosságoat, mint ahogyan a különböző a településrészek is felismeri. Ugyanakkor az Üllői út vonatkozásában érdemes észre venni, hogy ennek a budapesti útnak a teljes hossza eléri a 15 km-t, így célszerű lehet tesztelni az API-t, vajon a házszámokkal is boldogul-e. Néhány kísérlet után be kell látnunk: az API nincs felkészítve a címekben található házszámok kezelésére.

1.BCímkereső API GPS koordináták visszaadásával

Vajon milyen találatokat kapunk Google-ben az address API kifejezés keresése esetén? A találatok között turkálva felfedezhetünk egy érdekes ajánlatot: European Union Address API Belelapozva az ENDPOINTS menüpont tartalmába, nemcsak leírást, hanem konkrét példákat is találunk, melyek alapján tesztelhetjük az 1. pontban tárgyalt API gyenge pontját, vagyis az Üllői út házszámait: Csekkolva a visszaadott GPS koordinátákat, megállapíthatjuk, hogy ez az API csakugyan jól vizsgázik házszámmal történő keresés esetén is - némi kiegészítéssel. Egyrészt nem szabadszavasan, hanem struktúráltan kell paraméterezni, vagyis külön-külön paraméterben kell megadni a várost, az utcát, és a házszámot. Másrészt Budapest esetén a kerületet is muszáj megadni, ellenkező esetben többnyire nem kapunk találatot.

Az API tehát meglehetősen ügyes konkrét címek keresése esetén, de vajon boldogul-e a nem címekkel adott földrajzi helyekkel? A válasz nem túl pozitív, hiszen végignézve a kapcsolódó dokumentációt, a struktúrált paraméterezés lehetőségei között egész egyszerűen nem található olyan opció, ahol meg lehetne adni intézményt, turisztikai látványosságot, vagy éppen tavak nevét. Tapasztalhatjuk továbbá, hogy nem ismeri fel az egyes települések nevesebb településrészeit sem, mint pl. Lillafüred, Mátraszentistván, vagy épp Salgóbánya.

 2. GPS koordinátákkal adott földrajzi helyek közötti távolság

Kiindulási elképzelésünk alapján olyan szabad felhasználású API-t kerestünk, mely meg tudja mondani két tetszőleges földrajzi hely között a távolságot. Ám ha ilyet nem találunk, az még nem jelenti azt, hogy olyanra sem bukkanhatunk rá, ami GPS koordinátákkal adott helyek közt mondja meg a távolságot. Ráadásul ha találnánk ilyet, akkor a fenti két API felhasználásával már tudnánk saját API-t készíteni a kívánt cél eléréséhez.

De vajon hogyan kell meghatározni a távolságot földrajzi koordinátákkal adott helyek között?
A kérdés azért is érdekes, mert ha a távolságot légvonalban értjük, akkor igazából API-ra sincs szükség, csupán matematikára.
A térképen a Föld gömb jellege miatt - külö-nösen nagy távolságok, pl. a légiközlekedés esetén - nem mindig a legrövidebbnek tűnő út a legrövidebb.
Ám ekkor is van lehetőség kiszámolni a távolságot a földrajzi koordináták alapján, pl. a Haversine formulával: ahol értelemszerűen a lat, és a lon értékei a szélességi és a hosszúsági fokokat jelölik, illetve R a Föld sugara, melynek középértéke 6371 km.
Persze, nem sokra megyünk a matematikával, ha mi a közúti távolságra vagyunk kíváncsiak.

Rákeresve a from gps to distance api free kifejezésre mi most teszteljük le az Open Source Routing Machine ajánlatát a project-osrm.org oldalon. Itt válasszuk a Documentation gombot! A lehetőségek között görgetve rátalálhatunk a Trip service opcióra, mely egy kiindulási pont és egy úticél GPS koordinátái között képes megadni a térképi távolságot (méterben), illetve az ennek megtételéhez szükséges időt (másodpercben). Vegyük észre azonban, hogy a szokásostól eltérő módon ez az API fordított sorrendben várja a szélesség-magasság koordináta-párokat, vagyis a korábbi API-k által kapott [lat,lon] adatpárost megcserélve kell majd a mostani API-nknak odaadni!

Teszteljük!

1. tesztpélda

Szeretnénk eljutni Budapestről a Népligettől Keszthelyre a Festetics-kastélyhoz. Mennyi idő kell ehhez? Milyen hosszú az út?

A Népliget GPS koordinátái az OpenStreetMap API-ja szerint lat:47.4752959, lon:19.0999512 A Festetics-kastély GPS koordinátái az OpenStreetMap API-ja szerint lat:46.7707287, lon:17.24190147849614 Ezeket a koordinátákat odaadva az OSRM API-jának (figyelve a fentebb már említett lat-lon cserére) azt kapjuk, hogy a két helyszín között
  • a távolság 194215.7, vagyis nagyjából 194 km
  • az utazási idő pedig 7790.3, tehát kb. 2 óra 10 perc
Ellenőrzésként hasonlítsuk össze a kapott adatokat a Google Maps által mondott adatokkal!

Mint látható, a távolság kilométerre pontosan egyezik, az utazáshoz szükséges időt azonban a forgalmi adatok függvényében nem feltétlenül azonosan számítja a két térkép.
2. tesztpélda

Határozzuk meg, milyen hosszú az Üllői út!

Az Üllői út 2. GPS koordinátái az EU Address API-ja szerint "XY":[19.0630406,47.4892366] Az Üllői út 798. GPS koordinátái az EU Address API-ja szerint "XY":[19.2337405,47.4239647] Ezeket a koordinátákat odaadva az OSRM API-jának (a lat-lon csere itt nem szükséges, mert az EU Address API is fordítva dolgozik velük) azt kapjuk, hogy a két helyszín között
  • a távolság 16890.5, vagyis 16,89 km
Ellenőrzésként hasonlítsuk össze a kapott adatokat a Google Maps által mondott adatokkal!

Itt érdemes észrevenni, hogy bár a két térkép szinte méterre pontosan azonos távolságot ad vissza, valójában nem az Üllői út hosszát kaptuk meg, hanem a két végpont között leggyorsabban megtehető útnak a hosszát. Ám ez egy picit hosszabb út, mintha végig az Üllői úton mennénk.
Tesztpéldáink meggyőzhetnek minket arról, hogy a felhasznált API-k lehetővé teszik egy saját Distance API megalkotását.

Feladat

A fent bemutatott API-k összeépítésével készítsen saját API-t, mely két adott földrajzi hely között képes megmondani A távolságokat kilometerben, egytizedes pontossággal, az időt pedig percben, egész számra kerekítve adja vissza!

Oldja meg, hogy az API akkor is működjön, ha a felhasználó különféle földrajzi helyeket (városokat, település-részeket, turisztikai látványosságokat, intézményneveket, stb.) szeretne szerepeltetni a keresésben, és akkor is, ha inkább konkrét címeket adna meg házszámok használatával együtt.

Az API kényelmesebb tesztelhetősége érdekében készítsen webes űrlapot (frontend felületet), melyen szövegesen megadható a tervezett utazás kiindulási pontja, illetve a kívánt érkezési hely. E felületen oldja meg az API által visszaadott értékek megjelenítését is, de egy linken keresztül adjon lehetőséget rá, hogy az érdeklődők az API eredményeit közvetlenül az API-hívással is megtekinthessék a böngészőben, egy önálló fülön!

Tipp a megoldáshoz

Munkánk során tapasztalni fogjuk, hogy az OpenStreetMap API-ja nem hagyja magát kiolvasni a szokásos módon, vagyis az fopen() függvénnyel. Éppen ezért itt egy picit összetettebb megoldásra lesz szükség. Ehhez használja az alábbi PHP forráskódot!
$url = "https://nominatim.openstreetmap.org/search?q=Galyateto&format=json";

$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36");

$json = curl_exec($ch);

curl_close($ch);

Precizitás és anomáliák

Vegyük észre, hogy helyenként meglehetősen fontos a földrajzi hely precíz megnevezése ahhoz, hogy találatként, pláne első találatként valóban a keresett helyet kapjuk eredményül. Lássunk néhány félreértési lehetőséget. Hasonló tapasztalatokba Ön is beleszaladhat. Ilyenkor kísérletezzen, pontosítson - és igyekezzen úgy megírni a feladatként elkészítendő API-t, hogy az

Minta

Nézzünk mindkét esetre egy-egy lehetséges példát!

Ha van találat a kiindulási és az érkezési helyre is http://localhost/api/tavolsag/?from=bkszc&to=jégpark akkor a kapott JSON kibontva pl. az alábbi tartalommal bírhat:
stdClass Object
(
    [result] => ok
    [from] => stdClass Object
        (
            [query] => bkszc
            [gps] => 47.41978215,19.05715843424581
            [location] => BKSZC Weiss Manfréd Szakgimnáziuma és Szakközépiskolája, 7, Tanműhely köz, Csepel-Gyártelep, XXI. kerület, Budapest, Közép-Magyarország, 1211, Magyarország
        )
    [to] => stdClass Object
        (
            [query] => jégpark
            [gps] => 47.4297729,19.0672983
            [location] => Csepeli Jégpark Jegypénztár, II. Rákóczi Ferenc út, Csepel-Gyártelep, XXI. kerület, Budapest, Közép-Magyarország, 1211, Magyarország
        )
    [distance] => stdClass Object
        (
            [airkm] => 1.3
            [km] => 1.8
            [time] => 4
        )
)
Tehát a két helyszín között a távolság légvonalban 1,3 km, ám ez közúton valójában 1,8 km, melyet autóval 4 perc alatt lehet megtenni.

Ha nincs találat pl. az érkezési helyre http://localhost/api/tavolsag/?from=bkszc&to=nszfh akkor a kapott JSON hasonló lehet:
{"result":"error","error":"to is unknown","documentation":"http://localhost/api/"}


előző oldal random oldal következő oldal


2024-06-24 03:24:46 Admin Köszönöm, ha Ön lesz az első, aki megírja ide véleményét, észrevételét, kérdését ezzel a lappal kapcsolatban.




Új hozzászólás:
E-mail cím:


Erre a címre küldjük ki a hozzászólás jóvá- hagyásához szükséges linket. Az e-mail címet sehol nem tesszük közzé.

Név:


Ez a név fog megjelenni az Ön hozzászólásai mellett.

Mennyi tizenhárom + négy?
Számjegyekkel írja be!



Ez a robotok beírása elleni védelem miatt szükséges ellenőrzés.


© infojegyzet.hu, 2024. január