Stations past the nearest-12 cutoff silently fell back to straight-line,
which explained the remaining app-vs-Apple-Maps gaps (e.g. 3.5 straight-line
vs 5.9 road). Raise the per-pass cap to 40 and route every station within a
25 km straight-line radius (covers the 15 mi max search window) so any station
the widget/Live Activity/list can show gets a real road distance.
Also harden the new cache tests against persistent keychain state across
invocations (reset in setUp) so they pass deterministically.
The widget/Live Activity showed straight-line haversine distance (0.8 mi)
while Apple Maps routes 1.8 mi. Road routing is too heavy for the widget
execution + ~40-70/day refresh budget, so the APP now computes it:
- New RoadDistanceService (app target): for the nearest 12 stations each
pass, calls MapKit MKDirections (free, no API key, matches Apple Maps)
and caches metres keyed by station ID.
- Cache stored in KEYCHAIN (fuelboard.roadDistances) so the widget reads it
even on free SideStore accounts with no app-group container; only valid
within 600 m of the location it was built from.
- Throttled: recompute max every 10 min, or when the user moves > 400 m;
wired into the location-update hook + location onChange.
- Widget face, app station rows + Live Activity show the cached road
distance, falling back to straight-line when absent.
- 4 new cache tests (105 total).