Skip to content

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.

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 GameWidget with the floor map
  • Floor bar: Current floor name and coordinates
  • Bottom bar: BLE toggle, Navigate/Stop button, "Center on me" button

Lifecycle

  1. Build navigation graph from bundle floors
  2. Load beacons into the positioning engine
  3. Load the first floor map into the Flame game
  4. User selects a floor → _loadFloor(index) updates the game
  5. User selects a POI → starts navigation

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 floor
  • projectOntoNearestEdge(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

MethodDescription
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
  1. User selects a POI destination from the chips
  2. App requires a position fix (at least one BLE beacon detected)
  3. Finds the nearest graph node to the current position
  4. Finds the nearest graph node to the destination beacon
  5. Runs pathfinding:
    • Server pathfinding (if connected): POST /navigation/pathfind
    • Local pathfinding (offline): NavigationGraph.findShortestPath()
  6. Draws the path on the map via NavigationGame.drawNavigationPath()
  7. During navigation, position updates every 2 seconds:
    • BLE scan → PositioningEngine.calculatePosition()
    • Project position onto nearest graph edge
    • Update player arrow on the map