GpxCueEnricher: tier-0 cues from the GPX itself #63

Open
opened 2026-09-01 17:35:44 +02:00 by robert · 0 comments
robert commented 2026-09-01 17:35:44 +02:00 (Migrated from git.butzei.de)

Goal

Read the cue sheet that is already in the file. D7 reasoned from "komoot GPX carries geometry only" (true) to treating every GPX as geometry-only (false). RideWithGPS, cycle.travel, Garmin and Strava exports frequently ship turn cues already: <rtept> and <wpt> entries with turn types and street names, plus gpxx / Garmin <extensions>.

Where they exist, these cues are exact, offline, instant, and need neither BRouter nor a network call. This becomes tier 0 of the enrichment chain, ahead of BRouterEnricher.

It is also what makes D6's "the route source is pluggable" claim actually pay off. Without it, pluggability costs three backends and buys nothing over komoot-only.

Acceptance criteria

  • GpxCueEnricher implements CueSheetEnricher and is tried first in the chain
  • <rtept> route points with <name> / <cmt> / <desc> / <type> parsed into cues
  • <wpt> waypoints recognised as cues where the file uses them that way, and as points of interest where it does not
  • Garmin gpxx:RoutePointExtension and <extensions> turn data parsed
  • Source vocabularies mapped onto the canonical direction enum from #26, in the same mapping layer as the other backends
  • Cues matched back onto the simplified polyline by position, so indices line up with what #31 snaps against
  • Reports "no cues present" cleanly and hands off to tier 1 - a geometry-only komoot export must fall through, not fail
  • Cue confidence reported as NAV_CUE_CONFIDENCE = 2 (from the file)
  • Fixtures from a real RideWithGPS and a real cycle.travel export, alongside the komoot ones in #38

Files

  • companion/.../route/enrich/GpxCueEnricher.kt
  • shared/ - no contract change; NAV_CUE_CONFIDENCE already exists in docs/PROTOCOL.md

Notes

See D26. Tier 0 is the cheapest good enrichment in the chain and it was missing entirely.

Update — 2026-09-03: what "read the cues" actually means (D59)

Nine BRouter encodings verified live (timode 1–9; 8 and 9 exist in shipping code but are missing
from the AIDL docs) plus three foreign alphabets. Minimum parser surface: cues in <trkpt>,
<rte>/<rtept>, <wpt>, vendor namespaces (locus:rtePointAction integer codes,
om:oruxmapsextensions numeric icon ids, brouter:*), and XML comments (timode 4 — a
conforming parser discards these by default). Alignment keys exist in only two encodings
(<offset>; RWGPS i); everything else needs nearest-point association with out-and-back
ambiguity. Vocabulary normalisation onto D8's enum must cover BRouter's 19 mnemonics including
BL (beeline — not a turn, must not render as one), OFFR, EL/ER, both u-turn flavours.
Fixtures ti_1.gpx–ti_9.gpx are already generated from live BRouter 1.7.10.

## Goal Read the cue sheet that is already in the file. `D7` reasoned from "komoot GPX carries geometry only" (true) to treating every GPX as geometry-only (false). RideWithGPS, cycle.travel, Garmin and Strava exports frequently ship turn cues already: `<rtept>` and `<wpt>` entries with turn types and street names, plus `gpxx` / Garmin `<extensions>`. Where they exist, these cues are exact, offline, instant, and need neither BRouter nor a network call. This becomes **tier 0** of the enrichment chain, ahead of `BRouterEnricher`. It is also what makes D6's "the route source is pluggable" claim actually pay off. Without it, pluggability costs three backends and buys nothing over komoot-only. ## Acceptance criteria - [ ] `GpxCueEnricher` implements `CueSheetEnricher` and is tried first in the chain - [ ] `<rtept>` route points with `<name>` / `<cmt>` / `<desc>` / `<type>` parsed into cues - [ ] `<wpt>` waypoints recognised as cues where the file uses them that way, and as points of interest where it does not - [ ] Garmin `gpxx:RoutePointExtension` and `<extensions>` turn data parsed - [ ] Source vocabularies mapped onto the canonical direction enum from #26, in the same mapping layer as the other backends - [ ] Cues matched back onto the simplified polyline by position, so indices line up with what #31 snaps against - [ ] **Reports "no cues present" cleanly** and hands off to tier 1 - a geometry-only komoot export must fall through, not fail - [ ] Cue confidence reported as `NAV_CUE_CONFIDENCE = 2` (from the file) - [ ] Fixtures from a real RideWithGPS and a real cycle.travel export, alongside the komoot ones in #38 ## Files - `companion/.../route/enrich/GpxCueEnricher.kt` - `shared/` - no contract change; `NAV_CUE_CONFIDENCE` already exists in docs/PROTOCOL.md ## Notes See D26. Tier 0 is the cheapest good enrichment in the chain and it was missing entirely. ## Update — 2026-09-03: what "read the cues" actually means (D59) Nine BRouter encodings verified live (`timode` 1–9; 8 and 9 exist in shipping code but are missing from the AIDL docs) plus three foreign alphabets. Minimum parser surface: cues in `<trkpt>`, `<rte>/<rtept>`, `<wpt>`, vendor namespaces (`locus:rtePointAction` integer codes, `om:oruxmapsextensions` numeric icon ids, `brouter:*`), and **XML comments** (timode 4 — a conforming parser discards these by default). Alignment keys exist in only two encodings (`<offset>`; RWGPS `i`); everything else needs nearest-point association with out-and-back ambiguity. Vocabulary normalisation onto D8's enum must cover BRouter's 19 mnemonics including `BL` (beeline — not a turn, must not render as one), `OFFR`, `EL`/`ER`, both u-turn flavours. Fixtures `ti_1.gpx`–`ti_9.gpx` are already generated from live BRouter 1.7.10.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
robert/PedalPebble#63
No description provided.