Appearance
Navigation System
The navigation system is the core feature of the mobile app. It combines a graph-based pathfinding engine with real-time BLE positioning and a Flame-based map renderer.
Navigation Screen
File: mobile/lib/screens/navigation_screen.dart
The main UI screen that coordinates all navigation components:
UI Layout
- Top bar: Location name, floor selector menu
- POI chips: Horizontal list of Point of Interest beacons for destination selection
- Map area: Full-screen Flame
GameWidgetwith the floor map - Floor bar: Current floor name and coordinates
- Bottom bar: BLE toggle, Navigate/Stop button, "Center on me" button
Lifecycle
- Build navigation graph from bundle floors
- Load beacons into the positioning engine
- Load the first floor map into the Flame game
- User selects a floor →
_loadFloor(index)updates the game - User selects a POI → starts navigation
Navigation Graph
File: mobile/lib/core/navigation_graph.dart
An undirected weighted graph built from the floor nodes and edges in the navigation bundle.
Building
buildFromFloors(floors) processes all NavigationFloor data:
- Adds all nodes to a lookup map
- Builds an adjacency list with bidirectional edges and weights
Pathfinding
findShortestPath(startId, endId) implements Dijkstra's algorithm using a HeapPriorityQueue (min-heap). Returns a PathResult with the ordered list of nodes and total weight.
Spatial Queries
findNearestNode(x, y, {floorId})— Finds the closest node to a point using Euclidean distance, optionally filtered by floorprojectOntoNearestEdge(px, py, {floorId})— Projects a point onto the nearest graph edge segment (used during live navigation to snap the user position to the path)
Map Renderer
File: mobile/lib/game/navigation_game.dart
A Flame game that renders the indoor map with interactive pan/zoom.
Components
- Floor map image: Background sprite loaded from cached PNG
- Nodes: Blue circles at graph node positions
- Edges: Green translucent lines between connected nodes
- Navigation path: Blue highlighted lines along the computed route
- Destination pin: Red marker at the target node
- Player arrow: Directional arrow showing current position and compass heading
Controls
- Pinch zoom: Scale the map within defined bounds
- Pan: Drag to scroll the map
- Center:
centerOn(x, y)moves the camera to a specific point
Key Methods
| Method | Description |
|---|---|
loadFloorMap(navFloor, imagePath) | Load a floor's map image and draw its graph |
drawNavigationPath(path) | Highlight the route with blue lines and a destination pin |
updatePlayerPosition(x, y, angle) | Move and rotate the player arrow |
centerOn(x, y) | Center the camera on a point |
Navigation Flow
- User selects a POI destination from the chips
- App requires a position fix (at least one BLE beacon detected)
- Finds the nearest graph node to the current position
- Finds the nearest graph node to the destination beacon
- Runs pathfinding:
- Server pathfinding (if connected):
POST /navigation/pathfind - Local pathfinding (offline):
NavigationGraph.findShortestPath()
- Server pathfinding (if connected):
- Draws the path on the map via
NavigationGame.drawNavigationPath() - During navigation, position updates every 2 seconds:
- BLE scan →
PositioningEngine.calculatePosition() - Project position onto nearest graph edge
- Update player arrow on the map
- BLE scan →