Mapnik

A Turistautak.hu wikiből
Rasztertérképek készítése a Turistautak.hu adatbázisából Mapnik eszközkészlettel

Ezen dokumentáció még fejlesztés alatt áll. Célja, hogy a megszerzett tapasztalatokat megosszam a Turistautak.hu közösségével és reprodukálhatóvá tegyem az előállítás folyamatát. (--bpeti68)

A térkép itt megtekinthető.

Tartalomjegyzék

Használt operációs rendszer

Ubuntu8.10

A lenti csomagok nagyrésze MS Windows alá is megtalálható, de van köztük 1-2 aminek csak a forrása érhető el, így a fordítással magunknak kell bajlódni.

Szükséges csomagok

  • mapnik-utils (Licensz: LGPL)
  • python-mapnik
  • mapnik-plugins
  • libmapnik0.5 (Licensz: LGPL)
  • gdal-bin (Licensz: Free and open source software)
  • python2.5 (Licensz: Python licence)
  • postgreSQL (Licensz: BSD)
  • postgresql-8.3-postgis
  • python-pygresql
  • osm2pgsql (Licensz: GNU GPL)

Domborzatárnyékoláshoz

  • libgdal1-dev
  • geotiff-bin (Forrás: GeoTiff)
  • libgeotiff1.2 (Ha a listgeo reklamálja libgeotiff.so hiányát, akkor hozzunk létre egy ilyen nevű szimbolikus linket a libgeotiff.so.1.2.4 -re, jobbára a /usr/lib könyvtárban)

Egyéb: http://svn.openstreetmap.org/applications/rendering/mapnik/generate_tiles.py

Továbbá szükséges még szmi kolléga tuhu2osm.c programjának módosított változata. (Licensz: GNU GPLv2)
Ennek fordítása: gcc tuhu2osm_2.c -o tuhu2osm

Postgres és PostGIS beállítása

Az alábbiak csak Ubuntus környezetre vonatkoznak:

Egyéb rendszerekre itt az eredeti leírás: http://wiki.openstreetmap.org/wiki/Mapnik/PostGIS

Hogy a továbbiakban egyszerűbb legyen a dolgunk, hozzunk létre egy adatbázis felhasználót olyan névvel és jelszóval, mint a sajátunk.

  • Legyünk előbb postgres: $ sudo -u postgres -i
  • Lépjunk be a postgresbe: $ psql
  • Hozzuk létre a felhasználót:
postgres=#  CREATE USER <loginnevem> [egyéb opciók] CREATEDB LOGIN PASSWORD '<jelszavam>';
  • majd lépjünk ki: \q
  • Hozzuk létre a "gis" adatbázist:
$ createdb -E UTF8 -O loginnevem gis
$ createlang plpgsql gis
  • Aktiváljuk a PostGIS-t az adatbázison:
$ psql -d gis -f /usr/share/postgresql-8.3-postgis/lwpostgis.sql
  • Majd tegyük az újonnan létrejött táblákat is a magunkévá (ne feledjük, ekkor még mint postgres vagyunk belépve "postgres@peter-desktop:~$"):
$ echo "ALTER TABLE geometry_columns OWNER TO loginnevem; ALTER TABLE spatial_ref_sys OWNER TO loginnevem;"  | psql -d gis

  • $ exit, és már kész is.

Mapnik környezet és térképleíró beállítása

TODO

  • POI-k konvertálása hiányzik a tuhu2osm scripből.
    • Megoldva, bár egyelőre kétségeim vannak, hogy egy "dagonya" típusú POI-t milyen bitképpel szimbolizáljak.
  • OSM.XML "térkép leíró" rejtelmeinek feltárása.
  • turistajelzések megjelenítése a térképen. Megoldva.
    • Jelek megjelenítése, ha több is halad egy úton párhuzamosan.

Turistajelzések megjelenítése

Turistajelek megjelenése

Első lépésként a polyline-ok label-jében található jelzéseknek kellett helyet találnom a postGIS adatbázisban. Ezt az eredeti tuhu2osm a Ref mezőbe tette, de így esetleg felülíródott az út referencia száma (ami előzőleg az Utnév paraméterből került oda) ha volt neki. Így én a tourism mezőt választottam. A módosított tuhu2osm már ezt tartalmazza. A Mapnik szimbólumokat tartalmazó könyvtárába (/symbols) el kell helyeznünk a turistajelzések képeit PNG formátumban, majd a térképleíró XML fájlba a megfelelő stílusleíró szakaszban hivatkozni rájuk egy szabállyal. Ez praktikusan a "roads-text" szabály. Tovább bonyolítja a helyzetet, hogy egy úton több jelzés is haladhat, így nem tudjuk milyen sorrendben és hol helyezkedik el a mezőben a keresett karakter, ezért regular-expression alkalmazásával keresem. Erre szolgál a <Filter> elem. Ha az adott út tourism mezője tartalmaz K+ karaktersort, akkor a <PointSymbolizer> elemmel kirajzoltatjuk a megfelelő képecskét. Előzőleg a <MaxScaleDenominator> elemmel megadhatjuk, hogy milyen nagyítási szinten rajzolódjanak ki a jelzések. Az általam használt térképleíró letölthető innen. Használatához először módosítani kell a set-mapnik-env script-ben a MAPNIK_MAP_FILE környezeti változó értékét osm.xml-ről tuhu.xml-re, majd a customize-mapnik-map paranccsal a template-ből legyártatjuk a saját rendszerünknek megfelelő tuhu.xml-t.

Példa a K+ jel keresésére és megjelenítésére:

<Style name="roads-text">
 ...
  <Rule>
    <MaxScaleDenominator>100000</MaxScaleDenominator>
    <Filter> [tourism].match('[K][\+]|[K][\+][ ]|[ ][K][\+][ ]|[ ][K][\+]') </Filter>
    <PointSymbolizer file="%SYMBOLS_DIR%/kk.png" type="png" width="14" height="12" allow_overlap="false"/>
  </Rule>
</Style>

Képek előállítása

A Mapnik háromféle adatforrásból képes kimenetet előállítani:

  1. PostGIS (SQL) adatbázis
  2. Shapefileok
  3. Raszterek (Tif)

A harmadik (raszter) adatforrással lényegében csak egyetlen dolgot tud tenni, egy az egyben leképezi a kimenetre. Az első és a második variáció alkalmas igazán térkép előállítására. Az elsőnél további előny a tetszőleges SQL lekérdezés eredményeként fellépő sebességnövekedés.

A térkép előállításának mechanizmusa nagy vonalakban

      TUHU.XML
térképstílus leíró
POI-k bitképei (PNG)
tuhu.mptuhu2osmtuhu.osm (XML)PostgresSQLMapnikPNG/PDF/SVG
    SRTMGeoTif  
  1. Töltsd le a régiók mp állományait zip-elve. Ehhez értelemszerűen rendelkezned kell a megfelelő jogosultságokkal.
  2. Csomagold ki és fűzd össze őket egyetlen mp-vé.
  3. Konvertáld át UTF-8 formátumba. (Ezt megteszi a tuhu2osm)
  4. Engedd rá a tuhu2osm programra: (tuhu2osm tuhu.mp data.osm)
  5. Importáld be a Postgres adatbázisba (osm2pgsql -m data.osm)
  6. Szerkeszd a set-mapnik-env file-t. Állítsd be az összes MAPNIK_* környezeti változót, hogy illeszkedjen a könyvtárrendszeredhez illetve adatbázis kapcsolatodhoz, majd futtasd a ./customize-mapnik-map >$MAPNIK_MAP_FILE parancsot. Ez létrehozza a rendszerednek megfelelő beállítású OSM.XML térképleíró állományt.
  7. Indítsd el a képkockák generálását (a mapnik könyvtárában kiadott ./set-mapnik-env ./generate_tiles.py paranccsal), vagy ha egyetlen képre akarod a térképet kirajzoltatni akkor a generate_image.py -t.

A 2-5 lépésekhez használhatod ezt a shell scriptet. A 7. lépés előtte a generate_tiles.py scriptben beállítandók a kívánt zoom szintek és a generálandó terület koordinátái, mivel a frissen telepített mapnik alapértelmezésben a teljes földgolyót le akarja gyártani.

A renderelő mechanizmus teljesítménye

Jelenleg egy középkategóriás gépen futtatom. Alaplap: ASUS P4P800-VM/S alaplap Processzor: Hyperthread-es 2800MHz-es Northwood mag, 800FSB Memória: 512MB

Ezzel a konfigurációval, magassági szintvonalak nélkül a teljes országot 7-15 -ös zoomszinten kb.13 óra alatt készíti el. Szintvonalakkal ez felment duplájára. Nyilván, ha egyszer be van állítva és egyszer már legenerálta a teljes országot, a változott kisebb régiókkal sokkal hamarabb végez. Jelenleg készítem azt a scriptet, amit paraméterezve indítva csak az adott régiót befoglaló négyzet kockáit generálja le.

Felhasznált dokumentációk

 Mapnik telepítése, használata

Kontúr vonalak, domborzat színezés és árnyékolás

Domborzatárnyékoláshoz le kell töltenünk az SRTM adatokat a következő helyről: ftp://e0srp01u.ecs.nasa.gov/srtm/version2/SRTM3/Eurasia/ Az adatok zipelve, 1x1 fokos szegmensekre osztva tartalmazzák a golyóbis magasságadatait. Minket tehát a következő állományok érdekelnek: ftp://e0srp01u.ecs.nasa.gov/srtm/version2/SRTM3/Eurasia/N45E016.hgt.zip ... ftp://e0srp01u.ecs.nasa.gov/srtm/version2/SRTM3/Eurasia/N48E023.hgt.zip

Szükségünk lesz még az srtm_generate_hdr.sh scriptre. Ha lent vannak az adatok, bontsuk ki őket a következő scripttel:

#!/bin/bash

PREP_TABLE="1"
for X in *.hgt.zip; do
    yes | ./srtm_generate_hdr.sh $X
    rm -f "${X%%.zip}"
	    
    # Import 10m contours
    rm -f "${X%%.hgt.zip}.shp" "${X%%.hgt.zip}.shx" "${X%%.hgt.zip}.dbf"
    gdal_contour -i 10 -snodata 32767 -a height "${X%%.hgt.zip}.tif" "${X%%.hgt.zip}.shp"
    [ "$PREP_TABLE" ] && shp2pgsql -p -I -g way "${X%%.hgt.zip}" contours | psql -q gis
    shp2pgsql -a -g way "${X%%.hgt.zip}" contours | psql -q gis
				    
    rm -f "${X%%.hgt.zip}.shp" "${X%%.hgt.zip}.shx" "${X%%.hgt.zip}.dbf"
    rm -f "${X%%.hgt.zip}.bil"
    rm -f "${X%%.hgt.zip}.hdr"
    rm -f "${X%%.hgt.zip}.prj"
#    rm -f "${X%%.hgt.zip}.tif"
    unset PREP_TABLE
done

A fenti script eredetileg betolta PostGIS adatbázisunkba a magasságvonalak rajzolásához szükséges adatokat, majd kitörölte a generált shape fájlokat. Az utolsó rm -f "${X%%.hgt.zip}.tif" parancs kiiktatásával azonban a tif-eket megőrizzük. Ezekre lesz szükségünk az árnyékolás és domborzatszínezés elkészítéséhez.

Következő lépésben összefűzzük a geotiffeket:

gdal_merge.py -v -o <srtm.tif> -ul_lr <west> <north> <east> <south> <tif-directory>/*.tif

Update: A teljes országot lefedő tif olyan nagy lett, hogy a Mapnik nem volt képes a memóriába tölteni. A megoldás az lett, hogy az országot 7 oszlopra bontottam az egész számú hosszúsági fokok mentén (E16-E17, E17-E18, ... E22-E23). Az így keletkezett 7 raszterrel már megbirkózott a program.

Majd egy kis korrekció amit innen puskáztam. Aki érti, hogy itt mi történik, az ne fogja vissza magát:

gdal_translate -of GTiff -co "TILED=YES" -a_srs "+proj=latlong" <srtm.tif> <srtm_adapted.tif>

Aztán a tiff Mercator projekcióra húzása:

gdalwarp -of GTiff -co "TILED=YES" -srcnodata 32767 -dstnodata 32767 -t_srs "+proj=merc +ellps=sphere +R=6378137 +a=6378137 +units=m" -rcs -order 3 -tr 30 30 -multi <srtm_adapted.tif> <srtm_warped.tif>

Ezután jöhet a színezés, árnyékolás. Az alábbi scriptet mentsük el mint mkrelief.sh:

#!/bin/sh

INFILE=$1
OUTFILE=${2:-hillrelief.tif}
PID=$$
hillshade $INFILE .s_$PID.tif -s 370400 -z 20
color-relief $INFILE scale.txt .c_$PID.tif
listgeo .s_$PID.tif > .info_$PID.dat
composite -blend 50 .c_$PID.tif .s_$PID.tif .geo_$PID.tif
geotifcp -g .info_$PID.dat .geo_$PID.tif $OUTFILE
rm -f .s_$PID.tif .c_$PID.tif .geo_$PID.gif .geo_$PID.tif .info_$PID.dat

A fentiekből hillshade, color-relief és scale.txt innen van. A listgeo és geotifcp a geotiff csomagból. (Forrást lásd fent.) A composite és convert az ImageMagic csomag részei. Használata:

$ mkrelief.sh <srtm_warped.tif> <srtm_shaded.tif>

Ez el fog szöszölni pár órát.

Az eredmény valami ilyesmi lesz (kicsinyített részlet):

dunakanyar hillshade.png

Ezt lehet majd betolni az úthálózat alá külön, kikapcsolható rétegként.

TODO

  • OpenLayers réteg elkészítése a kezelésükhöz

Forrás:

 GDAL-based DEM utilities
 [Mapnik-users Shaded Relief]
 OSM HikingBikingMaps

DEMTOOLS fordítása Ubuntu8.10 alatt:

g++ `gdal-config --cflags` hillshade.cpp -o hillshade `gdal-config --libs`
g++ `gdal-config --cflags` color-relief.cpp -o color-relief.cpp `gdal-config --libs`
g++ `gdal-config --cflags` aspect.cpp -o aspect `gdal-config --libs`
g++ `gdal-config --cflags` slope.cpp -o slope `gdal-config --libs`