Große OpenStreetMap-Karten selbst rendern
Marvin Gülker · 18.04.2014
Erstellung von großen OSM-Karten.
Kategorien: OpenStreetMap, Software
OpenStreetMap ist ein wunderbares Projekt, zu dem beizutragen jedem nur zu empfehlen ist. Die Qualität der Karten lässt mittlerweile manch kommerziellen Anbieter alt aussehen, allerdings stellt sich das Rendern einer etwas größer als üblichen Karte als ein wenig schwierig heraus. In diesem Artikel beschreibe ich, wie man eine Karte im Format A1 erstellt.
Wer regelmäßig die OpenStreetMap-Website nutzt, der kennt diese Fehlermeldung:
The gateway did not receive a timely response from the upstream server or application.
Oder alternativ:
The load on the servers is too high currently. Please try again in a few minutes.
Für Karten, die in etwa die Größe eines A4-Blattes nicht überschreiten, ist diese Meldung noch verhältnismäßig selten. Sobald man aber größere Areale in eine druckbare Form bringen möchte (man denke etwa an Informationstafeln), ist die OpenStreetMap-Website nicht mehr zu gebrauchen. Die einzige Lösung dieses Problems besteht darin, die Rohdaten von OpenStreetMap selbst auf dem heimischen Rechner zu rendern, was ich nun näher erläutern möchte.
Voraussetzungen
Ich bin von den Anforderungen des Renderings selbst ein wenig überrascht gewesen. Es empfiehlt sich ein Computer mit mindestens 8 GiB Arbeitsspeicher, dazu ein möglichst schneller Prozessor. Jedenfalls konnte ich nicht beobachten, dass die Rendering-Software auf meine Graphikkarte zugegriffen hätte, was der benötigten Zeit sicherlich gut getan hätte, so aber sind ein paar Minuten 100%-ige CPU-Auslastung schonmal drin.
Die Rohdaten
Das OpenStreetMap-Projekt bietet die Rohdaten der gesamten Erde direkt selbst zum Download an, mit einer Größe von momentan etwa 24 GiB im PBF- und 34 GiB im OSM-Format ist von einem vollständigen Download allerdings eher abzuraten. Stattdessen gibt es Spiegelseiten, die auch Teile des Gesamtmaterials anbieten. Für diesen Artikel nutze ich die Nordrhein-Westfalen-Karte von Geofabrik. Zu beachten ist, dass es wie erwähnt zwei Formate gibt: Das traditionelle XML-basierte OSM-Format, das aufgrund seiner schieren Größe bei derartigen Datenmengen momentan auf dem Rückzug ist, sowie das neuere platzsparende Binärformat PBF. Es ist empfehlenswert, sich für PBF zu entscheiden. (Direktlink zum NRW-PBF).
PostgreSQL und PostGIS
Die Daten können nicht roh von der Rendering-Software (dazu sogleich) eingelesen werden. Stattdessen wird eine PostgreSQL-Datenbank mit der PostGIS-Erweiterung benötigt; dabei handelt es sich um ein speziell für Geodaten ausgelegtes Format sowie dazugehörige Abfragebefehle, mit denen an die Datenbank Fragen wie „Welche Straßen liegen in diesem so und so umgrenzten Gebiet?“ gestellt werden können. Perfekt etwa auch für die Erstellung von Straßenkarten, bei denen ein Index für die Zuordnung von Straßenname und Kartenquadrant vorgenommen werden soll – das soll hier aber nicht Thema sein.
Die meisten Distributionen haben PostgreSQL und PostGIS in ihren Repositorien, sodass ich auf die Installation nicht weiter einzugehen brauche. Allerdings wird empfohlen, die Ressourcenlimits für PostgreSQL anzuheben:
# postgresql.conf shared_buffers = 128MB checkpoint_segments = 20 maintenance_work_mem = 256MB
Dazu muss auch eine Kernel-Variable erhöht werden:
# sysctl kernel.shmmax=268435456
Selbstverständlich kann man diese Änderung auch in /etc/sysctl.d
bzw.
/etc/sysctl.conf
festschreiben, um sie nicht nach jedem Reboot
wiederholen zu müssen.
Nun benötigen wir noch einen Nutzer und eine Datenbank mit
PostGIS-Erweiterung. Der Standard-Openstreetmap-Stil erfordert
zwingend
den Datenbanknamen gis
. Zunächst als Superuser am Datenbankserver
anmelden:
# su - postgres $ psql psql (9.3.4) Geben Sie „help“ für Hilfe ein.
Einen Nutzer (hier quintus
) und eine Datenbank (zwingend gis
)
erstellen:
CREATE USER quintus WITH PASSWORD 'supergeheimespasswort'; CREATE DATABASE gis WITH OWNER quintus;
Das Passwort ist im Grunde egal, da PostgreSQL lokalen Verbindungen standardmäßig ohnehin vertraut. Dies ist auch erforderlich, da ansonsten die Datenbankverbindung im Openstreetmap-Carto-Stil (dazu gleich mehr) geändert werden müsste.
Nun müssen wir die PostGIS-Erweiterung aktivieren. Dazu die SQL-Shell
verlassen (\q
) und neu anmelden, diesmal auf der gis
-Datenbank:
$ psql -d gis
Erweiterung aktivieren:
CREATE EXTENSION postgis;
Von anderer Seite wird
zudem die Aktivierung der plpgsql
-Erweiterung gefordert, allerdings
musste ich bei mir folgendes feststellen:
CREATE EXTENSION plpgsql;
FEHLER: Erweiterung „plpgsql“ existiert bereits
Daraus schließe ich, dass dies bei neueren Versionen von PostgreSQL
nicht mehr erforderlich ist. Zuletzt noch die Zugriffsrechte anpassen
(weil wir mit dem postgres
-Nutzer gearbeitet haben):
ALTER TABLE geometry_columns OWNER TO quintus; ALTER TABLE spatial_ref_sys OWNER TO quintus;
Kontrollergebnis:
gis=# \d Liste der Relationen Schema | Name | Typ | Eigentümer --------+-------------------+---------+------------ public | geography_columns | Sicht | postgres public | geometry_columns | Sicht | quintus public | raster_columns | Sicht | postgres public | raster_overviews | Sicht | postgres public | spatial_ref_sys | Tabelle | quintus (5 Zeilen)
Die OpenStreetMap-Daten liegen im Format 900913
vor, das in meiner
PostGIS-Version jedoch ebenfalls bereits enthalten war. Ansonsten kann
das zur
Erstellung
notwendige SQL hier eingesehen werden.
osm2pgsql
Der Import der Daten aus dem PBF in die Postgres-Datenbank wird mithilfe des Programms osm2pgsql durchgeführt. Dieses steht unter ArchLinux im AUR zur Verfügung.
Mapnik
Herzstück des gesamten Prozesses ist die Rendering-Software Mapnik. Diese Library (es handelt sich nicht um ein Endnutzer-Programm) übernimmt die eigentliche Rendering-Arbeit und wird sehr aktiv entwickelt. Zum erfolgreichen Einsatz mit der anderen in diesem Artikel vorgestellten Software ist mindestens Version 2.2.0 erforderlich, insbesondere TileMill (siehe unten) verweigert ansonsten den Dienst. Mapnik ist in C++ geschrieben und wird primär über ein Python-API angesprochen, das jedoch auch in einer Weise verwendet werden kann, die den Python-Code im Wesentlichen auf das Laden einer XML-Datei reduziert. Es stehen auch Bindings für andere Programmiersprachen zur Verfügung, darunter JavaScript und Ruby.
Mapnik ist unter Arch Linux
als
reguläres Paket im community
-Repository verfügbar.
TileMill
Gewissermaßen das „Gesicht“, sprich die UI, mit der vordringlich
gearbeitet wird, stellt TileMill
da. Die in NodeJS geschriebene Software entwickelt sich so rasant, dass
man dort nicht einmal ernsthafte Gedanken an stabile Relases
verschwendet – das letzte
war vor zwei Jahren und
ist hoffnungslos veraltet. Stattdessen wird darauf verwiesen, man möge
sich stets den aktuellen master
herunterladen. Der ganz
offensichtliche Fokus auf Mac OS X erleichtert einem Linuxer den Umgang
mit der Software nur sehr bedingt.
Die im OpenStreetMap-Wiki genannten Alternativen werden (freilich mit Ausnahme von „custom python script for mapnik“) nicht mehr entwickelt, sodass es sich bei TileMill gewissermaßen nun um den „offiziellen“ Renderer handelt. Es gibt zurzeit noch das Kommandozeilen-Programm Nik2img, das aber seit 2011 nicht mehr entwickelt wird und dessen Verwendung von Mapnik durch „Deprecated“-Meldungen quittiert wird. Es stellt sich mithin die Frage, wie lange dieses Programm noch verwendbar sein wird; spätestens mit dem Release von Mapnik 3 wird TileMill der einzig verbliebene Renderer sein.
Die nicht etwa in der README dokumentierte Installation von TileMill ist für Leute, die sich mit NodeJS nicht auskennen, ein wenig ungewöhnlich, daher gehe ich hier darauf ein. Zunächst wird das Git-Repository geklont:
$ git clone git://github.com/mapbox/tilemill.git $ cd tilemill
Die für den Bau erforderlichen Abhängigkeiten können der oben verlinkten Installationsanleitung entnommen werden. Auf Arch Linux ist es nicht erforderlich, wie dort beschrieben Boost, Mapnik und NodeJS aus dem Quellcode zu bauen – alle Programme liegen bereits in einer ausreichend aktuellen Version vor. Konzentrieren wir uns stattdessen auf den Bau von TileMill:
$ npm install
Das downloaded und kompiliert eine ganze Reihe von Software und kann einige Zeit in Anspruch nehmen. Nach Abschluss der Installation kann TileMill wie folgt gestartet werden:
$ node index.js
Datenimport
Der Import der OSM-Daten in die PostgreSQL/PostGIS-Datenbank erfolgt
grundsätzlich mit osm2pgsql
. Am konkreten Aufruf des Programms aber
scheiden
sich
die
Geister
– ich habe es schließlich so aufgerufen, ohne irgendwelche Nachteile
feststellen zu können:
$ osm2pgsql --slim -d gis --number-processes 3 ~/Downloads/nordrhein-westfalen-latest.osm.pbf
Dises Prozess dauert relativ lange, bei mir war es relativ genau eine Stunde. Größere Datenmengen benötigen freilich länger.
Rendering
Für ein erfolgreiches Rendering ist es zunächst wichtig zu verstehen, wie der Prozess eigentlich abläuft. Für Mapnik existieren im Wesentlichen zwei Datenquellen: Shapefiles und Geodaten. Bei letzteren handelt es sich um das, was wir vorhin in PostGIS importiert haben, Shapefiles sind reine Konturdaten. Das kanonische Beispiel sind die Küstenlinien an den Weltmeeren, die OpenStreetMap nicht selbst erfasst, sondern über eine Shapefile von Natural Earth verwaltet. Sowohl von Shapefiles als auch von PostGIS-Daten können beliebig viele (lies: Solange der RAM reicht) in eine Karte importiert werden, man spricht oberbegrifflich von Datenquellen (engl. data sources).
Datenquelle / \ Shapefile Geodaten
Diese Datenquellen werden nun als Ebenen in eine bestimmte Reihenfolge gebracht (jede Ebene hat genau eine Datenquelle); beim finalen Rendering werden die Ebenen dann „aufeinander gepresst“. So könnte man beispielsweise ein sehr rohe Straßenkarte erstellen, indem man die Küstenlinien-Shapefile unter den Straßen-Geodaten anordnet:
Straßen-Geodaten Küsten-Shapefile ↓↓ Gesamtkarte
Die OpenStreetMap-Daten liefern insgesamt sieben Geodatenquellen:
gis=# \d Liste der Relationen Schema | Name | Typ | Eigentümer --------+--------------------+---------+------------ public | geography_columns | Sicht | postgres public | geometry_columns | Sicht | postgres public | planet_osm_line | Tabelle | quintus public | planet_osm_nodes | Tabelle | quintus public | planet_osm_point | Tabelle | quintus public | planet_osm_polygon | Tabelle | quintus public | planet_osm_rels | Tabelle | quintus public | planet_osm_roads | Tabelle | quintus public | planet_osm_ways | Tabelle | quintus public | raster_columns | Sicht | postgres public | raster_overviews | Sicht | postgres public | spatial_ref_sys | Tabelle | postgres
Alle Tabellen, die im obigen Listing mit „planet\_“ anfangen, sind in
Mapnik verwertbare Geodatenquellen unterschiedlichen Umfangs. So enthält
planet_osm_roads
etwa nur Straßen, planet_osm_polygon
nur in sich
abgeschlossene Objekte (z.B. Gebäude).
Jede Ebene kann zudem gestyled werden (z.B. Wege auf dieser Ebene blau, Hintergrund grün); die gesamte Kartenstruktur wird Mapnik in Form eines komplexen XML-Kontrukts mitgeteilt. Da insbesondere das Styling der verschiedenen Kartenelemente in XML eine ausgesprochen leidige Arbeit ist, hat TileMill hierfür einen Abkömmling von CSS einführt, CartoCSS. CartoCSS ist sehr mächtig und kann zur besonderen individuellen Gestaltung von Karten verwandt werden, für den Moment begnügen wir uns aber mit dem CartoCSS, das das OpenStreetMap-Projekt für seine eigene Online-Karte verwendet, openstreetmap-carto.
Hinweis: TileMill-Projekte können mithilfe des in Tilemill
enthaltenden Programms carto
(unter node_modules/carto/bin/carto
)
direkt in Mapnik-XML konvertiert werden. So ist es möglich, ein
TileMill-Projekt außerhalb des UIs von TileMill zu bearbeiten, zu stylen
und auch zu rendern.
Openstreetmap-Carto kommt als TileMill-Projekt daher, welches in den
Projektordner von TileMill kopiert werden muss. Damit dieser überhaupt
existiert, muss TileMill wie weiter oben gezeigt zumindest einmal
gestartet werden. Dieses TileMill-Projekt ist wie schon weiter oben
erwähnt der Grund dafür, dass die Datenbank gis
heißen muss – bei
einem anderen Datenbanknamen müssten für jede Ebene im TileMill-Projekt,
die auf die Geodaten zugreift, die Verbindungsdaten geändert werden.
Dies ist zwar möglich, aber ausgesprochen aufwendig.
Nach dem erstmaligen Start sollte ein Ordner
~/Documents/MapBox/project existieren
(sic, von XDG hat TileMill
bisher noch nicht gehört), in den das Openstreetmap-Projekt geklont
werden kann:
$ cd ~/Documents/MapBox/project $ git clone git://github.com/gravitystorm/openstreetmap-carto.git $ cd openstreetmap-carto
Die Instruktionen in der README können größtenteils ignoriert werden,
weil wir die notwendigen Vorbereitungen bereits getroffen haben.
Insbesondere entfällt der Fix von ne_10m_populated_places
, weil
aktuelle Versionen von Mapnik
das
Problem bereits behoben haben. Stattdessen können wir nun den Fix
fixen, d.h. in der Datei get_shapefiles.sh
folgende Zeilen
auskommentieren:
#process populated places echo "processing ne_10m_populated_places..." rm -f data/ne_10m_populated_places/ne_10m_populated_places_fixed.* ogr2ogr --config SHAPE_ENCODING UTF8 data/ne_10m_populated_places/ne_10m_populated_places_fixed.shp data/ne_10m_populated_places/ne_10m_populated_places.shp
und den darauf folgenden shapeindex
-Befehl wie folgt abändern:
shapeindex --shape_files \ data/simplified-land-polygons-complete-3857/simplified_land_polygons.shp \ data/land-polygons-split-3857/land_polygons.shp \ data/ne_10m_populated_places/ne_10m_populated_places.shp \ data/ne_110m_admin_0_boundary_lines_land/ne_110m_admin_0_boundary_lines_land.shp
Jetzt kann man das Skript ausführen, das einige Shapefiles herunterladen wird, die Openstreetmap-Carto als Datenquellen dienen. Danach kann das Projekt in TileMill geöffnet werden, indem es einfach auf der Startseite von TileMill ausgewählt wird. Sollte TileMill beim Öffnen des Projekts „file-not-found“-Fehlermeldungen zeigen, sollten die Dateinamen im Verzeichnis „data“ überprüft werden – wenn auch nur eine Datenquelle nicht gefunden wird, verweigert TileMill komplett die Arbeit und zeigt nur eine leere Karte ohne weiteren Kommentar.
In TileMill kann man nun ganz normal arbeiten; das Benutzerinterface ist recht intuitiv, die genaue Bedienung kann in der Anleitung nachgelesen werden. Wichtig ist insbesondere, beim Export eine Zoomstufe auszuwählen – Zoomlevel 0 erzeugt nur leere Karten (jedenfalls dann, wenn man nicht das gesamte (!) OSM-Datenmaterial in der PostGIS-Datenbank hat). Je nach Verwendungszweck kann man sich für ein passendes Export-Format entscheiden; der besseren Weiterverarbeitung wegen habe ich mich für SVG entschieden.
Nachbearbeitung
Die exportierte Karte ist in der Regel völlig unförmig, d.h. liegt in einem Seitenformat vor, das man so überhaupt nicht drucken kann. Mithilfe von Inkscape kann man die Karte jedoch etwa auf A1 herunterschneiden, indem man zunächst ein neues Dokument anlegt, danach in den Dokumenteneinstellungen das Seitenformat A1 + Querformat auswählt und anschließend das aus TileMill exportierte SVG importiert. Dieses Prozess dauert sehr lange und benötigt große Mengen Arbeitsspeicher, daher sollte man für diesen Schritt Geduld mitbringen. Nach erfolgtem Import kann die Karte auf der Seite platziert werden, wobei Überschüssiges ruhig über den Rand hinausragen darf. Über „Datei → Kopie speichern unter“ kann man nun nur den Seitenbereich (also das A1-Blatt) als PDF exportieren, wobei Teile außerhalb des Seitenbereichs abgeschnitten werden. Das Ergebnis sieht etwa so wie hier aus und ist druckfertig. Selbstverständlich kann man in Inkscape auch noch weitere Nachbearbeitungen machen, z.B. ein Gitter über die Karte legen oder eine Legende hinzufügen. Dies sei der Kreativität des Lesers überlassen – allerdings mit dem Hinweis, dass die Lizenzbedingungen von OpenStreetMap vorschreiben, dass irgendwo der Hinweis „© OpenStreetMap-Mitwirkende“ angebracht wird.
Fazit
OpenStreetMap ist ganz große Klasse. Neben Online- lassen sich damit
auch prima Druckkarten anfertigen, allerdings kränkt das Projekt in
dieser Hinsicht an fehlender und zuweilen sogar widersprüchlicher, weil
veralteter Dokumentation. Große Teile der im Internet (sogar im
OSM-Wiki) auffindbaren Informationen beziehen sich auf Mapnik Version
0.x, mittlerweile jedoch ist die Software schon zwei Major-Releases
weiter und damit schlicht nicht mehr kompatibel. Die alternativen
Renderer neben TileMill werden nicht mehr entwickelt, und CartoCSS hat
seinen Vorgänger MapCSS abgelöst. Auch PostgreSQL und PostGIS sind nicht
stehengeblieben, insbesondere ist es zur Verwendung von PostGIS nicht
mehr erforderlich, irgendwelche SQL-Skripte aus dem contrib/
-Pfad von
PostgreSQL auszuführen. Insgesamt bewegt sich die OSM-Software sehr
schnell, sodass ich hoffe, mit diesem Artikel ein wenig Ordnung in
dieses verwirrende Durcheinander gebracht zu haben. Wie lange er
freilich aktuell bleiben wird, weiß ich nicht zu sagen.