Navigation display: route rail with what lies ahead, and a posted speed limit #14
Labels
No labels
agent
agent:ci
agent:done
agent:failed
agent:needs-input
agent:refined
agent:refining
agent:running
agent:skip
autonomous
driven
local
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
jeroen/cartopolis#14
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Driver mode's chrome (
crates/viberfox/src/systems/driver.rs:914) was specifiedagainst two reference navigation views and covered most of their layout: a
manoeuvre card top-left, the trip numbers as a strip down the right edge, a speed
pill at the bottom centre, and the compass cycle. Comparing it element by element
against those references leaves five real gaps, four of them in the right-hand
strip alone.
1. The right strip was a column of numbers, not a route bar. Both references
build their right-hand side around a vertical rail running the vehicle to the
destination, with what you will pass marked along it in proportion. Ours showed
arrival / distance left / time left and nothing else — it answered how far is
left, never what is left.
2. There was no concept of anything along the route.
Route(
systems/routing.rs:1246) carries points, distance, duration and turn steps.No POIs, no services, no waypoints.
systems/data_layers.rsstreams POIs, butminimal mode (
data_layers.rs:962) disables every layer the moment drivingstarts, so during a drive no POI data was even loaded.
3. No speed limit. Neither reference's speedometer stands alone.
maxspeedappears nowhere in the crate; the nearest thing,
RoadKind::speed_kmh(
routing.rs:223), is a routing cost per road class and is not retained on theroute.
4. No preview of the manoeuvre after the next one. The card showed one turn.
Two turns in quick succession is exactly the case that gets wrong — you take the
first and are already committed to the second before the card changes.
5. No lane guidance, no traffic, no intermediate waypoints. All three appear
in the references. See Out of scope.
Approach
New
crates/viberfox/src/systems/route_ahead.rs— what lies ahead on the route:corridor_query,route_ahead.rs:440),aroundover the route's own polyline thinned to 300 m,fetched once when driver mode starts and cached by the query string (so
narrowing the question is a cache miss by construction, not a stale broad
answer served from disk).
out center) andmaxspeedways(
out geom). Fuel, charging, parking and rest areas become rail markers;maxspeedis sampled onto the route every 25 m, nearest-way-wins(
stamp_limit,route_ahead.rs:603), so a service road beside a trunk cannotclaim the sign.
answers — a rail blank for the first seconds of a drive is blank exactly when it
is looked at.
driver::RouteGeom, now shared rather than rebuilt,so a rail marker at "9.4 km" and "9.4 km to go" mean the same thing.
driver.rsgains the chrome:route_rail(driver.rs:1131) — the strip becomes a real rail under the tripnumbers: vehicle at the foot, destination capped at the top, badges spread to a
minimum gap, overflow counted as "+N", nearest item spelled out underneath,
hover tooltip per badge.
rail_t(driver.rs:1271) — a two-zone scale, not linear. On a 40 km routea linear rail puts everything inside the next 2 km into the bottom 2% of the
track while the empty middle takes nine tenths of the pixels. The near field
gets
RAIL_NEAR_FRACTIONof the track (driver.rs:885) and the break isdrawn as a notch — a scale that changes silently halfway up is a lie about
distance, and distance is all that is read off it.
speed_limit_sign(driver.rs:1287) — the posted limit as a painted road signbeside the speedometer; over the limit turns the speed red, never the sign.
next_step_gap(driver.rs:1112) — a "then" preview inside the manoeuvre cardwhen the following turn is within 300 m.
Acceptance criteria
markers for services, saved places and the destination.
nearest one is named under the rail.
and the scale break is visible rather than implicit.
is absent where it does not — never inferred from road class.
planning a route (the rule
driver.rs's module note already sets forminimal mode).
Verification
cargo check -p viberfox— clean.cargo test -p viberfox --bin viberfox— 183 passed, including 12 new inroute_ahead(maxspeed parsing incl. refusal cases, nearest-way-wins, long-waystamping, corridor thinning, cache keying, response splitting, remark handling,
parking cap) and 2 new in
driver(rail scale monotonicity/endpoints/clamping,"then" preview gating).
cargo clippy -p viberfox --bin viberfox— no new warnings.Visual, headless (no window, per the project's screenshot rule):
Confirmed: rail with badges, destination cap, "+N" overflow,
30limit signbeside the speedometer, "then" chip in the card. Log line
route corridor ready items=16 limited=191.Measurement worth keeping (2026-07-30, the route above, 4.8 km): the first
query returned 45 amenities, 43 of them parking — the rail rendered as an
identical column of
Pbadges with "+38" and the single charging point on theroute was pushed off it. Parking is now asked for only when named, a structure or
a park-and-ride, and capped at a minority share whatever the query returns
(
MAX_PARKING,route_ahead.rs:113). Same route after: 16 items. Recorded indocs/notes/navigation-display.mdalong with the rejected options.Out of scope
no data:
turn:lanesis not in the Shortbread vector tiles the router is builtfrom, so it needs a third corridor query, a per-junction lane model, and — for
the useful version — knowing which lane you are in. Left out rather than
approximated.
congestion and puts a delay chip on it. There is no traffic feed, and adding one
is a data-source decision, not a UI one.
more than two endpoints;
RouteState(navigation.rs:196) hasfromandtoonly.
warning.
a route still costs nothing on the network beyond the solve.
Implemented on this branch in
2c22e48. This ticket is the record of theanalysis and the deliberate exclusions.
Branch:
feat/14-navigation-display-route-rail