Zum Hauptinhalt springen
  1. Artikel/

Privatsphären­freundliche Karten für jede Webseite

Autor
Christian Schärf

Einleitung
#

Gelegentlich soll eine Landkarte auf einer Webseite eingebunden werden, um geografische Sachverhalte darzustellen. Obwohl es prinzipiell möglich ist, die Software zum Bereitstellen der Kartendaten selbst zu betreiben, kann das bei gehosteten Webseiten oft nicht umgesetzt werden, da die Hosting-Plattform das Betreiben beliebiger Software nicht unterstützt. Dann wird häufig auf eine externe Lösung zurückgegriffen, was jedoch datenschutzrechtliche Komplikationen nach sich zieht.

Mit PMTiles können allerdings vektorgrafikbasierte Karten auf fast beliebigen Seiten eingebunden werden. Die technischen Voraussetzungen sind lediglich:

  • Die Hosting-Plattform muss das Bereitstellen von statischen Dateien unterstützen.
  • Der Webserver muss HTTP-Bereichsanfragen unterstützen.
  • Auf der Webseite muss HTML-Code eingebunden werden.

Technologiestack für Karten
#

Raster- und Vektorkarten
#

Alle Kartendarstellungen werden aus einzelnen Teilen, den sogenannten Tiles (englisch für Fliese), zusammengesetzt. Diese unterteilen die Weltkarte nach geografischen Koordinaten sowie Vergrößerungsstufe, da bei hohen Vergrößerungen mehr Details angezeigt werden. Auf diese Weise müssen nur die Kartendaten des aktuell gezeigten Ausschnitts geladen werden.

Es gibt zwei verschiedene Arten von Tiles: Raster- und Vektortiles. Rastertiles sind einfache Bilddaten, die einen kleinen Bereich der Karte darstellen. Sie werden von einem Renderer aus den Kartendaten erstellt.

Vektortiles hingegen enthalten geografische Informationen in einem „leichter verdaulichen“ Format als die Rohdaten, das außerdem das schnelle Auslesen von Ausschnitten unterstützt. Daraus wird erst clientseitig (bei Webseiten im Browser) die Karte gerendert. Sie haben zahlreiche Vorteile, beispielsweise:1

  • Stufenlose Vergrößerungen sind möglich.
  • Die Darstellung kann angepasst werden, zum Beispiel durch verschiedene Farbschemata oder inhaltliche Schwerpunkte.
  • Beim Rotieren bleiben die Beschriftungen aufrecht.

Im Folgenden werden Vektorkarten betrachtet.

Der Stack
#

Mehrere Schritte sind erforderlich, um von den Kartendaten zur Darstellung im Browser zu gelangen.

flowchart LR
raw-data@{shape: lin-cyl, label: "OSM-Daten"}
raw-data --> generator
generator(Generator)
generator -- schreibt --> tiles
tiles@{shape: lin-cyl, label: "Tile-Archiv"}
client(Browser)
client --- cloud
cloud@{shape: cloud, label: "Internet"}
cloud -- Anfrage --> tileserver
tileserver(Tileserver)
tileserver -- Zugriff --> tiles
  1. Aus den Kartendaten werden von einer Generator-Software aus den Karten-Rohdaten die Tiles erzeugt und in einem Archiv gespeichert.
  2. Der Tileserver nimmt Anfragen des Browsers nach einzelnen Tiles entgegen und liest die Tiles aus dem Archiv aus.
  3. Der Karten-Renderer setzt aus den einzelnen Tiles die Karte zusammen und stellt sie im Browser dar.

Als Renderer wird die MapLibre-Bibliothek verwendet. Diese im Browser ausgeführte Software wurde von Mapbox abgspalten, als Mapbox zu einer unfreien Lizenz wechselte. MapLibre unterstützt die Mapbox Vector Tiles. Dies ist das Dateiformat, in welchem die Vektorkarten über das Netzwerk zum Browser übertragen werden. Die Tiles sind in Vergrößerungsstufen unterteilt und bilden jeweils nur einen kleinen Kartenausschnitt ab. Es ist prinzipiell möglich, die Tiles einzeln im Dateisystem abzulegen. Allerdings wird durch die mehrfache Speicherung der in den Tiles enthaltenen Informationen so viel Speicherplatz benötigt, dass es unpraktikabel ist.2

Stattdessen werden die Tiles als Archiv in einer einzigen Datei gespeichert. Ein solches Format ist MBTiles. Eine auf dem Server ausgeführte Software kann daraus für jede Anfrage des Clients die gewünschte Tile auslesen.

Als Datenquelle dient OpenStreetMap. Die Daten werden von Freiwilligen zusammengetragen und können für jeden Zweck genutzt werden. Die gesamten Kartendaten sind von Planet OSM erhältlich. Regionale Auszüge werden von der Geofabrik bereitgestellt.

Mit einem Tile-Generator können daraus die Tiles, die später vom Server bereitgestellt werden, erzeugt werden. Dieser rechenaufwändige Schritt muss allerdings meistens nicht selbst durchgeführt werden, stattdessen wird auf fertig erstellte Tiles zurückgegriffen.

PMTiles
#

Ein weiteres Archivformat für Vektorkarten ist das von Protomaps entwickelte PMTiles. Dieses erlaubt es, den benötigten Dateiabschnitt des Archivs für eine bestimmte Tile clientseitig zu berechnen und über eine HTTP-Bereichsabfrage abzurufen. Eine spezielle serverseitige Software wird damit nicht mehr benötigt, lediglich ein HTTP-Server, welcher Bereichsabfragen unterstützt.

Der Abruf der Tiles über HTTP-Bereichsabfragen wird von einem Plugin für MapLibre implementiert.

Alles Zusammensetzen
#

Kartendaten
#

Aus OpenStreetMap-Rohdaten können Vektortiles beispielsweise mit Tilemaker erstellt werden.3 Da dieser Schritt viel Rechenzeit benötigt und aufgrund der Verfügbarkeit von fertig erstellten Tiles meistens nicht nötig ist, wird hier nicht näher darauf eingegangen.

Stattdessen werden die Tiles von Protomaps heruntergeladen. Die den gesamten Planeten umfassende Datei ist mit Stand März 2026 etwa 125 GB groß. Mit dem pmtiles-Kommando­zeilen­werkzeug kann ein geografischer Auszug daraus heruntergeladen werden.4 Dabei müssen die Koordinaten des Umrissrechtecks angegeben werden. Für Gebietskörperschaften lassen sich diese einfach mit dem Bounding Box-Werkzeug von Versatiles ermitteln. Für Mittelfranken sind die Koordinaten beispielsweise 10.069,48.86,11.602,49.789. Der Befehl zum Herunterladen der Karte lautet damit:

pmtiles extract https://build.protomaps.com/20260329.pmtiles mittelfranken.pmtiles --bbox=10.069,48.86,11.602,49.789

Dabei sollte sinnvollerweise der Dateiname 20260320.pmtiles an das aktuelle Datum angepasst werden. Die resultierende Datei mittelfranken.pmtiles ist in diesem Fall übersichtliche 160 MB groß.

JavaScript-Bibliotheken
#

Für die Darstellung der Karte im Browser werden diese Bibliotheken benötigt:

Auf basemaps kann verzichtet werden, wenn der Kartenstil als statische JSON-Datei hinterlegt wird.6 Diese kann von maps.protomaps.com erhalten werden.

Diese Bibliotheken können von UNPKG eingebunden werden. Da wir allerdings ohne Drittserver auskommen wollen, werden sie heruntergeladen, um dann vom eigenen Webserver bereitgestellt zu werden:

wget https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js
wget https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css
wget https://unpkg.com/pmtiles@latest/dist/pmtiles.js
wget https://unpkg.com/@protomaps/basemaps@latest/dist/basemaps.js

Diese Dateien werden in das HTML-Dokument eingebunden:

<script src="/maps/maplibre-gl.js"></script>
<script src="/maps/pmtiles.js"></script>
<script src="/maps/basemaps.js"></script>
<link href="/maps/maplibre-gl.css" rel="stylesheet" />

Der Pfad muss dabei gegebenenfalls an den Speicherort auf dem Webserver angepasst werden.

Assets
#

Für die Anzeige der Karte werden außerdem noch Assets (Glyphen für MapLibre sowie Sprites) benötigt.7 Diese können aus dem entsprechenden GitHub-Repository erhalten werden. Benötigt werden die Ordner fonts und sprites.

HTML-Code
#

Die Karte kann mit diesem HTML-Code in die Webseite eingebunden werden:

<!-- 1 -->
<div id="map" style="height: 30em; width: 100%"></div>
<script type="module">
    // 2
    const protocol = new pmtiles.Protocol();
    maplibregl.addProtocol("pmtiles", protocol.tile);
    // 3
    const origin = new URL(document.URL).origin;
    const map = new maplibregl.Map({
        container: "map",
        style: {
            version: 8,
            sources: {
                protomaps: {
                    type: "vector",
                    attribution: "<a href=\"https://github.com/protomaps/basemaps\">Protomaps</a> © <a href=\"https://openstreetmap.org\">OpenStreetMap</a>",
                    // 4
                    url: "pmtiles:///maps/mittelfranken.pmtiles",
                },
            },
            // 5
            layers: basemaps.layers("protomaps", basemaps.namedFlavor("light"), {lang:"de"}),
            // 6
            sprite: origin + "/maps/basemaps-assets/sprites/v4/light",
            glyphs: origin + "/maps/basemaps-assets/fonts/{fontstack}/{range}.pbf",
        },
        zoom: 10,
        center: [11.0772980, 49.4538720],
        // 7
        maxBounds: [
            [
                10.069,
                48.86,
            ],
            [
                11.602,
                49.789
            ],
        ],
    });
</script>

Anmerkungen:

  1. In diesem div wird die Karte angezeigt. In diesem Beispiel wird die Größe mit CSS festgelegt. Über die zugewiesene id kann MapLibre ihn referenzieren und die Karte rendern.
  2. pmtiles-Plugin registrieren, damit es später als Datenquelle verwendet werden.
  3. Die Glyphen und Sprites müssen als absoluter Pfad angegeben werden.8 Damit die Domain der Webseite nicht fest hinterlegt werden muss, wird sie aus dem document-Objekt ausgelesen.9
  4. Die pmtiles-Datei wird mit dem pmtiles-Protokoll als Datenquelle angegeben. Dahinter kann ein absoluter oder relativer Pfad stehen.
  5. Der Kartenstil wird durch die Darstellungsebenen definiert. Diese werden von basemaps bereitgestellt und sind in verschiedenen Varianten verfügbar. Als Sprache für die Kartenbeschriftungen wird Deutsch eingestellt.
  6. Die absolute URL der Sprites und Glyphen wird aus dem Origin und dem Speicherpfad auf dem Webserver zusammengesetzt.
  7. Der anzeigbare Kartenausschnitt wird auf den Bereich festgelegt, für den Kartendaten heruntergeladen wurden.

Resultat
#

Im Ergebnis sieht die Karte beispielsweise so aus:

Erweiterungsmöglichkeiten
#

Meistens ist das Anzeigen einer Standardkarte nicht das Ziel. Beliebige Zusatzdaten können beispielsweise als GeoJSON hinzugefügt10 und in zusätzlichen Kartenebenen angezeigt werden.