"Tiled web maps" is a term for interactive web maps you can pan, tilt and zoom and where data is loaded dynamically as you need it. They're also referred to as "slippy maps", a term popularised by OpenStreetMap in the mid-2000s.

Building a general-purpose tiled web map

flowchart LR
data["Geodata"]
schema["Schema"]
tile_gen["Tile Generator"]
web["Web"]
tile_server["Tile Server"]

data --> tile_gen --"Tiles"--> tile_server --"Tiles"--> web
schema --> tile_gen
Stylesheet --> web

Wir haben diesen Workflow mehr oder weniger implementiert. Insbesondere haben wir zwei separate Tileserver:

  1. Ein Proxy-Service, der alle Requests nach static.datenhub.net bekommt. Das ist ein Node-Service aus dem Versatiles Projekt (@versatiles/google-cloud). Die meisten Requests werden einfach durchgereicht aber es gibt einen Special Case für Requests auf *.versatiles-Dateien. Wenn so einer kommt werden die GET-Parameter und die Container-Datei geparst, und mit dieser Info die richtige Kachel ausgeliefert. Deshalb funktionieren Requests wie: GET https://static.datenhub.net/data/zensus-test/zensus2011e.versatiles?tiles/7/67/42 1
  2. Ein versatiles-rs tileserver, der OSM-Daten und Gemeinden ausliefert.
flowchart BT
classDef maybe stroke-style:dotted
class osm maybe;

subgraph "<span style='white-space:nowrap'>GCP Network Services (swr-data-1)</span>"
lb["Load Balancer + Cache"]
end

web[Frontend<br/><small>Svelte + Maplibre GL JS + <code>style.json</code></small>]
subgraph "GCP Cloud Run (swr-data-1)"
static-proxy["Static Proxy<br/><small>static.datenhub.net<br/><a href="https://github.com/SWRdata/datenhub-static-proxy">Repo</a>, <a href="https://console.cloud.google.com/run/detail/europe-west3/datenhub-static-proxy/metrics?inv=1&invt=AbnyaQ&project=swr-data-1">Service</a></small>"]
tileserver["Versatiles Server<br/><small>tiles.datenhub.net<br/><a href="https://github.com/SWRdata/versatiles-cloud-server">Repo</a>, <a href="">Service</a></small>"]

end

subgraph "GCS (swr-data-1)"
gcs["File Storage<br><small>datenhub-net-static</small>"]
versatiles-tiles["File Storage<br/><small>storage.googleapis.com/versatiles</small><br><small><a href="https://console.cloud.google.com/storage/browser/versatiles/download/planet;tab=objects?inv=1&invt=AboI-Q&project=swr-data-1&prefix=&forceOnObjectsSortingFiltering=false">Bucket</a></small>"]
end
project-data["Story Data"]
fonts["SWR Fonts"]
dhfonts["DEAD 💀: datenhub-map-fonts<br><small><a href='[text](https://github.com/SWRdata/datenhub-map-fonts)'>Repo</a></small>"]
versatiles-converter["Versatiles Converter<br/><small><code>versatiles convert</code></small>"]
tippecanoe["Generate Tiles<br/><small>arbitrary logic + <code>tippecanoe</code></small>"]

gcs-->static-proxy
versatiles-tiles-->tileserver
static-proxy--"TTL 60s"-->lb
lb<-->web
tileserver--"TTL 28 days"-->lb
project-data--".geojson etc."-->tippecanoe--".mbtiles"-->versatiles-converter--".versatiles"-->gcs
fonts--".otf"-->dhfonts-.".pbf".->gcs

subgraph Versatiles Projekt
tilemaker["Generate Tiles<br/><small><code>tilemaker</code> + <code>versatiles convert<code/></small>"]
shortbread["Shortbread<br><small>JSON + Lua</small>"]
osm["OSM + NatEarth"]
osm -.".pbf".-> tilemaker
shortbread -.-> tilemaker -.-> versatiles_download[<a href="https://download.versatiles.org/">download.versatiles.org</a>]
end

versatiles_download -."???".-> versatiles-tiles

Building a custom maplibre style

Prior work

References

  1. Das sieht so ähnlich aus wie ein HTTP-Range-Requests im pmtiles-Format, ist es aber nicht ↩︎