Architecture
"/home/yossef/notes/git/projects/maplibra/Architecture.md"
path: maplibra/Architecture.md
- **fileName**: Architecture
- **Created on**: 2026-06-16 00:48:42
Architecture
Purpose: High-level system design of the indoor navigation stack.
Related: ./Home.md, ./Project Map.md, ./modules/Bootstrap System.md, ./modules/MVF Loading.md, ./modules/Asset System.md
System Layers
┌─────────────────────────────────────────────────────────────────────┐
│ UI Layer (index.html, src/ui/) │
│ - Search, floor controls, theme toggle, settings menu, legend │
│ - Navigation panels, route summary, drop-mode UI │
├─────────────────────────────────────────────────────────────────────┤
│ App Shell (script.js) │
│ - Startup orchestration, MVF loading, drop screen │
│ - Global window.InGuide API, cross-module wiring │
├─────────────────────────────────────────────────────────────────────┤
│ Bootstrap Layer (src/bootstrap/) │
│ - Shell (theme, errors, viewport, service worker) │
│ - Map creation (Mapbox GL) │
│ - Data loading (app handle, asset providers) │
│ - Lazy routing, search, debug initialization │
│ - Performance budgets, rollout telemetry │
├─────────────────────────────────────────────────────────────────────┤
│ App Services (src/app/) │
│ - Floor data manager (load, cache, render, memory pressure) │
│ - Asset providers (ZIP, network, overlay, hybrid) │
│ - Derived asset cache (IndexedDB, meta index, hash keys) │
│ - Android bridge (WebView floor sync, native controls) │
│ - MVF loader (ZIP parsing, Web Worker, manifest processing) │
│ - Startup task queue (deferred work, idle scheduling) │
├─────────────────────────────────────────────────────────────────────┤
│ Layer Management (src/layer-manager.js, src/layers/) │
│ - Base layers (building shell, labels, style layers) │
│ - Debug overlays (wall, stairs, walkable, kinds nodes) │
│ - Visibility manager (floor filter, zoom threshold) │
│ - Theme reapplication (color swaps without rebuild) │
├─────────────────────────────────────────────────────────────────────┤
│ Pathfinding Controller (src/pathfinding-controller.js) │
│ - Facade delegating to 3 sub-controllers + 20+ mixins │
│ - RoutingController: graph loading, A* computation │
│ - LocationController: markers, selection, drop mode │
│ - NavigationController: GPS, follow camera, UI panel │
├─────────────────────────────────────────────────────────────────────┤
│ Routing Engine (src/pathfinding/) │
│ - JS A* + optional WASM acceleration (identical logic) │
│ - Multi-candidate snapping, route smoothing, outdoor stitching │
│ - Graph formats: JSON, binary, slices │
├─────────────────────────────────────────────────────────────────────┤
│ Path Renderer (src/path-renderer/) │
│ - GeoJSON LineString → map layers per floor │
│ - Animation, metrics, style updates │
├─────────────────────────────────────────────────────────────────────┤
│ Data Layer (MVF bundle) │
│ - Geometry per floor, walkable polygons, wall/object class │
│ - Connections (stairs/elevators/doors), annotations, locations │
│ - Pre-built routing graphs (JSON/binary/slices) │
│ - Debug node GeoJSON overlays │
└─────────────────────────────────────────────────────────────────────┘
Data Flow
- MVF Load → ZIP parsed by Web Worker → floors, geometry, walkable areas cached
- Graph Load → Pre-built graph (JSON/binary/slices) loaded into memory
- Floor Render → Fast raw render → prepared worker data → smooth swap
- User Selection → Click/tap on map → snapped to nearest graph node via doors/rooms
- Routing → Multi-candidate A* finds shortest path through graph
- Outdoor Stitching → If needed, fetch nearest road + street route, stitch to indoor
- Smoothing → Raw node path → walkable straightening + shortcut + Bezier curves → human-like polyline
- Rendering → GeoJSON LineString features displayed per floor on MapLibre
Key Design Decisions
- Deferred bootstrap — routing, search, and debug layers load lazily after first floor render (./decisions/Deferred Bootstrap.md)
- Dual routing engine — JS fallback + optional WASM acceleration with identical logic (./decisions/Dual Routing Engine.md)
- Sampling-based wall checks instead of geometric line-polygon intersection (./decisions/Sampling vs Intersection.md)
- Multi-candidate snapping — user selection fans out to multiple graph node candidates, A* tried for each pair
- Offline graph build — dense point grid generated ahead of time, not computed at runtime
- Per-floor isolation — walkable areas, blockers, and graph nodes are indexed by floor ID
- Post-A straightening* — shallow grid staircases are cleaned up after A* only when the direct segment validates walkable (./decisions/Post-A-Star Staircase Straightening.md)
- Layered asset providers — ZIP, network, overlay, hybrid providers compose to serve data from multiple sources
- IndexedDB derived asset cache — routing graphs and MVF data cached with SHA-256 hash keys and schema versioning (./decisions/Caching Strategy.md)
- Fast render + prepared swap — raw geometry paints immediately, then worker-prepared data swaps in for better quality
Component Boundaries
| Component | Input | Output |
|---|---|---|
| MVF Worker | ZIP blob | Parsed GeoJSON + metadata |
| Graph Builder | walkable_nodes + geometry | graph.json + binary assets |
| Snapping | User coords + floorId | Ranked snap candidates |
| A* Engine | Start/goal node IDs | Ordered node ID path |
| Smoothing | Raw node coords | Straighter validated coordinate array |
| Renderer | Smoothed GeoJSON features | Map layers |
| Floor Data Manager | floorId + MVF loader | Cached floor data + rendered layers |
| Asset Provider | Path string | JSON, text, blob, buffer, or object URL |
| Outdoor Router | Start/end coords | Street route coords or nearest road |
continue:[[]]
before:[[]]