Xmap.cz
Všechny návody
PostGIS9 min čtení27. srpna 2026

Od staženého SHP k dotazovatelné databázi (PostGIS)

Stáhli jste vrstvu ve formátu SHP v S-JTSK. Ukážeme, jak ji naimportovat do PostGIS, dát na ni index a pak se ptát: co je uvnitř polygonu, co je do 5 km, jak daleko to je.

PostGIS je rozšíření Postgresu pro geodata a je to nejpřímější cesta, jak se dat ptát na prostorové otázky. Tenhle návod vás provede od syrového SHP souboru k funkčním dotazům. Předpokládá běžící Postgres a nainstalované nástroje gdal-bin a postgis.

1. Zapnout PostGIS

CREATE EXTENSION IF NOT EXISTS postgis;

2. Import SHP s reprojekcí do WGS84

České vrstvy jsou v S-JTSK (EPSG:5514). Rovnou je při importu přepneme do WGS84 (EPSG:4326), aby seděly na web. Nejrychlejší je shp2pgsql, univerzálnější ogr2ogr.

# shp2pgsql: -I rovnou vytvori prostorovy index, -s zdroj:cil reprojektuje
shp2pgsql -I -s 5514:4326 zaplavova_uzemi.shp public.zaplavy | psql "$DATABASE_URL"

# ogr2ogr: univerzalne (SHP/GeoJSON/GPKG -> PostGIS)
ogr2ogr -f PostgreSQL PG:"$DATABASE_URL" zaplavova_uzemi.shp \
  -nln zaplavy -t_srs EPSG:4326 -lco GEOMETRY_NAME=geom -nlt PROMOTE_TO_MULTI
Když import hlásí divné souřadnice nebo prázdný obsah, skoro vždy je to špatný zdrojový EPSG. Zkontrolujte ho příkazem ogrinfo -so -al soubor.shp, uvidíte i skutečný souřadnicový systém.

3. Prostorový index (bez něj to bude pomalé)

Prostorové dotazy bez indexu procházejí celou tabulku. GiST index to změní na milisekundy. Pokud jste importovali přes -I, už ho máte, jinak:

CREATE INDEX idx_zaplavy_geom ON zaplavy USING GIST (geom);

4. Ptejte se: čtyři nejužitečnější dotazy

-- Je bod v polygonu? (parcela v zaplavovem uzemi)
SELECT z.nazev FROM zaplavy z
WHERE ST_Contains(z.geom, ST_SetSRID(ST_MakePoint(14.42, 50.08), 4326));

-- Body uvnitr oblasti (inzeraty v obci)
SELECT * FROM inzeraty i JOIN obce o ON ST_Within(i.geom, o.geom)
WHERE o.nazev = 'Beroun';

-- Vse do 5 km od bodu (ST_DWithin je indexovatelne, rychle)
SELECT * FROM pobocky
WHERE ST_DWithin(geom::geography, ST_MakePoint(14.42, 50.08)::geography, 5000);

-- Vzdalenost v metrech (cast na geography pocita na elipsoidu)
SELECT nazev, ST_Distance(geom::geography, ST_MakePoint(14.42,50.08)::geography) AS m
FROM pobocky ORDER BY m LIMIT 10;

Dvě pravidla pro výkon

  • Pro měření v metrech castujte geometrii na geography (počítá na elipsoidu). Typ geometry ve stupních dává nesmysly.
  • V podmínce WHERE preferujte ST_DWithin před ST_Distance. Jen ten první umí využít index.

Kam s tím dál

Typický vzorec: zóny (třeba záplavová území nebo chráněná území) naimportujete jednou, a při ukládání každého záznamu předpočítáte příznak ST_Intersects a uložíte boolean. Filtrování v katalogu pak běží bleskurychle bez opakovaného geo-dotazu. Celý postup na konkrétním příkladu rozebírá případovka o záplavovém území.