Frontend architecture
The web app is a single-page React application in Frontend/. It has no router: the workspace is one screen, and help pages open as dialogs or drawers.
| Concern | Library |
|---|---|
| UI framework | React 19 · TypeScript (strict) · Vite 8 |
| Components | Mantine 9 (core, dropzone, modals, notifications) · Tabler icons |
| 3D | three.js 0.186 · React Three Fiber 9 · drei 10 · postprocessing (N8AO, SMAA) · three-custom-shader-material · camera-controls |
| State | zustand 5 |
| Workers | comlink |
| Charts | ECharts 6 |
| Geo | geotiff.js · proj4 · d3-contour |
| Files | fflate (zip) · idb-keyval (IndexedDB) |
| Tests | Vitest · Testing Library · Playwright + axe-core |
The production build is split into three, charts, geo and mantine chunks, and uses a relative base: './' so it works from any path.
Source layout
Section titled “Source layout”DirectoryFrontend/
Directoryapi/ Vercel serverless functions (hf-space.js, overpass.js)
- …
Directoryserver/ Node production server + proxy (serve.mjs, overpass.mjs)
- …
Directorypublic/ logo, bundled sample scene
- …
Directorysrc/
Directoryapi/ inference providers
- provider.ts InferenceProvider interface
- registry.ts provider selection
Directorygradio/ GradioSpaceProvider, output + status parsing
- …
- errors.ts typed errors
Directorystore/ zustand stores: scene, camera, view, ui, settings, anchor, tool, usecases
- …
Directoryfeatures/
Directoryshell/ header, menus, shortcuts, status bar, backend status
- …
Directoryinput/ project panel (upload, GSD, TTA)
- …
Directoryprocessing/ run orchestration + overlay
- …
Directoryviewport/ canvas, cameras, overlays, scene graph
- …
Directoryinspector/ Layers and Info tabs
- …
Directoryvalidation/ reference metrics, charts, HTML report
- …
Directoryanchoring/ DEM anchoring + product chip
- …
Directorybasemap/ · osm/ · poi/ surroundings layers
- …
Directoryusecases/ flood and telecom scenarios
- …
Directoryfiles/ open, save project, exports
- …
Directoryhelp/ docs drawer, shortcuts, model info, about
- …
Directoryworkers/ terrain.worker.ts, analysis.worker.ts
- …
Directorytheme/ Mantine theme, CSS tokens, colormaps, class colours
- …
Inference providers
Section titled “Inference providers”classDiagram
class InferenceProvider {
<<interface>>
+id
+capabilities
+status(onChange)
+predict(req, onProgress, signal)
+modelInfo()
}
class GradioSpaceProvider {
+spaceId
upload, call/predict, SSE
}
class MockProvider {
offline demo
}
InferenceProvider <|.. GradioSpaceProvider
InferenceProvider <|.. MockProvider
registry.ts keeps one provider instance per configuration, so the Space connection is reused across runs. The provider can be chosen in Settings (Hugging Face Space (live model) or Offline demo).
Data flow
Section titled “Data flow”flowchart LR F[File drop] --> I[Read image<br/>geotiff.js · GSD · CRS] I --> P[Provider.predict] P --> R[ndsm_m.npy + meta.json<br/>+ seg.png + objects.json] R --> S[(scene store)] S --> W1[terrain.worker<br/>mesh LOD] S --> W2[analysis.worker<br/>slope · stats · flood] W1 --> V[R3F viewport<br/>custom shader drape] W2 --> UI[Inspector · status bar · scenarios] S --> A[anchoring<br/>Terrarium / DEM file] A --> S
- Mesh building and analysis run in Web Workers via comlink, keeping the UI responsive on large scenes.
- Drape layers (optical, height tint, hillshade, slope, classes, reference, error) are computed in a custom shader material on one mesh, so switching layers never rebuilds geometry.
- Post-processing (ambient occlusion, SMAA) turns itself off when the frame rate drops.
- Settings persist to
localStorage(dw.settings,dw.color-scheme). Recent projects, with thumbnails, go to IndexedDB.
Scripts
Section titled “Scripts”npm run dev # Vite dev server + proxiesnpm run build # typecheck + production buildnpm run serve # node server/serve.mjsnpm run test # Vitestnpm run e2e # Playwright (+ axe accessibility checks)npm run lint # ESLintnpm run cache-dem # pre-fetch DEM tiles for the bundled sample