ADR 018: Wear OS track map from SailEver tiles¶
Date: 2026-10-30 Status: accepted (owner, plan of 2026-10-27)
Context¶
The Track view gets a map behind the plot (track-view.md). Garmin watches with maps draw it from their own installed maps (WatchUi.MapView) and send nothing. Wear OS has no map of its own that an app can draw behind a canvas, so the map has to come from somewhere. Until now a Wear OS watch talked only to the SailEver API, and only after the consent.
Decision¶
- Wear OS draws the track map from SailEver's own tiles on
tiles.sailever.com(base map and depth, as on the website, maps.md) with MapLibre Native, OpenGL ES build. The style is bundled in the app (assets/track_map_style.json) and readstiles.jsonanddepth.json, so a new monthly build reaches the watch without an app update. - Paired watches only: the map, and with it every tile request, exists only when the watch is paired and has the current consent (
TrackMap.allowed). The setting Track map is shown only on a paired watch, default on; each user can turn it off. - Requests only while the Track view is on screen and not dimmed; the process is bound to a requested network for that time, as
Httpdoes per request. Tiles stay in MapLibre's cache (50 MB); offline, cached tiles keep showing and uncached areas stay black. - The privacy page names the requests (IP address and map area, not stored by us, Cloudflare's logs).
Consequences¶
- Paired watches now talk to the tile host as well as the API. MapLibre's requests don't go through
sync/Http; the gate isTrackMap.allowed, checked before the map is composed. - Tile traffic from watches counts against Cloudflare's free Worker and R2 limits; accepted without a limit before launch (owner, 2026-10-27).
- The APK grows by MapLibre's native libraries; the Play bundle delivers one ABI per watch.
- No map credit is drawn on the watch screen; the credits are on the website's map and the store listing. Revisit if OpenStreetMap or EMODnet ask for it on the watch.
- Raster tiles drawn by the app itself were the fallback if MapLibre had been too heavy; not needed.