GIS Contribution — Foundation Workshop¶
This page answers the Product & Technology Foundation Workshop agenda for the GIS / geospatial visualization capability. It follows the agenda's own numbering and uses the formats the agenda asks for: lessons as Problem → Root Cause → New Principle, technology decisions as Need → Alternatives → Decision → Rationale backed by lightweight ADRs.
Everything stated here is already built and tested, not proposed on paper: a working reference implementation runs on a Kubernetes cluster, every claim below links to the guide or ADR that proves it, and each guide ships with a rerunnable test suite.
If you read only two pages
Vision — the direction in one page. How it works — the platform explained without jargon.
Part 1 — WHAT: GIS in the product landscape¶
GIS is a platform-level capability, not a pillar product (§1, §2)¶
Applying the Four-Pillar Architecture Check: geospatial visualization is needed by any pillar that touches maps, weather, aeronautics or hydrology. It therefore belongs in the Common Platform, below the pillar products:
flowchart TB
subgraph CP["Common Platform"]
GIS["GIS services<br/>(OGC APIs: maps, features, processing)"]
REF["Shared referential<br/>(parameters, units, level types)"]
STORE["Shared data services<br/>(spatio-temporal DB, object storage)"]
end
subgraph PP["Pillar Products"]
P1["Pillar 1 product"]
P2["Pillar 2 product"]
P34["Pillars 3 / 4 (future)"]
end
P1 --> GIS
P2 --> GIS
P34 -.-> GIS
GIS --> REF
GIS --> STORE
What the GIS capability provides to every product on top of it:
| Capability | What products get | Standard |
|---|---|---|
| Map rendering | Styled maps of any published layer, any projection | OGC WMS |
| Tiled maps | Fast, cacheable map tiles for web/mobile clients | OGC WMTS / TMS |
| Feature access | Raw vector data (stations, observations, zones) as GeoJSON/GML | OGC WFS |
| Geospatial processing | Server-side computation (e.g. interpolation of station networks) | OGC WPS |
| Time navigation | Every time-aware layer answers TIME= requests |
WMS dimensions |
| Vertical navigation | Model layers answer ELEVATION= (pressure level / altitude) |
WMS dimensions |
| Run selection | Model layers distinguish forecast runs (reference time) | WMS custom dimension |
| Styling | Palettes and symbolization applied server-side at request time | SLD |
Because everything is exposed through OGC standards, any client — our future UI, QGIS, a customer's existing tool — consumes the same services. No customer-specific branches at the GIS layer: customer needs are met with configuration (layers, styles, workspaces), not forks.
Target data landscape (§2)¶
The capability is designed against the real operational inventory, not a toy dataset (details):
- Observations from the GTS network: SYNOP, METAR — dense surface networks; TEMP, AMDAR — sparse upper-air.
- Aeronautical area products with validity periods: SIGMET, AIRMET, GAMET, TAF.
- Imagery: satellite (per satellite/sensor, time series), radar, lightning.
- NWP models: multi-run, multi-validity, multi-level rasters.
- Hydrology: stations, discharge/level series, basins, flood-related layers.
Client applications must navigate this data in time and altitude, and apply palettes at request time — both are native WMS mechanisms in the design (dimensions + SLD), not custom code.
What unlocks several pillars first (§3)¶
The highest-leverage foundation pieces, in build order — this is exactly the sequence the reference implementation followed (guides):
- Shared spatio-temporal database (schemas, roles, PostGIS/TimescaleDB) — everything else reads from it.
- The parameter/unit referential — one table answering "what is this quantity and in which unit is it stored" (ADR-0003). A measurement without a unit is a bug; K vs °C confusion must be structurally impossible.
- The GIS service itself, clustered and configured entirely by code.
- Ingestion conventions (file naming, index tables) so any producer can feed the platform without touching the GIS service.
Part 2 — HOW: lessons, principles, stack¶
§4 Lessons learned (Problem → Root Cause → New Principle)¶
From previous operational experience with GeoServer platforms, validated again during the reference build:
| Problem | Root Cause | New Principle |
|---|---|---|
| GIS server config drifted between environments; nobody could rebuild it | Configuration lived in a UI, applied by hand, stored on a local disk | Nobody configures by hand. All configuration is code (a startup plugin + one ConfigMap); the database is the single source of truth (ADR-0006) |
| Adding/replacing a server instance was a manual, risky operation | Instances were "pets": fixed IPs, local state, hand-tuned | Cattle, not pets. Instances boot from an empty disk, register via DNS discovery, and are disposable (ADR-0005, ADR-0008) |
| Failures surfaced days later as wrong maps, not at deploy time | Components fell back silently on missing preconditions | Fail loud. A missing database, bucket or DNS entry stops startup with an explicit exit code — never a degraded service |
| Same physical quantity stored in different units by different feeds | No shared referential; each decoder chose its own conventions | Units are first-class. Canonical unit per parameter, conversion at ingestion, source unit kept (ADR-0003) |
| Upgrades feared and postponed; versions rotted | Environment not reproducible, no way to test an upgrade safely | Everything retestable. Pinned artifacts, scripted builds, rerunnable test suites per subsystem — an upgrade is a branch + a test run |
| Understanding official specs (WMO/ICAO) from text alone led to wrong implementations | Figures and tables in the standards carry meaning the text does not repeat | Study the source documents, figures included, before modelling data |
These are offered as input to the workshop's initial Engineering Principles.
§5 Architecture principles — GIS stance¶
Position against each relevant workshop principle, with the evidence:
| Workshop principle | GIS stance | Evidence |
|---|---|---|
| API-first | Everything is an OGC API (WMS/WMTS/WFS/WPS); the UI is just another client | All guides test via API only |
| Standards-based interfaces | OGC + SQL + S3 protocol; no proprietary interface anywhere | ADR-0009 |
| Cloud-native but on-premise capable | Runs on plain Kubernetes (validated on k3s); S3 protocol served by self-hostable storage; no cloud-vendor dependency | Guide 3, Guide 4 |
| Containerization | Single custom image built on the official GeoServer image, plugins baked in | Guide 2 |
| Configuration outside application code | One ConfigMap declares layers/styles/mosaics; secrets in K8s Secrets; zero config in the image | ADR-0006 |
| Scalability | Replica count is a number in a manifest; scaling up/down measured with zero request errors | Guide 3 |
| Upgradeability | Ephemeral instances + DB as source of truth ⇒ upgrade = new image tag + rollout | ADR-0005 |
| Observability by design | Honest gap — health probes exist; metrics/tracing/dashboards are the next subsystem to design | Risks |
| Event-driven where appropriate | Deliberately not event-driven at the GIS boundary: ingestion writes files + one DB row; the GIS service discovers data through the DB index, no notification bus needed. Simpler, and one less moving part | ADR-0010 |
| No customer-specific forks | Customer variation = workspaces, layers, styles — configuration, never code | §2 above |
§6 Technology stack (Need → Alternatives → Decision → Rationale)¶
| Need | Alternatives considered | Decision | Rationale |
|---|---|---|---|
| GIS / visualization server | GeoServer 3, GeoServer 2.x, MapServer, thin tile servers (pg_tileserv/martin) | GeoServer 3.0.1 | Only candidate covering the full need (WMS+WFS+WPS+time/elevation dimensions+SLD+plugin ecosystem); v3 = supported line (Tomcat 11/Spring 6/JDK 21); prior team production experience; thin tile servers cover only a fraction of the need |
| Relational + geospatial + time-series | PostgreSQL+PostGIS, +TimescaleDB, dedicated TSDB (Influx…) | PostgreSQL + PostGIS + TimescaleDB (shared, operator-run) | One database engine for geospatial and time-series; hypertables for observation volumes; the platform DB is shared — GIS gets its own schemas/roles (Guide 1) |
| GIS configuration storage | File data dir on shared volume (RWX), DB-backed config | DB-backed (jdbcconfig/jdbcstore) | Shared-filesystem data dirs were the root cause of past drift and locking issues; DB gives one source of truth + instant propagation (measured ~3 s across replicas) |
| Object / file storage | S3-compatible self-hosted (SeaweedFS, MinIO), filesystem | S3 protocol; SeaweedFS for the bench | Rasters as Cloud-Optimized GeoTIFF read directly from S3; tile cache in S3; MinIO rejected (AGPL licensing risk); final production storage = platform-level decision, anything S3-compatible works (ADR-0009) |
| Clustering / session sharing | Fixed-member config, K8s-native DNS discovery | Hazelcast with DNS discovery | Replica count becomes a free variable; UI sessions shared across replicas; no fixed IPs anywhere (ADR-0008) |
| Dense-network interpolation (SYNOP/METAR) | IDW, splines | IDW as WPS rendering transformation | Computed server-side at render time, styled by SLD like any raster (Guide 8) |
| Sparse-network interpolation (TEMP/AMDAR) | IDW, Barnes, RBF, first-guess + corrections | First-guess + corrections | Comparative study on realistic sparse/clustered stations: RMSE 1.36 K vs 4.40 (IDW), 4.93 (Barnes), 6.77 (RBF) (ADR-0013) |
| In-house plugin distribution | Ad-hoc copies, company artifact repository | Company Nexus/Artifactory (to confirm) | Community plugins are multi-JAR bundles; in-house plugins are Maven builds — both need a proper artifact channel (ADR-0007) |
Full decision log: 13 ADRs, all in the lightweight format the agenda proposes.
Part 3 & 4 — Organizing and starting¶
§8 What GIS needs from the initial toolchain¶
- Artifact/container registry — the single hard dependency: the custom GeoServer image and in-house plugin JARs must live somewhere (ties into ADR-0007).
- CI able to run the existing per-subsystem test suites (plain bash + kubectl against a throwaway cluster).
- Nothing exotic: the whole reference stack runs on a single-node k3s.
§9 Sprint 0 — the vertical slice already exists¶
The agenda asks Sprint 0 to demonstrate Source → Ingestion → Messaging/Processing → Storage → API → UI. The reference implementation already covers most of it, end-to-end and tested:
flowchart LR
SRC["Source<br/>(model runs, sat images,<br/>observations, basemaps)"] --> ING["Ingestion<br/>(convert to COG,<br/>write index row)"]
ING --> ST["Storage<br/>(S3 + PostGIS/Timescale)"]
ST --> API["API<br/>(OGC: WMS/WFS/WPS,<br/>time + elevation + runs)"]
API --> UI["UI<br/>(any OGC client)"]
style UI stroke-dasharray: 5 5
Proven today (each item = a rerunnable test suite): database bootstrap, image build, 3-replica cluster with config propagation and shared sessions, S3 tiles + COG rasters, model/satellite mosaic ingestion with time+elevation+run dimensions, observation tables + views, basemaps, server-side interpolation. The full chain was re-deployed from scratch on a second cluster using only the written runbooks, with zero deviation — the strongest durability evidence we have.
Deliberately not built yet (platform-level decisions the workshop should own):
| Gap | Why it waits |
|---|---|
| Messaging/eventing | GIS doesn't need it (ADR-0010); if the platform adopts a bus, ingestion plugs into it upstream |
| Identity / RBAC integration | GIS must federate with the platform IdP — the IdP choice comes first |
| UI / visualization client | Any OGC client works today; the common UI framework choice belongs to the workshop |
| Observability stack | Needs the platform-wide monitoring choice; biggest known gap |
| Data lifecycle / retention | Mechanism is ready to build (time-indexed tables), but the retention owner and policy are not defined yet |
| Real GTS decoders | Ingestion conventions are fixed; decoders (SYNOP/METAR/BUFR/GRIB) are the first real product work |
§10 30/90-day view (GIS slice)¶
- First 30 days: registry + CI in place, reference stack redeployed on the team's environment (the runbooks are written and proven), workspace organization decided against the real inventory (ADR-0002 — deliberately still open), identity integration designed.
- First 90 days: first real GTS decoders feeding the platform, area products with validity periods (SIGMET/AIRMET/GAMET/TAF) as interval-based time layers, request-time palette mechanism generalized, observability subsystem.
Where to see it¶
- Documentation — this site: vision, plain-language explanation, arc42 architecture, 8 runbook guides, 13 ADRs.
- Live demo — a 3-replica cluster serving the full stack (model layers with time/elevation/run navigation, satellite mosaics, observations, interpolated surfaces, cached tiles) is deployed and can be shown during the workshop.