Interaktivní mapa PSČ České republiky
Mapu poštovních směrovacích čísel (PSČ) v České republice nelze jednoduše stáhnout. A platit v dnešní době paušální poplatky za něco, co pravděpodobně zvládnu automatizovat sám s trochou Vibe codingu, mi bylo nepříjemné. A tak vznikl tento jednodenní projekt.
Motivace a cíle
PSČ není oficiální územní jednotka, jde o doručovací atribut přiřazený jednotlivým adresním bodům. Žádná oficiální mapa PSČ tedy neexistuje a Česká pošta se o ni ani nesnaží. V Triton IT jsme ji ale potřebovali pro zónování dopravy se zákazníkem. Cílem projektu bylo poskytnout veřejně dostupnou mapu, na které uživatel rychle zjistí, které PSČ pokrývá konkrétní oblast. Bez registrace, bez plateb, bez backendu, čistě statická webová stránka hostovatelná na GitHub Pages.
Jediný spolehlivý zdroj představuje RÚIAN (Registr územní identifikace, adres a nemovitostí) spravovaný ČÚZK. Obsahuje přibližně 3 miliony adresních bodů, každý s přiřazeným PSČ a souřadnicemi v systému S-JTSK. Z těchto bodových dat bylo nutné odvodit plošné hranice jednotlivých PSČ.
Hledání správného algoritmu
Pokus první: Alpha Shapes (konkávní obálky)
První verze využívala algoritmus Alpha Shapes - konkávní obálky, které lépe kopírují skutečný tvar zástavby než jednoduchý konvexní obal. Adaptivní parametr alpha se měnil podle hustoty bodů: nižší hodnota pro městskou zástavbu (těsnější obrys), vyšší pro venkovské oblasti.
Problém: Mezi jednotlivými PSČ vznikaly mezery, tj. „území nikoho", kde nebyla přiřazena žádná oblast. Vizuálně nepříjemné a prakticky matoucí.
Pokus druhý: Delaunay triangulace
Druhý přístup použil Delaunayovu triangulaci s filtrováním hran. Umožňoval generovat duté a konkávní tvary, ale mezery mezi PSČ přetrvávaly.
Finální řešení: Voronoi tessellation
Vrátili jsme se k přístupu používanému například v Google Maps. Voronoiův diagram přiřadí každému adresnímu bodu buňku obsahující prostor, který je k němu nejblíže. Buňky se stejným PSČ se sloučí a hranice se vyhladí algoritmem Douglas-Peucker.
Výhody Voronoiho přístupu:
- Vyplňuje celý prostor bez mezer
- Hranice jsou přirozené, vedou přesně uprostřed mezi sousedními adresami
- Jasně definované sousedství oblastí
Pro osamocené adresy (1-2 body) se použije kruhový buffer jako fallback.
Barevné rozlišení sousedů
Aby mapa byla čitelná, sousedící PSČ musí mít různé barvy. K tomu slouží Welsh-Powellův greedy algoritmus pro barvení grafů. Výsledkem je paleta pouhých 4 barev (teoreticky podle čtyřbarevné věty), kde žádná dvě sousedící PSČ nemají stejnou barvu.
Architektura
Projekt je rozdělen na dvě části:
- Offline ETL pipeline (Python) - výpočetně náročné zpracování dat
- Statická webová prezentace - vektorové dlaždice (MVT) + MapLibre GL JS
Data se transformují ze souřadnic S-JTSK do WGS84, generují se polygony a následně vektorové dlaždice pomocí nástroje tippecanoe. Výstupem je složka se statickými soubory, kterou lze nahrát na jakýkoliv hosting.
Závěr
Po třech iteracích algoritmu jsme konvergovali k Voronoiho tessellaci jako nejlepšímu řešení pro odvození hranic PSČ z bodových dat. Mapa je nyní dostupná na [mapa-psc.marekrost.cz](https://mapa-psc.marekrost.cz/) a [zdrojový kód](https://github.com/marekrost/mapa-psc) je otevřený pod licencí GPL-3.0.
Zobrazené hranice jsou z principu aproximací. Skutečná příslušnost k PSČ je vždy definována pouze pro konkrétní adresní místa. Mapa slouží k orientaci a vizualizaci, nikoliv jako oficiální podklad.