Turn-by-Turn Routing

Offline vehicle navigation powered by Valhalla and OpenStreetMap.

7 min read

Overview

GroundWave provides offline turn-by-turn navigation using Valhalla, an open-source routing engine that runs on OpenStreetMap (OSM) data. The routing engine runs as an optional Docker container (groundwave-router) and supports vehicle, bicycle, and pedestrian profiles.

Key design decisions:

  • Fully offline — once OSM PBF data is imported and tiles are built, routing works without any internet connection.
  • Optional container — enabled via Docker Compose profiles (--profile router). Not started by default.
  • Feature toggle gated — routing UI only appears when routing is in FEATURES_ENABLED and the Valhalla engine reports ready status.
  • Server-side proxy — the GroundWave app server proxies route requests to Valhalla, adding authentication and RBAC enforcement.

Setup

1. Enable the Router Container

Start GroundWave with the router profile to include the Valhalla container:

# Start with routing enabled
docker compose --profile router up -d

# Or add to your existing docker-compose command
docker compose -f docker-compose.yml --profile router up -d

2. Import OSM Data

Download an OpenStreetMap PBF extract for your region from Geofabrik or Protomaps, then import it via the Admin Dashboard.

  1. Open the Admin Dashboard and navigate to the Routing tab.
  2. Click Import PBF and select your .osm.pbf file.
  3. Wait for the upload and tile building to complete. The status will show progress.
  4. Once tiles are built, the routing engine is ready. Routes can be requested immediately.

PBF file size determines import time and disk usage. A state-level extract (e.g., Colorado, ~300 MB) takes a few minutes. A country-level extract can take longer. The Nginx proxy allows uploads up to 5 GB with a 30-minute timeout.

3. Enable the Feature Toggle

Add routing to the FEATURES_ENABLED environment variable:

# .env or docker-compose.yml environment
FEATURES_ENABLED=chat,markers,files,overlays,voice,video,routing

Vehicle Profiles

Three routing profiles are available, each optimized for different travel modes:

  • Auto — vehicle routing using roads, highways, and motorways. Respects turn restrictions, one-way streets, and road classifications.
  • Bicycle — cycling routes preferring bike lanes, paths, and low-traffic roads. Avoids highways and motorways.
  • Pedestrian — walking routes using sidewalks, footpaths, trails, and crosswalks. Can traverse pedestrian-only areas.

The profile can be switched at any time from the RoutePanel. Changing profiles automatically re-requests the route with the new travel mode.

User Interface

"Route to" Actions

"Route to" buttons appear alongside "Navigate to" throughout the interface:

  • User markers — route to another team member's position
  • Markers — route to a marker (uses centroid for polygons/lines)
  • Roster panel — route to a user from the roster list

RoutePanel

The RoutePanel is a slide-out panel that appears when a route is active. It contains:

  • Profile selector — switch between auto, bicycle, and pedestrian
  • Route summary — total distance and estimated travel time
  • Turn-by-turn instructions — step-by-step maneuver list with distance to each turn
  • Cancel route — clear the active route

ManeuverHUD

While a route is active, a floating ManeuverHUD overlay appears on the map showing the next upcoming maneuver — direction, street name, and distance to the turn. The HUD automatically advances as you progress along the route.

Route Layer

The route is rendered on the map as a blue route line with a darker casing for contrast. Start and end markers indicate the route endpoints. The line follows the actual road geometry returned by Valhalla.

Auto-Reroute

When your GPS position deviates more than 50 meters from the route line, the system automatically requests a new route from your current position to the original destination. This ensures the instructions stay relevant even if you take a different path.

REST API

Method Path Auth Description
POST /api/route Any authenticated Request a route between two points
GET /api/route/status Any authenticated Check routing engine status (ready, building, unavailable)
POST /api/route/admin/import Admin Upload OSM PBF file for tile building
GET /api/route/admin/status Admin Detailed import/tile build status
DELETE /api/route/admin/data Admin Delete imported routing data

Permissions

Capability Observer Operator Admin
Request routes Yes Yes Yes
View routing status Yes Yes Yes
Import PBF data No No Yes
Delete routing data No No Yes

Admin Dashboard

The Routing tab in the Admin Dashboard provides data management:

  • Status indicator — shows whether the Valhalla engine is ready, building tiles, or unavailable
  • Import PBF — upload an OpenStreetMap PBF extract
  • Build progress — real-time status during tile building
  • Delete data — remove imported routing data and tiles

The Valhalla container uses an entrypoint script with MD5-based skip logic — if the same PBF file is re-imported, tile building is skipped automatically. The container restarts after a PBF import to load the new tiles.