iOS 18.4 changed how Health and Fitness draw workout routes on the mainland-China base map. The same app and the same route data render differently depending only on the OS version. On iOS 17.5, 18.0 and 18.3.1 the whole track is drawn one GCJ-02 displacement away from its stored coordinates (≈415 m east, ≈221 m south at this location). On iOS 18.4, 18.6 and 27 only the first ~49 samples are displaced that way; every later sample is drawn at its stored coordinates, and a straight line joins the leading block back to the rest. The stored data is identical in all cases.
Version-dependent offset of a third-party HKWorkoutRoute drawn on the mainland-China map
Data: a cycling FIT file whose positions are GCJ-02 — the datum of Apple's mainland base map. Verified at 31.3013 N, 120.7418 E: the GCJ-02 value sits on the road centre line, the WGS-84 value lands ~470 m north-west, and fitting the ride against OSM roads improves from 52.8 m median to 8.3 m after converting GCJ-02 → WGS-84. The app writes every position verbatim into an HKWorkoutRoute (no conversion on our side).
iOS version What Health / Fitness draw
17.5, 18.0, 18.3.1 the entire track, offset by one GCJ-02 displacement (≈415 m E, ≈221 m S) from the stored coordinates
18.4, 18.6, 27.0 only the first ~49 samples are offset by one GCJ-02 displacement; every later sample is drawn at its stored coordinates, joined by a straight line
Further measurements:
The size of the affected block is a sample count (~49), not a time or distance: two recordings of the same geometry at 1 Hz and 2 Hz both shift ≈49 samples (≈48 s vs ≈96 s); with 20 m sample spacing the shifted block is ≈950 m long and still ≈49 samples.
The stored data is not the variable: HKWorkoutRouteQuery returns all 3,141 points unchanged, and a HealthKit export GPX matches the stored values within 1e-6 degrees.
For long real routes the offset is intermittent: the same route object sometimes renders correctly on first open and shows the shifted leading block after leaving the screen and re-entering it, with no write in between.
This behavior change is undocumented: the iOS 18.4 Release Notes contain no HealthKit, MapKit or CoreLocation section and no mention of coordinates or datum, and the same is true for 18.3, 18.5 and 18.6.
Expected: a route is drawn at its stored coordinates — as it effectively was on iOS 18.3 and earlier, where the conversion was applied to the whole track. Actual: since iOS 18.4 the conversion appears to be applied to the leading block only, so the head of the track is displaced by one GCJ-02 offset relative to the rest.
Minimal reproduction: install one build on an iOS 18.3.1 simulator and on an iOS 18.4 simulator; write one outdoor workout plus a 200+ sample HKWorkoutRoute that follows a known road using GCJ-02 coordinates; open the workout's map in Fitness on both. On 18.3.1 the whole line is offset; on 18.4 the head is offset and the rest is correct.
Topic:
App & System Services
SubTopic:
Health & Fitness
Tags: