Europa im Detail: So erstellst du deinen eigenen OpenStreetMap-Server


Software • by Sven Reifschneider • 16 September 2024 • 0 comments
#openstreetmap #linux #howto #projekt #internet
info
This post is also available in English. Read in English

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.

Titelbild

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.

Titelbild

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).

Titelbild

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
Titelbild

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.

Titelbild

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:

Titelbild

 

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.


Share this post

If you enjoyed this article, why not share it with your friends and acquaintances? It helps me reach more people and motivates me to keep creating awesome content for you. Just use the sharing buttons below to share the post on your favorite social media platforms. Thank you!

Sharing Illustration
Donating Illustration

Support the Blog

If you appreciate my work and this blog, I would be thrilled if you'd like to support me! For example, you can buy me a coffee to keep me refreshed while working on new articles, or simply contribute to the ongoing success of the blog. Every little bit of support is greatly appreciated!

Bitcoin (Segwit):3FsdZmvcwviFwq6VdB9PZtFK827bSQgteY
Ethereum:0x287Ffa3D0D1a9f0Bca9E666a6bd6eDB5d8DB9400
Litecoin (Segwit):MD8fMGDYtdeYWoiqMeuYBr8WBPGKJxomxP
Dogecoin:DTA6gkDCp1WncpoFJghzxCX7XPUryu61Vf
Sven Reifschneider
About the author

Sven Reifschneider

Greetings! I'm Sven, a tech innovator and enthusiastic photographer from scenic Wetterau, near the vibrant Frankfurt/Rhein-Main area. This blog is where I fuse my extensive tech knowledge with artistic passion to craft stories that captivate and enlighten. Leading Neoground, I push the boundaries of AI consulting and digital innovation, advocating for change that resonates through community-driven technology.

Photography is my portal to expressing the ephemeral beauty of life, blending it seamlessly with technological insights. Here, art meets innovation, each post striving for excellence and sparking conversations that inspire.

Curious to learn more? Follow me on social media or click on "learn more" to explore the essence of my vision.


No comments yet

Add a comment

You can use **Markdown** in your comment. Your email won't be published. Find out more about our data protection in the privacy policy.