Viewport selection, polyline clip, project and simplify #40

Open
opened 2026-08-31 17:14:51 +02:00 by robert · 0 comments
robert commented 2026-08-31 17:14:51 +02:00 (Migrated from git.butzei.de)

Goal

Prepare a map frame small enough to send once a second.

Acceptance criteria

  • Heading-up viewport, roughly 200 m across, centred on the rider
  • Route polyline clipped to the viewport
  • Projected to 200x228 screen pixels
  • Douglas-Peucker simplification to the pixel grid, so sub-pixel detail is never sent
  • Quantised to int16 pairs
  • Upcoming cue positions included as markers
  • Typical frame stays around 1 KB

Files

  • companion/.../map/ViewportRenderer.kt

Notes

Vector, not raster: a 200x228 bitmap is roughly 45 KB against an 8000 byte AppMessage cap and a few KB/s of Bluetooth.

Update — 2026-09-02: send geometry, not screen coordinates

The phone no longer projects (D39). It sends a slice of the route in a stable metric frame and the
watch projects it.

Three problems this fixes: the phone was never told the watch's screen geometry; zoom and re-centre
were Bluetooth round-trips, making NFR-P6 unsatisfiable; and a dropout froze the map.

  • Emit MAP_ANCHOR_LAT / MAP_ANCHOR_LON plus int16 decimetre offsets east/north of the
    anchor — ±3.2 km of range, more than any viewport offered
  • Clip and Douglas–Peucker simplify in the metric frame, to a tolerance derived from
    SCREEN_W/SCREEN_H, not to a hard-coded 200×228 pixel grid
  • Slices emitted on exhaustion — when the rider nears the edge of the sent slice, order once
    per few hundred metres — not at 1 Hz
  • Upcoming cues as MAP_CUES, rider position as MAP_POS, in the same frame
  • Typical slice stays around 1 KB

This is what takes the map off the critical path for bandwidth: link traffic for it drops by roughly
an order of magnitude.

## Goal Prepare a map frame small enough to send once a second. ## Acceptance criteria - [ ] Heading-up viewport, roughly 200 m across, centred on the rider - [ ] Route polyline clipped to the viewport - [ ] Projected to 200x228 screen pixels - [ ] Douglas-Peucker simplification to the pixel grid, so sub-pixel detail is never sent - [ ] Quantised to `int16` pairs - [ ] Upcoming cue positions included as markers - [ ] Typical frame stays around 1 KB ## Files - `companion/.../map/ViewportRenderer.kt` ## Notes Vector, not raster: a 200x228 bitmap is roughly 45 KB against an 8000 byte AppMessage cap and a few KB/s of Bluetooth. ## Update — 2026-09-02: send geometry, not screen coordinates The phone no longer projects (D39). It sends a **slice of the route in a stable metric frame** and the watch projects it. Three problems this fixes: the phone was never told the watch's screen geometry; zoom and re-centre were Bluetooth round-trips, making NFR-P6 unsatisfiable; and a dropout froze the map. - [ ] Emit `MAP_ANCHOR_LAT` / `MAP_ANCHOR_LON` plus `int16` **decimetre** offsets east/north of the anchor — ±3.2 km of range, more than any viewport offered - [ ] Clip and Douglas–Peucker simplify **in the metric frame**, to a tolerance derived from `SCREEN_W`/`SCREEN_H`, not to a hard-coded 200×228 pixel grid - [ ] Slices emitted **on exhaustion** — when the rider nears the edge of the sent slice, order once per few hundred metres — not at 1 Hz - [ ] Upcoming cues as `MAP_CUES`, rider position as `MAP_POS`, in the same frame - [ ] Typical slice stays around 1 KB This is what takes the map off the critical path for bandwidth: link traffic for it drops by roughly an order of magnitude.
Sign in to join this conversation.
No description provided.