Skip to content

Basemaps — hosted data and cascaded external services

Goal: give every map a background, with a deliberate choice between two patterns — reference data downloaded once and hosted locally (recommended for production), and an external WMS cascaded through GeoServer (quick to set up, but bound by third-party licence and availability). Both are cached in the shared S3 tile cache.

flowchart LR
    NE[Natural Earth archive<br/>public domain] -- "ogr2ogr Job (once)" --> DB[(schema basemap<br/>countries)]
    GS[GeoServer ×N] -- "jdbc/meteo · basemap-db" --> DB
    EXT[External WMS provider] -. "cascade (WMSStore)" .-> GS
    GS -- "GWC tiles" --> S3[(bucket gwc-tiles)]
    PLUG[geoserver-init plugin<br/>VECTOR_LAYERS · BASEMAP_WMS_* · styles as code] --> GS
Hold "Alt" / "Option" to enable pan & zoom

Decision: ADR-0012. Artifacts: poc/07-basemaps/.

  • Source: Natural Earth 1:110m country boundaries — public domain, no licence constraints. The load Job reads the published archive directly (ogr2ogr /vsizip//vsicurl/…) into basemap.countries (schema owned by a dedicated basemap role). On the target platform the archive would come from the internal artifact repository (ADR-0007), not from the internet.
  • Publication: one more entry in VECTOR_LAYERS using the schema.view syntax (countries|basemap.countries|-|-|Country boundaries (Natural Earth)|basemap-countries) — the plugin maintains one JNDI datastore per schema (basemap-db) and assigns the code-managed SLD style basemap-countries (the SLD body ships with the plugin and is written through the Resource API, so it is stored in the database and shared by all replicas).
  • Caching: EXTRA_TILE_LAYERS=countries,osm — tiles go to the default S3 blobstore like any other layer.

Cascaded external WMS (optional)

BASEMAP_WMS_URL (capabilities URL), BASEMAP_WMS_LAYER (remote name) and BASEMAP_WMS_NAME (local name) drive the plugin: it creates a WMSStore and a cascaded layer. Empty URL = disabled. Caveats (ADR-0012): third-party terms of use, availability and latency; the S3 tile cache softens the load on the provider but the dependency remains.

Verification (tests poc/07-basemaps/tests/)

Schema init, Natural Earth load (177 features), reader grant:

Schema

Load

Startup: per-schema datastore, layers, style and cascade verified:

Startup

01 Hosted countries layer: WFS 177 features, GetMap with the code-managed default style:

Countries test

Countries

02 Cascaded layer served through GeoServer:

Cascade test

OSM cascade

03 Basemap tiles in the shared S3 cache: MISS → HIT on the same pod, HIT from another pod (both hosted and cascaded layers):

Tiles

04 Layers, style and cascade survive a pod replacement; tiles still HIT:

Restart

Deviations and pitfalls observed

  • ogr2ogr in the GDAL "ubuntu-small" image includes the PostgreSQL driver; -lco FID=fid gives the table a real primary key, so no gt_pk_metadata entry is needed for plain tables.
  • The cascaded layer's remote name (OSM-WMS) comes from the provider's capabilities; the local name (osm) is ours.