Dostal jsem se k zajímavému projektu – geolog p. Mucha měl na svých stránkách zobrazená zajímavá místa, která navštívil. Každé místo mělo na své stránce uvedené souřadnice, ale jako součást běžného textu. Každé takové místo patřilo do nějaké lokality. Mým úkolem bylo na stránkách lokalit zobrazit mapu (pomocí Seznam map) s jednotlivými místy.
Potřeboval jsem tedy
- Získat potřebná data (viz. tento návod)
- Zobrazit je jako mapu s označením jednotlivých míst
Konečný výsledek vypadá takto:
https://www.geologie-astronomie.cz/Geologicke-lokality/Karlovarsko-a-za…
Jak získat strojová data
K zobrazení mapových bodu jsem potřeboval znát jejich souřadnici. Pro zobrazení různých značek – červené v aktuální lokaci, ostatní šedé – jsem potřeboval znát lokalitu dané souřadnice. Po kliknutí na bod se ukáže jeho jméno, obrázek a odkaz na detailní stránku.
Takže moje strojová data potřebovala obsahovat:
- Souřadnice x (49°59'50.519"N)
- Souřadnice y (12°37'12.477"E)
- Strojové jméno lokace (Karlovarsko-a-zapadni-Cechy)
- Jméno místa (Kynžvartský kámen)
- URL obrázku
- Link na detailní stránku
Vzhledem k tomu, že jsem i na mapě jednotlivé lokace zobrazoval všechny značky, potřeboval jsem jeden velký soubor (pole) s informacemi o všech místech. Bohužel jsem neměl přístup k plnému CMS či databázi, a stejně nějaké údaje (např. souřadnice) se vkládaly přímo do běžného textu stránky. Takže sem je potřeboval nějak „vysosat“.
Získání strojových dat
Začal jsem vytvářet jednoduchý PHP skript. Tam jsem si definoval pole jednotlivých lokalit, a to podle jejich URL.
Takže $lokace_all = array('Plzensko', 'Karlovarsko-a-zapadni-Cechy', ...
Tímto polem jsem procházel v cyklu a načítal HTML jednotlivých lokací:
$lokace_url = 'https://www.geologie-astronomie.cz/Geologicke-lokality/' . $lokace;
$html = file_get_html($lokace_url);
file_get_html() je základní funkce simplehtmldom, která načte DOM daného zdroje, v mém případě konkrétní lokace, kde jsem hledal potřebné údaje. Po prozkoumání kódu jsem se zaměřil na hledání CSS třídy photo_gal_heading.
Z tagu <a> získám link detailní stránky místa, z tagu <img> zase link na obrázek a jméno místa. Spolu s tím si i uložím informaci o jménu dané lokace.
Takovýchto míst je v každé lokaci několik. Takže všechny místa – znám jejich link – potřebuju opět načíst a z jejich HTML kódu získat tentokráte souřadnice. Na to už mi přišlo zbytečné volat opět DOM, vystačil jsem si s běžnou PHP funkcí file_get_contents(), která vrátí HTML kód jako jeden velký řetězec. Tam jsem hledal řetězce jako '49°' nebo '50°' pro zeměpisnou šířku, resp. '12°' - '17°' pro zeměpisnou délku.
Celé výsledné pole jsem potom uložit jako JSON řetězec.
Takhle nějak vypadá příslušná část kódu:
A výsledný JSON (výstup json_encode()):
Optimalizace
Ukázalo se, že takovýto skript, zpracovávající desítky míst (tedy desítky volání file_get_contents()) dohromady s devíti voláními file_get_html() trvá poměrně dlouho, cca 10 sekund. To v reálném fungování znamenalo zbytečný prostoj. Vzhledem k tomu, že v tomto konkrétním případě nepotřebujeme získávat 100% aktuální data (místa se nemění/nevytváří často), stačí tento skript volat pomocí cronu třeba jednou denně, a výstup si ukládat do souboru.
Závěr
V tomto návodu jsem ukázal jednoduchý příklad užití knihovny “PHP Simple HTML DOM Parser” pro získání dat z HTML souboru. Jeho možnosti můžete rychle prozkoumat nahlédnutím do jeho manuálu https://simplehtmldom.sourceforge.io/manual.htm.
Takto získaná data jsem následně zobrazil pomocí seznamáckých map - viz. Jak zobrazit vlastní body a značky na turistické mapě od Seznamu?.