Skip to main content

Architecture and Stack Components

Core Runtime

The stack is centered on one FastAPI application and several supporting services:

ComponentRole
FastAPI applicationAPI surface, static frontend hosting, viewer endpoints, auth, config, dataset registry access
MapServer and MapScriptdynamic WMS, WCS, and WFS rendering
MapCachecached GetMap and tile serving via a dedicated Apache based cache service
Celery workerasync execution for heavy jobs such as point-cloud conversion, terrain generation, HySpex bulk ingestion, and cache cleanup
RedisCelery broker and result backend
Mago terrainerCesium terrain generation helper
Shared data volumepersistent datasets, jobs, terrain outputs, server config, extents, thumbnails

Application Layout

The repository separates long-lived logic by concern:

PathPurpose
app.pyapp creation, startup lifecycle, static mounts, router registration
routers/HTTP route groups by domain
core/storage, config, CSW, terrain, mapcache, auth, styles, and state logic
frontend/legacy plain-JS operator UI served from /ui (if directory exists)
frontend-react/React operator UI served from /ui-react (built during Docker image build)
templates/server-rendered HTML shells plus shared viewer assets for Cesium routes
scripts/operational helpers such as MapCache config generation and campaign batch runners
data/example and persistent runtime artifacts in local workflows

Viewer module layout

The built-in browser viewers are split between route-time config generation and static frontend modules:

  • routers/cesium.py assembles VIEWER_CONFIG payloads for the Cesium pages.
  • templates/cesium_hello.html, templates/cesium_ion.html, templates/cesium_wms.html, and templates/cesium_terrain_test.html are thin HTML shells that load external assets.
  • templates/assets/js/cesium-shared.js and templates/assets/js/cesium-basic-viewer.js provide the shared bootstrapping path for the simple Cesium pages.
  • templates/assets/js/cesium-viewer/ contains reusable rich-viewer modules for layer loading, panels, and interactions.
  • templates/assets/js/cesium-terrain-test/ contains terrain-specific bootstrapping and dataset-query logic layered on top of those shared modules.

Main Request Paths

For rendered topology and request-sequence diagrams, see C4 Architecture, System Diagrams, Request Flows, and Workflow Diagrams.

Dataset and OGC traffic

  1. A dataset is uploaded or registered.
  2. Metadata is written to datasets.json and extent footprints are generated.
  3. WMS or WCS requests hit the API and are rendered through MapServer.
  4. When wms_use_mapcache is enabled, GetMap requests can be served by MapCache first, with safe fallback to direct MapServer rendering when MapCache rejects the request.

Async processing

  1. A mutation endpoint submits a Celery task.
  2. A job record is written to jobs.json.
  3. The worker processes the task and updates status and result data.
  4. The frontend polls /jobs and /jobs/{job_id} until the task is terminal.

HySpex campaigns

  1. A parent CSW request is submitted with campaign_id, max_children, and start_position.
  2. The parent job resolves a batch of children and queues child conversion jobs.
  3. The aggregate route /jobs/hyspex-csw-campaigns/{campaign_id} summarizes batch count, child job count, unique children, and the next cursor.
  4. The browser-side sequential runner or helper script repeats this flow batch by batch.

Deployment Model Used in This Repository

The project supports multiple runtime styles, but current active work is centered on the swarm-oriented stack in local-stack.yml.

Important characteristics:

  • the API service is the public edge for /, /ui, /ui-react, /docs, /guide, and all REST and OGC routes
  • Traefik provides HTTP to HTTPS redirect and public host routing in the swarm profile
  • the docs site is baked into the API image and mounted by FastAPI at /guide
  • MapCache and API share the tile cache volume so cache inspection and cleanup routes can operate on the same on-disk state

Persistence Model

Runtime state is split between environment defaults and persisted JSON manifests.

FilePurpose
/data/datasets.jsondataset registry
/data/terrain_datasets.jsonterrain tileset registry
/data/jobs.jsonactive and historical job records
/data/jobs_deleted.jsondeleted job archive
/data/server_config.jsonruntime config that overrides environment defaults

This design makes the stack operationally mutable through the UI and API without rebuilding containers.