Xmap.cz
Všechny návody
Adresy9 min čtení15. září 2026

Jak převést adresy na souřadnice zdarma (geokódování z RÚIAN)

Seznam adres v tabulce je k mapě nanic, dokud nemá souřadnice. Placené API na to ale potřeba není: stát zveřejňuje všechna česká adresní místa i s polohou v jednom měsíčním ZIPu. Ukážeme, jak z něj postavit vlastní geokodér a na které pasti v datech narazíte.

Máte v tabulce seznam poboček, zákazníků nebo svozových míst a chcete je dostat do mapy. Chybí jediná věc, souřadnice. První reakce bývá sáhnout po placeném geokódovacím API, jenže u českých adres to ve většině případů není potřeba. RÚIAN obsahuje kompletní seznam adresních míst v ČR včetně polohy a stahuje se zdarma jako CSV. Postavíte z něj geokodér, který běží u vás, nemá limit na počet dotazů a neposílá adresy vašich zákazníků nikam ven.

Co je adresní bod a kolik jich je

Adresní místo je v RÚIAN samostatný objekt s vlastním kódem (kód ADM). Má přiřazenou obec, část obce, případně ulici, číslo domovní a orientační, PSČ a souřadnice. K 31. 8. 2026 jich bylo 3 021 203, z toho 2 614 947 s číslem popisným a 406 256 s číslem evidenčním, což jsou typicky chaty a rekreační objekty.

Adresní bod není střed budovy ani střed parcely, je to definiční bod adresy, obvykle u vstupu. Pro doručování a špendlíky v mapě je to přesně ono. Na plošné analýzy zástavby sáhněte radši po definičních bodech a polygonech staveb, které RÚIAN nabízí zvlášť.

Stažení: jeden ZIP za celou republiku

ČÚZK publikuje adresní místa jako CSV ve Veřejném dálkovém přístupu, v sekci Výměnný formát. Soubor vzniká jednou měsíčně a nese v názvu datum posledního dne měsíce, denní varianta CSV neexistuje. Celá republika je jeden ZIP kolem 63 MB, uvnitř 6 258 souborů, jeden na každou obec. Stáhnout jde i jediná obec zvlášť, když vám stačí jedno město.

# Cela CR, jeden ZIP (cca 63 MB), uvnitr 6258 CSV po obcich
curl -O https://vdp.cuzk.gov.cz/vymenny_format/csv/20260831_OB_ADR_csv.zip
unzip 20260831_OB_ADR_csv.zip          # -> CSV/20260831_OB_*.csv

# Jen jedna obec, cislo v nazvu je kod obce z RUIAN (554782 = Praha)
curl -O https://vdp.cuzk.gov.cz/vymenny_format/csv/20260831_OB_554782_ADR.csv.zip

Kód obce najdete v číselníku obcí ve VDP nebo v katalogovém záznamu RÚIAN. Pro představu o velikosti: Praha má 134 627 adresních bodů, běžná vesnice jich má pár desítek.

Tři pasti, které v CSV čekají

  • Kódování je Windows-1250, ne UTF-8. Bez převodu se z Údolní stane nečitelný paskvil a zpětně to nespravíte. Převádějte hned při rozbalení, ne až v aplikaci.
  • Souřadnice jsou kladné a prohozené. S-JTSK má osy obráceně proti tomu, co čeká většina nástrojů, a CSV je navíc uvádí bez znaménka. Do EPSG:5514 patří hodnota ze sloupce Souřadnice Y na vodorovnou osu, hodnota ze sloupce Souřadnice X na svislou, a obě se znaménkem minus. Pražský hrad má v CSV 744384.54 a 1042569.73, správně je to tedy bod -744384.54, -1042569.73, po převodu 50,0895 severní šířky a 14,3986 východní délky.
  • Pár set řádků souřadnice vůbec nemá. Ve snímku z 31. 8. 2026 jich bylo 918. Prázdné pole si většina nástrojů tiše přepíše na nulu, jenže nula v EPSG:5514 leží až u Tallinnu. Takové řádky vyhoďte hned při zpracování.

Z CSV na mapu bez databáze

Nejdřív z 6 258 souborů uděláme jeden a rovnou ho překlopíme do UTF-8. Hlavička musí zůstat jen jedna, proto se ze zbylých souborů bere až druhý řádek dál.

# Hlavicka jednou, zbytek bez hlavicek, vse z Windows-1250 do UTF-8
head -1 CSV/20260831_OB_500011_ADR.csv | iconv -f CP1250 -t UTF-8 > adresy.csv
for f in CSV/*.csv; do tail -n +2 "$f"; done | iconv -f CP1250 -t UTF-8 >> adresy.csv

Teď dopočítáme sloupce se správně otočenými souřadnicemi a předáme to nástroji ogr2ogr, který z CSV udělá GeoPackage rovnou reprojektovaný do WGS84 pro web.

# Prida sloupce x, y v EPSG:5514 a vyhodi radky bez souradnic
awk -F';' 'BEGIN{OFS=";"} NR==1{print "x","y",$0; next} \
  $17!="" && $18!="" {printf "%.2f;%.2f;%s\n", -$17, -$18, $0}' adresy.csv > adresy_xy.csv

ogr2ogr -f GPKG adresy.gpkg adresy_xy.csv \
  -oo X_POSSIBLE_NAMES=x -oo Y_POSSIBLE_NAMES=y \
  -s_srs EPSG:5514 -t_srs EPSG:4326 -nln adresy
Formátování přes printf s %.2f v tom awku není kosmetika. Bez něj zapíše awk dlouhá čísla vědeckou notací (-1.04257e+06), GDAL je načte se ztrátou přesnosti a adresy se rozjedou o stovky metrů. Hotový GeoPackage otevřete v QGIS dvojklikem, viz Jak začít s QGIS.

Geokodér v PostGIS

Když adresy hledáte opakovaně a programově, patří data do databáze. Postup navazuje na návod Od staženého SHP k dotazovatelné databázi, jen místo importu vrstvy nahrajete CSV a geometrii dopočítáte v SQL.

CREATE TABLE adresy (
  kod_adm bigint, kod_obce integer, nazev_obce text,
  kod_momc integer, nazev_momc text, kod_mop integer, nazev_mop text,
  kod_casti_obce integer, nazev_casti_obce text,
  kod_ulice integer, nazev_ulice text, typ_so text,
  cislo_domovni text, cislo_orientacni text, znak_cisla_or text,
  psc text, souradnice_y double precision, souradnice_x double precision,
  plati_od timestamp
);

\copy adresy FROM 'adresy.csv' WITH (FORMAT csv, DELIMITER ';', HEADER true)

ALTER TABLE adresy ADD COLUMN geom geometry(Point, 4326);
UPDATE adresy SET geom = ST_Transform(
  ST_SetSRID(ST_MakePoint(-souradnice_y, -souradnice_x), 5514), 4326)
  WHERE souradnice_y IS NOT NULL;
CREATE INDEX ON adresy USING GIST (geom);

Čísla domovní a orientační nechte jako text, ne jako celé číslo. Budete je porovnávat s tím, co do formuláře napsal uživatel, a k číslu orientačnímu navíc patří písmenný znak z vedlejšího sloupce, takže se stejně skládají jako řetězce. Pro samotné hledání se pak hodí normalizovaná podoba názvů, aby Udolni našlo Údolní. Tady číhá drobná past: funkce unaccent() není v Postgresu označená jako IMMUTABLE, takže ji nejde použít přímo ve funkčním indexu. Řeší to vlastní obalová funkce.

CREATE EXTENSION IF NOT EXISTS unaccent;

-- unaccent() neni IMMUTABLE, v indexu ji musi obalit vlastni funkce
CREATE FUNCTION norm(t text) RETURNS text AS $$
  SELECT lower(unaccent('unaccent', t))
$$ LANGUAGE sql IMMUTABLE STRICT PARALLEL SAFE;

CREATE INDEX ON adresy (norm(nazev_obce), norm(nazev_ulice), cislo_domovni);

SELECT kod_adm, ST_Y(geom) AS lat, ST_X(geom) AS lon
FROM adresy
WHERE norm(nazev_obce) = norm('praha')
  AND norm(nazev_ulice) = norm('vinohradska')
  AND (cislo_domovni = '1511' OR cislo_orientacni = '230');

Proč hledání na ulici a číslo často selže

Geodata jsou ta snadnější část. Většina práce je v tom, jak lidé adresy píšou. Čtyři případy, na kterých naivní porovnání spolehlivě padá:

  • Číslo popisné versus orientační. Adresa Vinohradská 230 v Praze je v datech číslo domovní 1511 a číslo orientační 230. Když porovnáváte jen se sloupcem Číslo domovní, neuspějete u velké části městských adres. Testujte oba sloupce a počítejte i s tvarem 1511/230.
  • Skoro polovina adres nemá ulici. Bez názvu ulice bylo 1 443 867 záznamů, tedy zhruba 48 procent všech adresních míst. Ve vesnicích je adresa daná částí obce a číslem popisným, třeba Světlá nad Sázavou, část Dolní Dlužiny, č.p. 1. Dotaz, který vyžaduje vyplněnou ulici, tyhle adresy nikdy nenajde.
  • Městské části. Lidé píšou Praha 3 nebo Brno-střed, jenže ve sloupci Název obce je pořád jen Praha, respektive Brno. Městská část je zvlášť ve sloupci Název MOMC. Před porovnáním obec ořízněte na základní tvar a městskou část berte jen jako doplňkové kritérium.
  • Písmeno za číslem. Tvar 12a má číslo a písmeno rozdělené, znak je v samostatném sloupci Znak čísla orientačního. Při porovnávání si ho musíte zpátky slepit.

Reverzní geokódování: ze souřadnic na adresu

Stejná tabulka umí i opačný směr, tedy najít nejbližší adresu k poloze z telefonu nebo ke kliknutí do mapy. Stačí druhý index nad geografickým typem, aby operátor nejbližšího souseda počítal v metrech a ne ve stupních.

CREATE INDEX ON adresy USING GIST ((geom::geography));

WITH bod AS (
  SELECT ST_SetSRID(ST_MakePoint(16.5924, 49.1982), 4326)::geography AS g
)
SELECT nazev_ulice, cislo_domovni, cislo_orientacni, nazev_obce, psc,
       round((geom::geography <-> bod.g)::numeric, 1) AS vzdalenost_m
FROM adresy, bod
ORDER BY geom::geography <-> bod.g
LIMIT 1;

Kdy má naopak smysl sáhnout po API

Vlastní data se vyplatí na dávkové, opakované nebo offline zpracování. Na pár dotazů denně je jednodušší hotová služba, a někdy potřebujete i to, co SQL neumí, tedy našeptávání a toleranci k překlepům.

  • Nominatim nad daty OpenStreetMap je zdarma, ale veřejná instance má tvrdý strop jeden dotaz za sekundu, vyžaduje vlastní identifikaci v hlavičce User-Agent a hromadné geokódování na ní provozní pravidla zakazují. Na větší objem si ji musíte rozjet sami.
  • REST API Mapy.com je komerční, ale základní tarif dává 250 000 kreditů měsíčně zdarma a jedno vyhledání adresy stojí 4 kredity, tedy zhruba 62 000 dotazů měsíčně bez placení. Zvládá našeptávání i překlepy.
  • Ověření adresy přímo ve VDP je interaktivní formulář na jednu adresu. Hodí se na ruční kontrolu sporných případů, ne na dávku.
Shrnutí: na dávkové geokódování českých adres nepotřebujete placenou službu, jen jeden měsíční ZIP z ČÚZK, převod kódování a otočení znamének u souřadnic. Data jsou otevřená pod stejnou licencí jako zbytek RÚIAN, viz Licence, takže je můžete použít i komerčně, jen s uvedením zdroje.