Routing Tool
The Routing Tool adds turn-by-turn navigation, route simulation, speed camera alerts, nearby POI search, address geocoding, basemap switching, route saving, and real-time location sharing — all powered by the open-source Valhalla routing engine.
A companion Loop Route Generator lets you compute circular routes that start and end at the same point, with a preferred compass direction and target distance.
Opening the tool
Click the routing toolbar button (two circles connected by a curved line) to open the Routing panel in the left sidebar.
Setting waypoints
Address search (geocoder)
Type any address or place name into the search bar at the top of the routing panel. Results are fetched from the Photon/OSM geocoder. Click a result to fly to it on the map, then use the action chips below the search bar to assign it:
| Chip | Effect |
|---|---|
| Set Start | Use as the route start point |
| Set End | Use as the route end point |
| Add Waypoint | Insert as an intermediate stop |
| Fly to | Just fly the camera there — no waypoint added |
Map click
With the routing panel open, click directly on the Cesium globe to pick start, end, or waypoint positions. The active pick target is shown in the panel header.
Waypoint list
Intermediate waypoints appear in a list below the start/end displays. Each row has a ✕ button to remove that stop. Drag the ⠿ handle to reorder waypoints.
Route options
Expand the Options section to configure:
| Option | Description |
|---|---|
| Costing | Travel mode: motorcycle (default), auto, bicycle, pedestrian, truck… |
| Units | km or miles |
| Alternates | 0–3 alternative routes shown as dimmed lines |
| Avoid tolls / highways / ferries | Toggle per route |
| Top speed | Cap vehicle speed for time estimation |
Computing a route
With at least a start and end point set, click Get Route. The route line appears on the map in teal. The result panel shows total distance and duration.
If alternate routes were requested, click any alternate line to promote it to the primary route.
Route simulation
After a route is computed, the Simulate button starts a virtual drive along the route:
- A vehicle marker follows the route at configurable playback speed
- Turn instructions update in the panel as maneuvers approach
- The camera follows the vehicle automatically (configurable below)
Simulation controls
| Control | Description |
|---|---|
| Speed slider | Playback speed multiplier (1× to 20×) |
| ▶ / ⏸ | Play / pause |
| ⏹ | Stop and reset |
| ↺ Recenter | Snap the camera overhead above the vehicle |
Smart camera (follow mode)
The camera stays behind the vehicle and tilts to show the road ahead. Three sliders in the Camera section control the view:
| Slider | Description |
|---|---|
| Min altitude | Lowest camera height (metres) |
| Max altitude | Highest camera height (metres) |
| Back offset | How far behind the vehicle the camera sits |
Each slider has a ceiling input (the small number field to its right) to set the slider's maximum range.
Clicking ↺ Recenter during simulation switches to a top-down overhead view at 2 000 m, showing roughly a 1 km² area around the vehicle.
Speed camera alerts
Speed camera locations are fetched automatically from OpenStreetMap when a route is computed. Cameras appear as red SVG pins on the map.
A yellow ⚠ Speed camera ahead banner appears in the simulation panel when the vehicle comes within 300 m of a camera. The banner clears once the camera is passed.
Camera data is cached in Redis for 24 hours per 1°×1° grid cell.
Nearby POI search
Click the search+ toolbar button to open the Nearby POI Search panel.
- Category — choose from Gas Station, Camping, Grocery, Restaurant, Parking, Hotel, Hospital, Pharmacy
- Origin — where to centre the search:
- Route start — uses the set start point
- Route end — uses the set end point
- Map center — uses the current Cesium camera position
- Radius (km) — search radius, 1–100 km (default 20)
- Click Search
Results appear as coloured emoji pins on the map and as a list below. Each result has a + WP button that adds it as a route waypoint.
POI data is cached in Redis for 6 hours per category/location/radius bucket.
Route Manager
Click the list toolbar button to open the Route Manager panel.
Saving a route
After computing a route, enter a name (and optional description) in the Route Manager panel and click Save current route. Routes are stored in PostGIS and are private to your account.
Route Manager requires a PostgreSQL/PostGIS database. If
POSTGRES_HOSTis not configured the panel is still visible but save/load will return an error.
Loading a route
Saved routes appear in the list. Click a route card to load it — the waypoints and route line are restored exactly as saved.
Exporting a route
Each route card has two export buttons:
| Format | Description |
|---|---|
| GPX | Standard GPS exchange format, compatible with Garmin, OsmAnd, etc. |
| GeoJSON | LineString geometry, importable into QGIS, Mapbox, etc. |
Basemap selector
Click the globe toolbar button to open the Basemap panel. Three options are available:
| Basemap | Description |
|---|---|
| Cesium World | Default Cesium World Imagery (Bing) |
| OpenStreetMap | OSM tile layer |
| ESRI Topo | ESRI World Topo Map |
The selected basemap persists across browser sessions via localStorage.
Location sharing
Click the person+pin toolbar button to open the Location Sharing panel.
- Enter a Group ID — any shared string, e.g.
trip-norway-2025 - Enter Your name — identifies you to other group members
- Click Start sharing
Your position is published every 10 seconds. Other group members appear as labelled pins on the map with their initials in a deterministic colour. The member list shows each person's age (seconds since last update) and speed.
Click Fly on any member row to jump the camera to their location.
Positions expire automatically after 5 minutes of inactivity.
Loop Route Generator
Click the circular-arrow toolbar button to open the Loop Route Generator panel.
The loop route tool generates a circular route — a ride that starts and ends at the same point — using Valhalla's isochrone reachability engine to find a good turnaround point in your chosen direction.
Parameters
| Parameter | Description |
|---|---|
| Start from | Map centre (default) uses the current Cesium camera centre; GPS location uses the device fix when available |
| Distance (km) | Target total route length, 10–2 000 km |
| Direction | Preferred outbound heading: N, NE, E, SE, S, SW, W, NW |
| Avg speed (km/h) | Expected average speed used to size the isochrone ring (20–120, default 50). Lower values produce a tighter ring closer to the start; higher values explore further out. |
| Waypoints | Number of intermediate perimeter stops (2–8, default 6). More waypoints = shorter individual legs, less chance of a long out-and-back detour. |
| Reach depth | Percentile of the per-sector distance distribution used to place each waypoint (0.10–1.00, default 0.70). At 1.0 the furthest reachable point in each direction is chosen; lower values pull waypoints back from geographic dead-ends (fjord tips, valley ends) that force out-and-back riding. 0.70 is a good default for rugged terrain. |
Two toggles in the panel control Valhalla routing behaviour:
| Toggle | Description |
|---|---|
| Avoid backtracking | Marks intermediate waypoints as Valhalla type: "through" — the engine passes through without stopping or U-turning, reducing same-road overlap. |
| Force departure heading | Adds a heading constraint on the start location so the route departs in the requested compass direction (±45°). |
Routing options (costing model, highway/trail/ferry preference, top speed, etc.) are shared with the main Routing Tool — adjust them there and they apply here too.
How it works
The loop generator uses Valhalla's isochrone engine to define a reachable ring at the right distance, then places waypoints spread evenly around the compass:
- The equivalent circle radius is computed as
r = distance / (2π). Two time-based isochrone contours are requested usingavg_speed_kmhas the reference: inner atr / (avg × 1.2) × 60min and outer atr / (avg × 0.8) × 60min — a ±20 % speed band. The outer ring shows where you can realistically reach. - The compass is divided into
Nequal sectors starting at the requested direction. For each sector, isochrone boundary points are collected, sorted by distance from start, and the point at the reach depth percentile is chosen. This guarantees waypoints are spread in genuinely different directions (N/E/S/W quadrants) rather than clustering along a single valley. - Valhalla routes start → wp1 → wp2 → … → wpN → start with
type: "through"intermediate stops and an optional departure heading — a closed loop that crosses distinct road corridors.
Both isochrone rings remain visible on the map as translucent blue guide polygons. Numbered pins mark each intermediate waypoint.
Tuning for rugged terrain
In areas with fjords or mountain ranges there are topological bottlenecks — a single bridge or valley road — that cannot be avoided by any algorithm. The following adjustments help:
- Lower reach depth (0.40–0.60): avoids placing waypoints at the tips of fjord arms or valley dead-ends
- More waypoints (6–8): shortens each individual leg, reducing exposure to single-road corridors
- Lower avg speed: produces a larger isochrone (more candidate points per sector), giving the algorithm more road options to choose from
After computing
- The status line shows the actual distance and estimated duration.
- Click ↗ Add to Route to send all waypoints to the main Routing Tool (where you can inspect turn-by-turn instructions, simulate the ride, or adjust individual stops).
- Click 🔖 Save to persist the loop to your Route Manager account.
Tile coverage (adding countries)
By default Valhalla is built with Norwegian OSM data. To route through additional countries (e.g. for a Norway → Italy trip):
- Edit
valhalla-tiles.conf— uncomment the countries you need - Run the rebuild script:
./scripts/valhalla-rebuild.sh
The script downloads and builds tiles for all active regions (Norway → Italy requires Sweden, Denmark, Germany, Austria, Italy — roughly 45–90 min build time), then prints the command to lock the tiles in for future restarts.