ADR-0008: Mobile maps via fluttermap + OpenStreetMap raster tiles
Status: ProposedDate: 2026-05-11Owner: @satyaRelated: ADR-0001 (Flutter), spec 0001 (Trip Planner)Context
Section titled “Context”Spec 0001-trip-planner §3.1 F1.7 wants two map surfaces for v0:
- Per-day map with pins for activities that have a location, ordered path.
- Full-trip map with all destinations + all activities.
- Tap a pin → activity detail.
Constraints:
- No paid SaaS bills at v0.
- No API key provisioning step in the developer onboarding flow.
- Offline-first reads (F1.10.a) — at least last-viewed tiles cached.
- Acceptable rendering quality on a 2022-era Android.
Decision
Section titled “Decision”Use flutter_map with raster
tiles from OpenStreetMap (https://tile.openstreetmap.org/{z}/{x}/{y}.png).
Pins are Markers, ordered paths are Polylines. Geocoding stays out of
scope at v0 — destinations and activities carry user-entered lat/lng.
Alternatives considered
Section titled “Alternatives considered”| Option | Why not (now) |
|---|---|
| Mapbox SDK | Paid above 50k loads/mo; needs API key + secret rotation; v1 candidate. |
| Google Maps Flutter | Free tier ample but billing account required; iOS/Android plumbing per platform. |
Apple Maps via apple_maps_flutter | iOS-only; we’d still need a non-Apple option for Android. |
MapLibre GL Native (maplibre_gl) | Vector tiles look great but require a tile host (MapTiler, ProtoMaps, self-host); v1 candidate when we hit OSM rate limits. |
| Pure offline tile bundle | Storage cost too high for v0; pursued in M11 if needed. |
Consequences
Section titled “Consequences”Positive
- Zero-config local dev. No API keys, no billing.
- Pure-Dart on top of standard Flutter widgets — small surface area, easy to test.
- Tile cache via
flutter_cache_managerlands offline-first reads cheaply.
Negative
- OSM raster looks dated next to vector tiles; aesthetic cost on the brand.
- OSM Tile Usage Policy bans heavy / commercial traffic — when MAU grows we must migrate to a paid provider or self-hosted tiles.
- Attribution mandatory: a small ”© OpenStreetMap” overlay is part of the UI.
Implementation notes
Section titled “Implementation notes”apps/mobile/lib/features/trips/view/trip_map_page.dart - Two view modes: full-trip / per-day (segmented). - Markers: destination → outline house icon, lime fill. activity → forest dot with kind icon. - Polyline through chronologically ordered activities w/ location. - Tapping an activity marker opens a small bottom-sheet with title + time + "Edit" CTA that pushes the existing ActivityEditor.Tile attribution lives at the bottom-left as a tappable link to
https://www.openstreetmap.org/copyright.
Follow-ups
Section titled “Follow-ups”- ADR revisit when we either: (a) blow past OSM’s fair-use thresholds, or (b) add geocoding (probably triggers Mapbox/Geoapify selection).
- Offline tile pinning per pinned trip (F2.4.b) — owned by a later spec.