DE:HowTo Mapnik & Tirex
Wenn du aktuelle Informationen beitragen kannst, hilf bitte bei der Aktualisierung oder teile diese auf der Diskussionsseite mit. (Discussion)
Dieses HowTo beschreibt in Anknüpfung an das „HowTo minutely hstore“, in welchem eine osm2pgsql Datenbank des Planeten incl. einer hstore-Spalte erstellt wurde, wie diese nun unter Verwendung von Mapnik und Tirex verwendet werden kann, um einen eigene Kachel-Server zu erstellen. Im Laufe des HowTos wird ein Kachel-Render-Server mit zwei Render-Stilen eingerichtet: dem OSM Standard-Stil und ein eigener, auf der hstore-Spalte basierender.
Software
Wir benötigen eine Reihe von Softwarekomponenten: Mapnik, Tirex, Apache, Mod_Tile sowie einige Tools und den Osm-Mapnik-Style samt der zugehörigen Symbole. Die einzelnen Komponenten werden zusammen mit ihren Abhängigkeiten einzeln installiert, da einige Leser evtl. gar keinen Tile-Server benötigen sondern mit einer reinen Mapnik-Installation schon glücklich sind.
Mapnik
Da bei der in diesem HowTo verwendeten Distribution „Debian Lenny“ Installation nur Mapnik 0.5.1 als Paket verfügbar ist, müssen wir Mapnik selbst kompilieren. Tirex liegt ebenso wie Mod_Tile generell nur in Quellcode-Form vor, daher benötigen wir außerdem eine Menge Development-Pakete, um die Abhängigkeiten dieser selbst übersetzten Tools abzudecken. Falls das vorangegangene „HowtoMinutelyHstore“ absolviert wurde, können wir alles was für das Übersetzen von Mapnik nötig ist, mit folgenden Kommandos installieren:
osm@osm:~$
sudo aptitude update
sudo aptitude install pgpgpg devscripts dpatch build-essential debhelper libboost-thread-dev \
libboost-filesystem-dev libboost-regex-dev libboost-program-options-dev libboost-python-dev \
libpng12-dev libjpeg62-dev libtiff4-dev zlib1g-dev libfreetype6-dev libpq-dev proj \
libltdl3-dev libfribidi-dev python-dev libgdal1-dev libxml2-dev libagg-dev libboost-iostreams-dev \
quilt libcairomm-1.0-dev libcairo2-dev python-cairo-dev ttf-dejavu ttf-unifont
Wie oben beschrieben werden wir uns den Quellcode von Mapnik direkt vom Download-Server des Projektes holen und selbst übersetzen. Alle Abhängigkeiten haben wir durch den vorangegangenen Installations-Marathon bereits an Ort- und Stelle, sodass das Übersetzen nun Reibungslos funktionieren sollte (tatsächlich warnt Mapnik beim Konfigurieren wegen einer fehlenden boost-system Bibliothek, aber diese ist in unserer Konfiguration auch gar nicht nötig). Da wir Mapnik als Debian-Paket installieren möchten, benötigen wir noch die zugehörige Paketkonfiguration. Diese ist nicht Teil des Quelltext-Downloads und wird daher von einem externen SVN Repository nachinstalliert. Die Pakete werden im Home-Directory erstellt und von dort aus installiert.
osm@osm:~$
wget http://download.berlios.de/mapnik/mapnik-0.7.1.tar.gz
tar xvzf mapnik-0.7.1.tar.gz
mv mapnik-0.7.1.tar.gz mapnik_0.7.1.orig.tar.gz
cd mapnik-0.7.1
osm@osm:~/mapnik-0.7.1$
svn co https://svn.toolserver.org/svnroot/mazder/mapnik0.7.1-debian debian
debuild -i -b -us -uc
cd ..
osm@osm:~$
sudo dpkg -i libmapnik-dev_0.7.1_all.deb libmapnik0.7_0.7.1_*.deb mapnik-plugins_0.7.1_*.deb mapnik-utils_0.7.1_*.deb python-mapnik_0.7.1_*.deb
sudo mkdir -p /usr/lib/mapnik/fonts
sudo ln -s /usr/share/fonts/truetype/unifont/*.ttf /usr/share/fonts/truetype/ttf-dejavu/*.ttf /usr/lib/mapnik/fonts/
Die Argumente für das debuild-Kommando weisen es an, weder die Plattform-spezifischen Änderungen an den Quelltexten des Paketes -uc) noch den Quelltext selbst (-us) kryptographisch zu signieren. Die -b-Option weist debuild an, nur die Binärpakete zu erstellen (den Quelltext haben wir ja schon) und das -i-Flag bringt debuild dazu, nicht nach plattform-spezifischen Diffs zu suchen.
Für die Installation unter Debian Squeeze und auch Ubuntu 10.04 (Lucid Lynx) muss im Verzeichnis ~mapnik-0.7.1\debian\ eine Anpassung an der Datei python-mapnik.install vorgenommen werden.
osm@osm:~/mapnik-0.7.1$
cd debian
nano python-mapnik.install
Dort muss an zwei Stellen "site-packages" durch "dist-packages" ersetzt werden.
Nachdem die Pakete erstellt wurden, was eine gewisse Zeit in Anspruch nehmen wird, werden die neu erstellten Pakete mit dpkg installiert. Anschließend werden die dejavu- und unifont-Schriftarten aus dem System-Schriftarten-Ordner als Symlink in das Mapnik-Verzeichnis eingebracht, damit Mapnik auch die dort abliegenden Schriftarten findet.
OSM Kartenstil
Als nächstes besorgen wir uns den Standard OSM Kartenstil – das ist der, welcher für die Karte auf http://www.openstreetmap.org/ verwendet wird. Dazu gehören unter anderem auch die verwendeten Symbole. Zum herunterladen der Stil-Dateien führen wir folgende Kommandos aus:
osm@osm:~$
svn co http://svn.openstreetmap.org/applications/rendering/mapnik/@r27279 osm-mapnik
sudo mv osm-mapnik /usr/share/
cd /usr/share/osm-mapnik
anschließend müssen wir einige Konfigurationen in den XML-Dateien vornehmen. Zunächst kopieren wir die .template-Dateien um diese anschließend auf unsere Umgebung anzupassen:
osm@osm:/usr/share/osm-mapnik$
cp inc/datasource-settings.xml.inc.template inc/datasource-settings.xml.inc
cp inc/fontset-settings.xml.inc.template inc/fontset-settings.xml.inc
cp inc/settings.xml.inc.template inc/settings.xml.inc
Anschließend müssen wir die XML-Dateien anpassen. Wenn die Datenbank der aus dem ersten „HowTo minutely hstore“ stammt, sollten die Dateien wie folgt aussehen:
inc/datasource-settings.xml.inc
<Parameter name="type">postgis</Parameter>
<Parameter name="password"></Parameter>
<Parameter name="host">/var/run/postgresql/</Parameter>
<Parameter name="port"></Parameter>
<Parameter name="user">gis</Parameter>
<Parameter name="dbname">gis</Parameter>
<!-- this should be 'false' if you are manually providing the 'extent' -->
<Parameter name="estimate_extent">false</Parameter>
<!-- manually provided extent in epsg 900913 for whole globe -->
<!-- providing this speeds up Mapnik database queries -->
<Parameter name="extent">-20037508,-19929239,20037508,19929239</Parameter>
inc/fontset-settings.xml.inc
<FontSet name="book-fonts">
<Font face_name="DejaVu Sans Book" />
<Font face_name="unifont Medium" />
</FontSet>
<FontSet name="bold-fonts">
<Font face_name="DejaVu Sans Bold" />
<Font face_name="unifont Medium" />
</FontSet>
<FontSet name="oblique-fonts">
<Font face_name="DejaVu Sans Oblique" />
<Font face_name="unifont Medium" />
</FontSet>
inc/settings.xml.inc
<!--
Settings for symbols, the spatial reference of your postgis tables, coastline shapefiles directory, and their prefix names.
-->
<!-- use 'symbols' unless you have moved the symbols directory -->
<!ENTITY symbols "/usr/share/osm-mapnik/symbols">
<!-- use the '&srs900913;' entity if you have called osm2pgsql without special flags (or with -m); use '&srs4326;' if you have used -l -->
<!ENTITY osm2pgsql_projection "&srs900913;">
<!-- used for 'node in way' ST_DWithin spatial operations -->
<!-- Use 0.1 (meters) when your database is in 900913 -->
<!-- Use 0.000001 (degrees) when your database is in 4326 -->
<!ENTITY dwithin_900913 "0.1">
<!ENTITY dwithin_4326 "0.00001">
<!ENTITY dwithin_node_way "&dwithin_900913;">
<!-- use 'world_boundaries', which is the usual naming for the local folder the coastline shapefiles are unzipped into -->
<!ENTITY world_boundaries "/usr/share/osm-mapnik/world_boundaries">
<!-- use 'planet_osm' unless you have customized your database table prefix using the osm2pgsql 'prefix' flag -->
<!ENTITY prefix "planet">
World Boundaries
Wer aufgepasst hat, hat’s gemerkt: wir haben einen noch nicht vorhandenen Pfad in die Konfiguration eingetragen: „/usr/share/osm-mapnik/world_boundaries“. Aus diesem Ordner lädt Mapnik im Auftrag des Standard-OSM-Stils die Land/Wasser Grenzen und die Formen größerer Bebauungsgebiete. Beides wird in unregelmäßigen Abständen aus der OpenStreetMap-Datenbank erzeugt. Dieser Umweg ist notwendig, da die entsprechenden Relationen öfters mal kaputt gehen (d.h. nicht mehr durchgehend und linear sind sondern Löcher oder Schleifen haben). Solche kaputten Geometrien kann Mapnik nicht rendern. Damit nun nicht alle paar Wochen die Küstenlinien ganzer Kontinente verschwinden, werden diese Grenzen mit dem „Coastline error checker“ halb-automatisch repariert und daraus Shapefiles erstellt. Shapefiles sind Mini-Datenbanken mit geometrischen Objekten – und genau diese legen wir nun in diesen Ordner ab:
osm@osm:/usr/share/osm-mapnik$ ./get-coastlines.sh
Mapnik testen
Nun sind wir so weit und können unsere Mapnik-Installation und damit auch unsere Datenbank testen. Mapnik selbst ist eigentlich kein Programm sondern eine in C++ geschriebene Bibliothek. Sie lässt sich sehr einfach von Script-Sprachen wie Perl oder Python ansprechen. Um das Setup testen zu können, bedarf es also eines kleinen Programms, das die wichtigsten Optionen der Mapnik-Bibliothek über die Kommandozeile verfügbar macht. Ein solches Tool werden wir nun installieren. Anschließend führen wir es einmal ohne Parameter aus und anschließend mit dem bbox-Argument. Dabei sollten – wenn alles geklappt hat – zwei PNGs herauskommen: „world.png“ sollte die ganze Welt zeigen und „berlin.png“ die Innenstatt von Berlin.
osm@osm:~$
wget https://svn.toolserver.org/svnroot/mazder/render-tool/render
chmod +x render
sudo mv render /usr/local/bin/
render --file world
render --file berlin --bbox 12.88,52.67,13.8,52.35
Durch ausführen von „render --help“ können alle Optionen des Render-Scripts eingesehen werden. Das Script ist auch sehr nützlich, um eigene Stile in verschiedenen Situationen zu testen.
Eigener Stil
Ein Server der „nur” den OSM Standard-Stil rendern kann ist ja langweilig. Daher wollen wir noch einen zweiten Test-Style herunterladen, der die Funktionen der hstore-Spalte nutzt.
osm@osm:~$
svn co https://svn.toolserver.org/svnroot/mazder/styles/surveillance
sudo mkdir -p /usr/share/osm-styles
sudo mv surveillance/ /usr/share/osm-styles/
render --file berlin-cams --bbox 12.88,52.67,13.8,52.35 --style /usr/share/osm-styles/surveillance/common.xml
Dieser Aufruf produziert eine Datei namens „berlin-cams.png“ welche auf einem transparenten Hintergrund alle Überwachungskameras in Berlin zeigt. Ohne eine entsprechende Basiskarte ist dies natürlich wenig Nützlich aber man könnte nun beispielsweise das ImageMagic-Toolkit verwenden, um diese Grafik über das zuvor gerenderte Basiskarten-Bild zu legen.
Tirex
Nun können wir also aus unserer OSM-Datenbank und den Shapefiles Karten erstellen, doch das gezielte Rendern einzelner Kartenausschnitte ist teuer, das kann man sich anhand der Laufzeiten der render-Aufrufe ja selbst ausrechnen. Um jetzt aber viele tausend Benutzer mit Karten Bedienen zu können, brauchen wir einen Kachel-Server. Wer mit dem Konzept der Kacheln nicht vertraut ist, sollte Slippy map und Tiles lesen. Der Tile-Server besteht aus mehreren Komponenten. Wir beginnen mit der Einrichtung von Tirex, welches die Render-Warteschlange sowie den eigentlichen Render-Server bereitstellt und Mapnik als Render-Backend verwenden kann.
Wir installieren zunächst die nötigen Abhängigkeiten und Übersetzen anschließend Tirex ebenso wie zuvor Mapnik in Debian-Pakete. Von den dabei entstehenden Paketen installieren wir anschließend den tirex-core, das mapnik-backend und die mapnik-Beispiel-Karte.
osm@osm:~$
sudo aptitude install libipc-sharelite-perl libjson-perl libgd-gd2-perl libwww-perl libboost-program-options-dev libboost-program-options1.34.1
svn co http://svn.openstreetmap.org/applications/utils/tirex/
cd tirex
osm@osm:~/tirex$
debuild -i -b -us -uc
cd ..
osm@osm:~$
sudo dpkg -i tirex-backend-mapnik_0.2.0_*.deb tirex-core_0.2.0_*.deb tirex-example-map_0.2.0_*.deb
Nun müssen wir dem tirex unsere unsere Karten-Stile bekannt machen. Dies geschieht über .conf Dateien im Verzeichnis /etc/tirex/renderer/mapnik. Hier wurde durch das Paket „tirex-example-map“ bereits eine ausführlich dokumentierte Konfigurationsdatei angelegt. Wir legen dort drei .conf-Dateien an:
osm.conf
name=osm
tiledir=/var/lib/tirex/tiles/osm
maxz=18
mapfile=/usr/share/osm-mapnik/osm.xml
surveillance.conf
name=surveillance
tiledir=/var/lib/tirex/tiles/surveillance
maxz=18
mapfile=/usr/share/osm-styles/surveillance/common.xml
anschließend wird die tirex-daemons neu gestartet und der Erfolg unserer Konfiguration mit tirex-status überprüft. In der „Maps“-Sektion sollten vier Kartenstile aufgelistet sein: example, osm, surveillance und test.
sudo /etc/init.d/tirex-master restart
sudo /etc/init.d/tirex-backend-manager restart
tirex-status --once --extended
Vorberechnen
Nun da Tirex unsere Styles kennt, können wir beginnen, erste Kacheln zu berechnen. Es empfiehlt sich, die kleinsten Zoomstufen der Karte (z.B. 0-6) bereits im Vorhinein berechnen zu lassen. Dazu kann der Befehl tirex-batch verwendet werden:
tirex-batch --prio=25 map=osm,surveillance bbox=-180,-90,180,90 z=0-6
Dies bringt Tirex dazu, 176 Kacheln zu berechnen. Um Ihm dabei zuzusehen, kann wieder das tirex-status Kommando verwendet werden:
tirex-status --extended
Apache & mod_tile
Tirex stellt einen Server bereit, der im Hintergrund OSM-Daten in Pixelgrafiken im Kachelformat umrechnen kann. Er stellt außerdem ein ausgefeiltes Warteschlangen-System bereit, mit welchem er zwischen dringenden und weniger dringenden Aufgaben unterscheiden kann. Damit daraus aber ein Karten-Server wird, brauchen wir zunächst eine Schnittstelle zum Internet – einen Webserver. Wir verwenden den apache, da es für ihn ein spezielles Modul zum Karten-Kacheln ausliefern gibt, das hervorragen mit tirex zusammenarbeitet: mod_tile.
Die Installation läuft so ab:
sudo apt install apache2 apache2-dev
osm@osm:~$
git clone https://github.com/openstreetmap/mod_tile/
cd mod_tile/
osm@osm:~/mod_tile$
echo '/etc/renderd.conf' > debian/renderd.conffiles
debuild -i -b -us -uc
cd ..
osm@osm:~$
sudo dpkg -i libapache2-mod-tile_0.3_*.deb
sudo ln -s ../mods-available/tile.load /etc/apache2/mods-enabled/
In der Datei „renderd.conffiles“ gibt es zwei Zeilen, die in dieser Distribution zu Problemen führen. Dieses Problem wird durch die „echo“-Zeile behoben. Anschließend sollte der Bau-Vorgang reibungslos ablaufen.
Wir installieren auch nur mod_tile, da die Funktionen des renderd von tirex mit übernommen werden. Der Symlink in das Apache-Konfigurationsverzeichnis aktiviert das Modul als Teil des Webservers. Als nächstes müssen wir mod_tile mitteilen, wie sie unseren neuen tirex erreichen kann und welche Karten-Styles dieser bereitstellt. Dazu erstellen wir eine neue Datei im Apache Konfigurations-Ordner:
/etc/apache2/mods-available/tile.conf
ModTileRenderdSocketName /var/lib/tirex/modtile.sock
ModTileTileDir /var/lib/mod_tile
ModTileRequestTimeout 5
AddTileConfig /tiles/test/ test
AddTileConfig /tiles/example/ example
AddTileConfig /tiles/osm/ osm
AddTileConfig /tiles/surveillance/ surveillance
Aufgrund eines Fehlers in mod_tile sind derzeit keine angepassten Ablageorte für die von tirex generierten Dateien möglich, wesshalb derzeit eine Symbolische Verknüpfung diese beiden Verzeichnisse verbinden muss:
sudo rm -rf /var/lib/mod_tile
sudo ln -s /var/lib/tirex/tiles /var/lib/mod_tile
Diese Konfiguration wird nun, analog zum tile-Modul selbst, aktiviert und der Apache anschließend neu gestartet.
sudo ln -s ../mods-available/tile.conf /etc/apache2/mods-enabled/
sudo /etc/init.d/apache2 reload
Ab sofort liefert unser Apache Kacheln aus (zum ausprobieren statt osm.local den eigenen Hostname oder die IP einsetzen):
- http://osm.local/tiles/osm/0/0/0.png
- http://osm.local/tiles/osm/6/34/20.png
- http://osm.local/tiles/osm/8/137/83.png
- http://osm.local/tiles/surveillance/11/1100/671.png
- http://osm.local/tiles/osm/16/35201/21492.png
OpenLayers
Jetzt sollen die Benutzer der Seite natürlich nicht einzeln durch die Kacheln blättern, sondern mit einer schönen Slippy-Map darüber browsen können. Dazu brauchen wir eine Webseite welche die OpenLayers Bibliothek verwendet, um dem Benutzer diesen Bedienkomfort zu bieten. Wie die Fernsehköche habe ich da schon mal was vorbereitet…
osm@osm:~$
wget -O /var/www/index.html http://svn.toolserver.org/svnroot/mazder/startup/openlayers/index.html
Einfach aufrufen und die erste, eigene Karte bewundern.
Expire
Eine weitere Aufgabe, die es zu Erledigen gilt, ist das „als alt markieren“ von geänderten Kacheln (invalidieren). Diese Funktion ist in dem Script rund um „load-next“ bereits vorgesehen. Durch das Markieren als veraltet werden die Kacheln beim nächsten Aufruf durch Tirex in die Warteschlange zum Neu-Berechnen eingereiht. Wir verwenden eine modifizierte Version des expire.rb-Scripts, welches aus der .osc-Datei die geänderten Knoten und Wege liest, die zu den Wegen gehörenden Knoten aus der PostGIS Datenbank nachlädt und aus den sich daraus ergebenden Koordinaten die zu invalidierenden (Meta-)Kacheln ermittelt. Eine Meta-Kachel ist ein Satz von 8x8 PNG-Kacheln, welche aus Effizienzgründen in einer einzelnen Datei abgelegt werden.
Aus dieser Methode ergeben sich zwei Probleme:
- Wege mit viel Abstand zwischen den Knoten, bei denen zwischen zwei Knoten eine ganze Meta-Kachel passt, invalidieren diese dazwischen liegende Kachel nicht.
- Relationen werden aus Effizienzgründen ignoriert.
Alle nötigen Dateien haben wir bereits im Schritt Diff_Imports des HowTo minutely hstore geladen. Wenn Sie nach einer Version des „HowTo minutely hstore“ vorgegangen sind, welche die expire Skripte nicht mit installiert, müssen Sie diesen Schritt nach der aktuellen Version wiederholen. Es genügt dann, im Kopf der Datei „load-next“ „EXPIRE=0“ auf „EXPIRE=1“ zu ändern. In der Datei „tile_expiry/expire.rb“ können über die Parameter „MIN_ZOOM“ und „MAX_ZOOM“ eingestellt werden, welche Zoomlevel bearbeitet werden sollen. Diese Werte müssen an die Leistung der Maschine und den Bedarf des Betreibers angepasst werden, so dass hier ein wenig experimentieren nötig ist.
Munin
Mittels tirex-status kann der aktuelle Zustand des Rendering-Servers sehr komfortabel beobachtet werden, jedoch kann man damit keine Veränderungen über einen längeren Zeitraum beobachten – hierzu braucht es eine weitere Software-Komponente. Munin ist ein Messwert-Überwachungssystem, welches vor allem zur Aufzeichnung der Leistungsparameter von Servern verwendet. Eine der Leitmotive dieses Programms ist, einfach eigene Graphen über Plugins hinzufügen zu können. Tirex stellt seinerseits eine Reihe von Plugins für Munin bereit. Die Installation von Munin sowie den genannten Plugins ist ganz einfach:
osm@osm:~$
sudo aptitude install munin-node munin
sudo dpkg -i tirex-munin-plugin_0.2.0_*.deb
Von nun an wird Munin alle 5 Minuten eine Probe nehmen, aufzeichnen und in Graphen präsentieren. Um diese Aufzurufen, muss die URL so aussehen aus (zum ausprobieren statt osm.local den eigenen Hostname oder die IP einsetzen): http://osm.local/munin/
Wenn noch einzelne Karten-Stile überwacht werden sollen, müssen dafür noch einzelne Symlinks erstellt werden:
STYLES=osm surveillance
for MAP in $STYLES; do
sudo ln -s /usr/share/munin/plugins/tirex-status-render-time /etc/munin/plugins/tirex-status-render-time-$MAP
sudo ln -s /usr/share/munin/plugins/tirex-status-requests-rendered /etc/munin/plugins/tirex-status-requests-rendered-$MAP
sudo ln -s /usr/share/munin/plugins/tirex-tiledir-diskusage /etc/munin/plugins/tirex-tiledir-diskusage-$MAP
sudo ln -s /usr/share/munin/plugins/tirex-tiledir-tileage /etc/munin/plugins/tirex-tiledir-tileage-$MAP
sudo ln -s /usr/share/munin/plugins/tirex-tiledir-tilecount-absolute /etc/munin/plugins/tirex-tiledir-tilecount-absolute-$MAP
sudo ln -s /usr/share/munin/plugins/tirex-tiledir-tilecount-relative /etc/munin/plugins/tirex-tiledir-tilecount-relative-$MAP
done
Links
Erster Teil des HowTo: http://wiki.openstreetmap.org/wiki/DE:HowtoMinutelyHstore Mapnik:
Coastline Error Checker:
Tirex
Mod-Tile
OpenLayers
Expire
Munin