Im ersten Teil dieser Blogserie habe ich den langen und oft steinigen Weg beschrieben, wie ich mit OpenStreetMap (OSM) einen eigenen Kartenserver erstellt habe. Wir haben uns durch verschiedene Hindernisse gekämpft, Rückschläge erlitten und letztendlich den Durchbruch geschafft – mit einem speziellen Tile-Server für die DACH-Region (Deutschland, Österreich, Schweiz). Falls du den ersten Teil noch nicht gelesen hast, solltest du das unbedingt nachholen, um die grundlegenden Herausforderungen und Erkenntnisse zu verstehen.
Jetzt kommen wir zu Teil 2: Hier wird es praktisch. Ich gebe dir eine detaillierte Anleitung, wie du einen benutzerdefinierten Kartenserver für die gesamte europäische Region erstellst. Dabei gehen wir Schritt für Schritt vor – von der Hardwareeinrichtung über die Tile-Generierung bis hin zur Bereitstellung der Kartendaten auf deinem Webserver.
Wenn du bereit bist, großflächige OSM-Daten zu verarbeiten und deinen eigenen Tile-Server zu starten, dann geht es jetzt richtig los!
Rückblick: Herausforderungen und Erfolge
Als kurze Zusammenfassung: In Teil 1 haben wir uns verschiedenen Problemen gestellt, um OSM-Karten zu erstellen und bereitzustellen. Nach zahlreichen Versuchen mit unterschiedlichen Tools und Umgebungen – von VMs mit zu wenig Leistung bis hin zu veralteter Hardware – gelang es uns schließlich, mit Hilfe von OpenMapTiles die DACH-Region (Deutschland, Österreich, Schweiz) erfolgreich zu rendern. Doch der Weg war gespickt mit Hürden: langsame Importe, Speicherprobleme und Platzmangel. Es war eine wertvolle Lektion in Geduld und Fehlersuche.
Mit diesen Erfahrungen und einem soliden Prozess können wir jetzt den nächsten Schritt wagen: die Skalierung für ganz Europa.
Die Hardware: So bereitest du deinen Tile-Server für Europa vor
Die Kartendaten für einen ganzen Kontinent wie Europa (etwa 30GB komprimierte OSM-Daten) zu rendern, ist keine leichte Aufgabe. Die Hardwareanforderungen steigen erheblich im Vergleich zur DACH-Region (ca. 4GB komprimierte OSM-Daten). Das wirst du benötigen:
Minimale Hardwareanforderungen
- CPU: Ein moderner Quad-Core-Prozessor oder besser (z.B. Intel i5, AMD Ryzen 5)
- RAM: 24GB bis 32GB (mehr ist immer besser)
- Speicherplatz: Mindestens 500GB SSD (NVMe bevorzugt, aber SATA-SSD funktioniert auch); ich habe eine 750GB SSD genutzt.
- Alternativ kannst du eine zweite SSD für den Docker-Speicher verwenden. Das verhindert Speicherprobleme beim Umgang mit großen Dateien, während du dein System auf einer kleineren SSD oder sogar über USB laufen lässt.
Obwohl du dies auf einer Cloud-Instanz für den temporären Gebrauch einrichten kannst, bedenke, dass die Verarbeitung der Europadaten Tage, wenn nicht Wochen dauern wird. Für diesen Schritt wird ein leistungsstarker lokaler Rechner oder eine gemietete Cloud-Instanz empfohlen.
Für das Erstellen der .mbtiles
-Datei reicht allerdings ein leistungsfähiger Host aus. Sobald die Datei erstellt ist, kannst du sie problemlos auf einem einfachen Webserver bereitstellen. Der eigentliche Serverbetrieb ist relativ ressourcenschonend.
Festplattenkonfiguration für Docker
Wenn du eine zusätzliche SSD verwendest, stelle sicher, dass Docker den zweiten Speicher nutzt. Dies lässt sich durch Anlegen einer Datei /etc/docker/daemon.json
konfigurieren:
{
"data-root": "/pfad/zur/externenfestplatte/docker-files"
}
Das verhindert, dass der Haupt-SSD der Speicherplatz ausgeht – besonders, wenn es um große Datensätze wie Europa geht, die unkomprimiert über 500GB Speicherplatz beanspruchen können.
Einrichtung der Host-Umgebung
Installation der Grundwerkzeuge
Für dieses Setup verwenden wir Debian 12. Ich habe eine minimalistische Installation durchgeführt, die nur SSH unterstützt. Beginne mit der Installation der notwendigen Tools:
apt update
apt install docker-compose vim git curl build-essential htop tmux
Da dieser Prozess über längere Zeit läuft, empfehle ich die Verwendung von tmux, einem Terminal-Multiplexer, der es dir ermöglicht, Sessions weiterzuführen, selbst wenn deine SSH-Verbindung abbricht. So startest du eine Session:
tmux new -s osm
Es ist hilfreich, sich mit den Grundlagen von tmux vertraut zu machen – es spart dir Zeit und Nerven, da du lange Prozesse nicht neu starten musst, falls die SSH-Verbindung unterbrochen wird. Zum Beenden einer Sitzung drückst du "Ctrl + B" und dann "D", um die Sitzung zu trennen. Mit tmux a -t osm
kannst du sie wieder aufnehmen. Manche bevorzugen GNU Screen als Alternative.
Klonen von OpenMapTiles
Sobald die Umgebung bereit ist, klonen wir das OpenMapTiles-Repository und initialisieren die notwendigen Verzeichnisse, so wie es die offizielle Anleitung beschreibt:
cd /usr/local/src
git clone https://github.com/openmaptiles/openmaptiles.git
cd openmaptiles
make
Konfigurieren der Zoomstufen
Für mehr Detailreichtum in der generierten Karte empfehle ich, die maximale Zoomstufe auf 20 zu setzen. Dies kannst du in der .env
-Datei leicht ändern:
sed -i 's/^MAX_ZOOM=.*/MAX_ZOOM=20/' .env
source .env
Der source
-Befehl macht die Variablen dann in unserer Umgebung zugänglich. Beachte, dass du diese Datei jedes Mal neu ausführen musst, wenn du eine neue Umgebung startest (z.B. nach einem Neustart).
Schritt-für-Schritt-Anleitung: Tiles für Europa generieren
Jetzt kommen wir zum detaillierten Prozess der Kartengenerierung für Europa.
Anstatt das Quickstart-Skript von OpenMapTiles zu verwenden, führen wir die Befehle Schritt für Schritt aus. Das gibt uns mehr Flexibilität, besonders wenn Probleme auftreten.
Initiales Setup
Bevor wir mit der Tile-Generierung beginnen, bereinigen wir die Umgebung und bereiten Docker vor:
make refresh-docker-images
make init-dirs
make clean
make all
Das stellt sicher, dass alles korrekt eingerichtet ist und keine alten Daten oder unvollständigen Durchläufe den Prozess stören.
Herunterladen des Europadatensatzes
Als Nächstes laden wir die .osm.pbf
-Datei für Europa herunter. Du kannst sie entweder manuell von Geofabrik herunterladen oder OpenMapTiles den Download erledigen lassen:
make download area=europe
In beiden Fällen wird die Datei europe.osm.pbf
im data
-Verzeichnis abgelegt. Falls du so wie ich herumexperimentierst, macht es Sinn, die Datei zu sichern und bei Bedarf wieder ins Verzeichnis zu kopieren.
Die Datei ist über 30GB groß – stelle also sicher, dass du genügend Speicherplatz hast.
Starten der Datenbank
Für die vorkonfigurierten Daten starten wir die Datenbank mit den OpenMapTiles-Voreinstellungen:
make start-db-preloaded
Damit wird eine PostgreSQL / PostGIS-Datenbank gestartet, die die OSM-Daten verarbeitet.
Importieren der OSM-Daten
Jetzt beginnen wir mit dem Import der rohen OSM-Daten in die Datenbank. Dieser Schritt dauert auf meinem Rechner etwa 10 Stunden:
make import-osm
Importieren von Wikidata-Labels
Als nächstes importieren wir Labels von Wikidata für zusätzliche Kontextinformationen (z.B. Sehenswürdigkeiten). Dies ist schneller und dauert etwa 2-3 Stunden:
make import-wikidata
Beachte, dass all diese Daten viel Speicherplatz benötigen. Ich habe mit einer 500GB SSD gearbeitet, und dieser Prozess schlug nach einigen Stunden fehl. Also richtete ich eine alte 750GB SSD ein, konfigurierte sie für Docker und wiederholte alle Befehle. Diesmal funktionierte es.
Ausführen der SQL-Skripte
In diesem Schritt werden eine Reihe von SQL-Skripten ausgeführt, um die Daten zu formatieren und zu optimieren. Das dauerte bei mir über 13 Stunden, ist aber ein entscheidender Teil des Prozesses:
make import-sql
An diesem Punkt hast du den Großteil der Arbeit erledigt. Überprüfe, ob die Datenbankstruktur korrekt ist:
make analyze-db
make test-perf-null
Da wir die Kacheldaten für einen Abschnitt des Planeten generieren, müssen wir die Begrenzungsbox berechnen:
make generate-bbox-file ${MIN_ZOOM:+MIN_ZOOM="${MIN_ZOOM}"} ${MAX_ZOOM:+MAX_ZOOM="${MAX_ZOOM}"}
Generierung der Tiles
Mit den vorbereiteten Daten ist es nun Zeit, die Tiles zu generieren. Dies ist mit Abstand der längste Schritt, besonders bei einer so großen Region wie Europa. Bei mir dauerte es über 13 Tage, bis der Vorgang abgeschlossen war!
make generate-tiles-pg
Beachte, dass die Prozessanzeige anfangs eine stark übertriebene Restzeit anzeigt. Je weiter der Vorgang voranschreitet, desto schneller sinkt diese Zahl.
Nach 2 Stunden zeigt der Prozess 6279 Tage und 23 Stunden verbleibende Zeit an.
Nach einem Tag sind es noch 3537 Tage, 0,0264 % sind erledigt.
Nach 3 Tagen sind es noch 2255 Tage, 0,1131 % abgeschlossen. Nach 4,5 Tagen sind es noch 1890 Tage, 0,2142 % abgeschlossen.
Nach 6 Tagen, 6 Stunden und 6 Minuten haben wir 6666,66 Minuten hinter uns, was 0,4080 % entspricht. Jetzt sind es nur noch 1490 Tage.
Nach 9 Tagen sind über 1,2 % erledigt, nur noch 705 Tage verbleiben ...
Dann beginnt es schneller zu gehen. Nach 11 Tagen sind wir bei 4,4 %, nur noch 222 Tage verbleiben.
Nach 13 Tagen ist der Prozess endlich abgeschlossen und zeigt an:
Zoom Tile count Found tile ranges
------ ------------ -----------------------
0 1 0,0 x 0,0
1 2 0,1 x 1,1
2 4 1,2 x 2,3
3 16 2,4 x 5,7
4 56 4,8 x 10,15
5 168 9,17 x 20,30
6 644 18,34 x 40,61
7 2,475 37,69 x 81,123
8 9,504 75,139 x 162,246
9 37,664 150,279 x 325,492
10 150,304 300,559 x 651,985
11 600,362 601,1118 x 1303,1971
12 2,396,628 1203,2236 x 2606,3942
13 9,586,512 2406,4472 x 5213,7885
14 38,332,392 4813,8944 x 10426,15771
Nach Abschluss des Vorgangs hast du eine 38GB große .mbtiles
-Datei, die alle Kachel-Daten für Europa enthält. Diese Datei kann nun an deine Nutzer bereitgestellt werden.
Da wir auf diesem Host fertig sind, können wir die Datenbank stoppen:
make stop-db
Einrichten eines Tile-Servers
Nachdem die Tiles generiert wurden, ist der nächste Schritt, sie auf einem Webserver bereitzustellen. Dafür verwenden wir TileServer GL Light, eine leichtgewichtige Version von TileServer ohne Abhängigkeiten.
Installation von TileServer GL Light
Wenn du mit Docker vertraut bist, kannst du der Standardanleitung für TileServer GL folgen, deine mbtiles-Datei bereitstellen und loslegen. In meinem Fall habe ich mich für eine Node.js-basierte Einrichtung entschieden, um meinen Webserver schlanker zu halten (und dockerfrei). Beginne mit der Installation von Node.js und TileServer GL Light:
curl -fsSL https://deb.nodesource.com/setup_22.x -o nodesource_setup.sh
bash nodesource_setup.sh
apt-get install -y nodejs
npm install -g tileserver-gl-light
Webserver (Nginx)
Um die Tiles bereitzustellen, nutze ich Nginx. Installiere es wie folgt:
apt install nginx-full
Erstelle ein Verzeichnis, um deine Kartendateien zu hosten:
mkdir /var/www/maps
Kopiere deine generierte europe.mbtiles-Datei in dieses Verzeichnis.
Jetzt startest du den Tile-Server:
/usr/bin/tileserver-gl-light --file /var/www/maps/europe.mbtiles -p 3000 -u "https://maps.example.org/tiles"
Dies stellt die Tiles auf Port 3000 bereit. Die Tiles sind nun unter 127.0.0.1:3000/tiles
abrufbar, aber alle zurückgegebenen URLs haben https://maps.example.org/tiles
als Basis.
Nginx konfigurieren
Um deine Karten über das Web bereitzustellen, müssen wir Nginx konfigurieren. In meinem Fall möchte ich die Karten über die URL https://maps.example.org
und SSL (ich nutze Let’s Encrypt) bereitstellen. Erstelle einen neuen Serverblock (vhost) in /etc/nginx/sites-enabled/maps.conf
:
server {
listen 80;
listen [::]:80;
server_name maps.example.org www.maps.example.org;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name maps.example.org www.maps.example.org;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
# Provide the tiles via tileserver on port 3000
location ~ /tiles/(?.*) {
proxy_set_header X-Rewrite-URL $uri;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://127.0.0.1:3000/$fwd_path$is_args$args;
}
location / {
root /var/www/maps;
rewrite ^(.+)/+$ $1 permanent;
try_files $uri $uri/ /index.html;
}
}
Lade Nginx neu:
systemctl reload nginx
Jetzt sind deine Karten unter https://maps.example.org
zugänglich und dein Tile-Server unter https://maps.example.org/tiles
, der alles an 127.0.0.1:3000
weiterleitet. Wir haben nun einen funktionierenden Tile-Server, benötigen aber noch eine kleine Karten-UI, um diese anzuzeigen.
Kartenanzeige mit MapLibre GL JS
Um die Tiles zu visualisieren, nutzen wir MapLibre GL JS, eine Open-Source-Mapping-Bibliothek. Erstelle eine einfache index.html
-Datei im Verzeichnis /var/www/maps
basierend auf dem Beispiel von MapLibre:
Im gleichen Verzeichnis müssen wir nun eine style.json
bereitstellen, die alle unsere Konfigurationen enthält. Du kannst zwischen verschiedenen Kartenstilen wählen. Ich habe mich für OSM Liberty entschieden, da dieser Stil sehr ansprechend aussieht.
Nimm die style.json
-Datei von dort und passe die openmaptiles
-Quellen in Zeile 12 an. Anstatt MapTiler zu verwenden, setzen wir unseren eigenen Tiles-Server ein:
{
"sources": {
"openmaptiles": {
"type": "vector",
"url": "https://maps.example.org/tiles/data/v3.json"
}
}
}
Automatisierung mit Systemd
Wir haben unseren Tile-Server manuell gestartet. Für den produktiven Einsatz ist es jedoch sinnvoll, diesen als Dienst laufen zu lassen, damit er automatisch bei jedem Neustart des Servers startet.
Erstelle dafür eine systemd-Dienstdatei unter /etc/systemd/system/tileserver.service
:
[Unit]
Description=Tileserver GL osm tile server
After=local-fs.target
After=network.target
After=nginx.service
[Service]
PIDFile=%t/tileserver.pid
ExecStart=/usr/bin/tileserver-gl-light --file /var/www/maps/europe.mbtiles -p 3000 -u "https://maps.example.org/tiles"
ExecReload=/bin/kill -USR2 $MAINPID
User=www-data
Type=simple
[Install]
WantedBy=multi-user.target
Aktiviere und starte den Dienst:
systemctl enable --now tileserver.service
Nun ist dein Kartenserver voll eingerichtet, wird bei jedem Neustart automatisch gestartet und ist bereit zur Nutzung.
Fazit
Nach Wochen harter Arbeit, Geduld und Lösungsfindung haben wir nun einen eigenen Kartenserver erstellt, der die gesamte europäische Region abdecken kann. Von der Verarbeitung der OSM-Daten über die Konfiguration des Webservers bis hin zur Bereitstellung der Tiles mit MapLibre GL JS – wir haben jetzt volle Kontrolle über die eigene OpenStreetMap-basierte Lösung.
Die Erstellung der Europakacheln hat zwar 13 Tage gedauert, und das Projekt hat sich über mehrere Wochen erstreckt (Begonnen im Februar, waren die Tiles für Europa schließlich erst weit nach Ostern, Ende April fertig), aber das Ergebnis war die Mühe definitiv wert. Dieses System kann jetzt problemlos skaliert werden, um noch größere Regionen abzudecken, und mit den richtigen Tools können wir diese Infrastruktur weiter optimieren.
Nun haben wir unsere eigenen Karten, die wir in unseren Apps verwenden können – ohne uns um API-Kontingente oder Datenschutzprobleme sorgen zu müssen.
Hast du Fragen oder Feedback? Teile sie gerne in den Kommentaren!
Dieser Beitrag wurde von mir mit Unterstützung künstlicher Intelligenz (GPT-4o) erstellt. Die Illustrationen sind KI-generiert. Alle Screenshots wurden von mir erstellt. Neugierig, wie KI solche Texte und Illustrationen aus deinen eigenen Ideen erstellen kann? Erfahre mehr auf der Neoground GmbH-Website.
No comments yet
Add a comment