11. Mapové servery (GeoServer, MapServer) & Python klient (OWSLib)¶
V reálném (produkčním) nasazení je potřeba řešit zprovoznění nejen aplikační vrstvy mapového serveru, ale i webového serveru a jeho komunikace s mapovým serverem. V našem případě si tuto část výrazně zjednodušíme použitím předpřipravených Docker obrazů, které mají mapový a webový server již integrován v podobě izolovaného prostředí.
Docker je technologie sloužící pro izolaci aplikací ve formě kontejnerů (wikipedia).
Seznam příkazů:
docker pull
docker run
docker logs
docker exec
docker stop
docker rm
Mapové servery¶
GeoServer¶
GeoServer jestiť software otevřený pod licencí GNU GLPv2 určený pro sdílení, zpracování a editaci geoprostorových dat skrze internetové rozhraní. Často slouží jako spojovací článek mezi uživateli geoprostorových dat a daty samotnými. Jeho jádro je napsáno v programovacím jazyku Java. GeoServer započal svůj život roku 2001 jako projekt The Open Planning Project.
Mezi jeho nesporné výhody patří následující:
- Data uživatelům poskytována ve formátech definovaných OGC
- WMS
- WFS
- WCS
- WPS
- REST
- Podpora mnoha formátů geoprostorových dat
- Rozšířitelnost: Velké množství zásuvných modulů
- Škálovatelný
- Uživatelsky přístupné, klikací rozhraní
Nevýhody:
- Uživatelsky přístupné, klikací rozhraní
- Automatizace bývá zpravidla značně nepříjemná
- Způsob, jakým GeoServer jako nováček rozeběhnout s lokálními daty, bývá trpký
GeoServer je dokonce implementovaný i jako plugin pro QGIS (bohužel, k roku 2024 proběhla poslední aktualizace roku 2016): https://plugins.qgis.org/plugins/geoserverexplorer/#plugin-about
Spuštění GeoServer¶
Budeme pracovati s oficiální docker obrazem docker.osgeo.org/geoserver
. Ten si nejdřív stáhněme (docker pull
) a následně jej spusťme (docker run
) na pozadí (-d
, není nutné). Přepínač -p
slouží k přesměrování portu, na němž bude GeoServer přístupný. Přes parametr -v
si připojíme adresář do /opt/geoserver_data/data
- tento adresář nám umožní přidávati nová data do běžící instance GeoServeru.
docker pull docker.osgeo.org/geoserver:2.25.x
docker run -d -v /tmp/data_dir:/opt/geoserver_data/data -p 8080:8080 docker.osgeo.org/geoserver:2.25.x
Tip
Doporučujeme pro větší přehlednost svůj docker kontejner pojmenovat použitím --name my_geoserver
Přesvědčme se, zda naše instance běží v pořádku na adrese http://localhost:8080/geoserver.
Ve výchozím nastavení jsou administrátorské přihlašovací údaje následující:
Struktura dat¶
Jak si lze povšimnouti po přihlášení do rozhraní GeoServeru, data jsou strukturována následujícím způsobem:
- workspaces
- konvolut sloužící k organizaci sobě podobných vrstev dohromady
- definován jménem (
name
) a identifikátorem (Namespace URI
)
- data stores
- slouží k připojení datového zdroje obsahujícího rastrová či vektorová data
- může to býti soubor či skupina souborů, tabulka v databázi, adresář
- umožňuje definici parametrů spojení na jednom místě pro různé datové zdroje
- layers
- vrstvami jsou jednotlivé rastrové či vektorové datasety
Tvorba/upload dat¶
Vytvořme databázi zemětřesení. Vstupní data jsou otevřeně poskytována na stránkách USGS. Protože GeoServer bohužel nepodporuje data stores ve formátu GeoJSON, musíme je převésti do formátu jiného. K tomu můžeme využíti znalostí získaných v přednášce o knihovně a nástrojích GDAL/OGR.
Nejprve vytvořme odpovídající workspace ve Workspaces -> Add new workspace
.
Následně vytvořme odpovídající data store v Stores -> Add new store
. V našem případě vyberme data store založený na formátu GeoPackage.
Jest vhodné nalezenou vrstvu následně publikovati.
Při publikaci dat definujme souřadnicový systém a nejmenší ohraničující obdélník. Nejsnáze tak učiníme skrze možnost Compute from native bounds
.
Data si můžeme prohlédnout v záložce Layer Preview
.
Styly¶
Protože výchozí styl pro bodová data není dostatečně sexy, pokusme se bodům přiřaditi vábnější design. Učiňme tak v záložce Styles -> Add a new style
. Velkou výhodou je možnost generování stylů v software QGIS (jedná se o OGC standard SLD - Styled Layer Descriptor). Otevřeme si tedy data v QGISu a exportujme vhodný styl.
Důležité
Nezapomeňte při ukládání stylu zaškrtnout As SLD Style File
Následně si daný styl přiřaďme k vybrané vrstvě. Otevřeme-li si danou vrstvu, učiníme tak v záložce Publishing
.
Následně data již uvidíme v námi definovaném stylu.
Webové služby¶
Náš GeoServer nyní poskytuje data jako WFS službu. Námi publikovaným workspaces odpovídají adresy ve formátu http://localhost:8080/geoserver/workspace/ows?service=WFS. WFS si můžeme připojiti na příklad jakožto novou vrstvu v prostředí QGIS (Layer -> Add Layer -> Add WFS Layer
).
Tip
Preferujete-li GRASS GIS, můžete data importovati následujícím příkazem: v.in.wfs url="http://localhost:8080/geoserver/zemetreseni/ows?" out=zemetreseni_duben name=duben
Úkol
Učiňte totéž s exportem ve formě WMS.
MapServer¶
MapServer (https://mapserver.org/) je open source mapový server jehož vývoj započal již v polovině 90. let na univerzitě v Minnesotě (dříve byl označován jako UMN MapServer). Je publikován pod licencí MIT. Je napsán v jazyku C. Vyniká nejen svojí rychlostí, ale i malou paměťovou náročností (binární soubor má pouze několik desítek kilobajtů!).
Nastavení tohoto mapového serveru se typicky řídí pomocí jednoduchých konfiguračních souborů (tzv. "map files").
V následující části budeme použít sestavený Docker obraz dostupný z https://hub.docker.com/r/camptocamp/mapserver/. Obraz nejprve stáhneme k sobě na disk:
Vytvoříme pracovní adresář a přepneme se do něj:
WMS¶
V tomto adresáři vytvoříme konfigurační soubor mapové serveru (viz dokumentace).
Do konfigurace přidáme vrstvu (sekce
LAYER ) vodních toků (cesta
na GIS.labu: /mnt/repository/155FGIS/05/VodniTok.shp
). Lokální
adresář s daty (/mnt/repository/155FGIS
) připojíme posléze do
běžícího Docker kontejneru jako /mapfile
. Proto v konfiguračním
souboru uvedeme cestu /mapdata/05/data50/VodniTok.shp
.
MAP
NAME "FGIS"
STATUS ON
SIZE 600 400
EXTENT -904582 -1227334 -431727 -935354
UNITS meters
IMAGECOLOR 255 255 255
IMAGETYPE PNG
PROJECTION
"init=epsg:5514"
END
WEB
METADATA
"wms_title" "WMS FGIS Server"
"wms_onlineresource" "http://localhost:8090/?map=/etc/mapserver/fgis.map"
"wms_srs" "EPSG:5514"
"wms_enable_request" "*"
"wms_format" "image/png"
END
END
LAYER
NAME "vodni_toky"
STATUS ON
TYPE LINE
DATA "/mapdata/05/data50/VodniTok.shp"
CLASS
NAME "Vodní toky"
STYLE
COLOR 0 0 255
END
END
METADATA
"wms_title" "Vodní toky"
END
END
END
Tip
Prostorový rozsah datové kompozice můžeme zjistit pomocí příkazu knihovny GDAL ogrinfo
:
Následně spustíme instanci mapové serveru například na portu 8090:
sudo docker run -d \
--rm --name mapserver \
-v /mnt/repository/155FGIS:/mapdata/:ro \
-v $(pwd)/fgis.map/:/etc/mapserver/fgis.map:ro \
-p 8090:80 \
camptocamp/mapserver:8.0
Běžící mapový server otestujeme. Nejprve vyzkoušíme dotaz typu
GetCapabilities
:
http://localhost:8090/?map=/etc/mapserver/fgis.map&service=WMS&request=GetCapabilities
Dále otestujeme dotaz GetMap
, který vrací reálná data:
Do seznamu vrstev přidáme rastrová data:
LAYER
NAME "dtm"
STATUS ON
TYPE RASTER
DATA "/mapdata/05/dtm1m.tif"
METADATA
"wms_title" "DTM"
END
END
Důležité
Po každé změně mapového souboru je nutné Docker kontejner restartovat:
Úkol
Vrstva DTM se zobrazuje pomalu z důvodu velkého prostorového rozlišení (1m) a navíc v nevhodné tabulce barev.
Tento nedostatek vyřešíme buď přidáním pyramid (GDAL příkaz gdaladdo
) anebo převzorkováním do nižšího rozlišení (např. 10m) a nastavením vhodné tabulky barev. GDAL umožňuje nastavit tabulku barev ve formátu GeoTIFF pouze pro celočíselná data. Z tohoto důvodu převedeme hodnoty DTM na celočíselné. Tuto úpravu provedeme např. pomocí GRASS GIS:
grass -c EPSG:5514 wms_dtm
r.external -o in=/mnt/repository/155FGIS/05/dtm1m.tif out=dtm1m
r.colors map=dtm1m color=elevation
g.region -ap rast=dtm1m res=10
mkdir data
r.out.gdal -f in=dtm1m out=data/dtm10m.tif type=UInt16
exit
rm -r wms_dtm/
Upravte konfigurační soubor:
Jelikož se jedná o 16bit data, je nutné přeškálování do rozsahu 0-255:
Následně na to připojte do kontejneru lokální adresář s daty:
Dále si ukážeme přidání databázových datových zdrojů. Začneme formátem OGC GeoPackage, který je založen na souborové databázi SQLite:
LAYER
NAME "okresy"
STATUS ON
TYPE POLYGON
CONNECTIONTYPE OGR
CONNECTION "/mapdata/07/ruian_vusc.gpkg"
DATA "okresy"
CLASS
NAME "Okresy"
STYLE
OUTLINECOLOR 0 0 0
COLOR 150 150 150
END
END
METADATA
"wms_title" "Okresy"
END
END
Úkol
Zkuste přidat další vrstvu - městské části v Praze:
LAYER
NAME "praha_mc"
STATUS ON
TYPE POLYGON
DATA "/mapdata/05/MAP_MESTSKECASTI_P.shp"
CLASS
NAME "Praha - městské části"
STYLE
OUTLINECOLOR 0 0 0
COLOR 100 100 100
END
END
METADATA
"wms_title" "Praha - městské části"
END
END
Vyzkoušejte dotaz GetMap.
Pokud dotaz skončí chybou, tak se nejprve podívejme se na logovací zprávy:
Případně se do běžícího kontejneru přepneme a zkusíme otevřít datový zdroj pomocí GDAL příkazu ogrinfo
:
V našem případě pomůže zpracovat soubor ve formátu Esri Shapefile pomocí knihovny GDAL:
ogr2ogr -f "Esri Shapefile" -lco ENCODING=UTF-8 \
data/MAP_MESTSKECASTI_P.shp \
/mnt/repository/155FGIS/05/MAP_MESTSKECASTI_P.shp
a aktualizovat konfigurační soubor:
Nicméně důvod, proč MapServer nedokáže načíst data ve formátu Esri Shapefile dostupná z portálu otevřených dat IPR zůstává záhadou....
Úkol
Zkuste přidat podporu pro další souřadnicové systémy a otestujte (GetCapabilities
):
Výsledek ověřte v QGIS Data Source Manager:
Styly¶
Přidáme novou vrstvu vodních ploch, které kategorizujeme na základě atributu "DATA50_K". Styl definujeme v sekci CLASS.
Tip
Unikátní hodnoty lze zjistit i pomocí konzolového nástroje knihovny GDAL ogrinfo
:
ogrinfo -sql "select distinct DATA50_K from VodniPlocha" /mnt/repository/155FGIS/05/data50/VodniPlocha.shp
Popis kategorie je uložen v atributu "DATA50_P".
LAYER
NAME "vodni_plochy"
STATUS ON
TYPE POLYGON
DATA "/mapdata/05/data50/VodniPlocha.shp"
LABELITEM "JMENO"
ENCODING UTF-8
CLASS
NAME "Vodní plocha"
EXPRESSION ([DATA50_K] = 3330000)
STYLE
OUTLINECOLOR 0 0 255
COLOR 0 0 255
END
LABEL
COLOR 20 20 20
TYPE TRUETYPE
SIZE 10
POSITION LC
END
END
CLASS
NAME "Vodní tok nad 20 m šířky"
EXPRESSION ([DATA50_K] = 3020500)
STYLE
OUTLINECOLOR 80 150 220
COLOR 80 150 220
END
END
METADATA
"wms_title" "Vodní plochy"
END
END
Příklad výstupu:
WFS¶
WFS službu zprovozníme na základě dokumentace.
Sekci WEB > METADATA
rozšíříme o
"wfs_title" "WFS FGIS Server"
"wfs_onlineresource" "http://localhost:8090/?map=/etc/mapserver/fgis.map"
"wfs_srs" "EPSG:5514 EPSG:4326"
"wfs_enable_request" "*"
Dále pro každou vrstvu (LAYER > METADATA
) definujeme (příklad pro vrstvu vodních toků):
Důležité
Pokud chcete publikovat u dané vrstvy i atributy prvků je nutné doplnit do sekce LAYER > METADATA
:
Běžící WFS server otestujeme. Nejprve vyzkoušíme dotaz typu
GetCapabilities
:
http://localhost:8090/?map=/etc/mapserver/fgis.map&service=WFS&request=GetCapabilities
Dále otestujeme dotaz GetFeatrure
, který vrací vektorová data ve formátu OGC GML:
Python klient (OWSLib)¶
V následujících ukázkách se budeme dotazovat na námi provozované instance mapových serverů z pozice klienta.
Úkol
Ukázky níže pracují s instancí MapServer na portu 8090. Otestujte podobně i běžící instanci GeoServeru na portu 8080.
WMS¶
Připojíme se k WMS službě, stáhneme vybranou mapovou kompozici a uložíme na disk do souboru ve formátu PNG:
Příklad stažené kompozice vrstev:
WFS¶
Připojíme se k WFS službě, stáhneme vybrané vrstvy a uložíme na disk do souboru ve formátu OGC GML:
Poznámka
Pokud obsahuje GML chybovou hlášku "Web application error. Traditional BROWSE mode requires a TEMPLATE in the WEB section, but none was provided." je to pravděpodobně způsobeno chybou v knihovně OWSLib. Řešením by bylo změnit URL adresu mapového serveru tak, aby neobsahoval slovo "map".
ZABAGED¶
V této ukázce se zaměříme na mapový server poskytující reálná data, konkrétně ZABAGED® - Polohopis.
Pro území definované minimálním ohraničujícím obdélníkem (řádek 8
)
stáhneme všechny dostupné vrstvy ZABAGEDu. Pokud stažená vrstva
neobsahuje žádné prvky (to zjistíme pomocí Python API knihovny GDAL),
tak ji smažeme.
Výsledek může vypadá následovně: