A bug from another planet
Last week a user in Shanghai sent us a screenshot of his bike ride. The route was sharp, smooth, every turn in its place. The only problem was the lake. He had not, in fact, ridden across a lake.
Turns out, by law, every map served inside mainland China has to use a coordinate system called GCJ-02. It takes the real-world coordinates everyone else uses, and adds a deliberate, pseudo-random offset on top. Between 50 and 700 meters, varying point by point. Two coordinates a meter apart can have completely different offsets. The algorithm is classified.
The reason, according to the Chinese government, is national security. The name, according to the Chinese tech community, is 火星坐标. Mars Coordinates. Because the maps live on a different planet.
The law follows political lines, not geographic ones. Hong Kong is exempt. Macao is exempt. Taiwan is exempt. If you ride your bike from Shenzhen to Hong Kong, somewhere over the river your map snaps back into reality.
The reference implementation that lets the rest of the world reverse-engineer the offset is a GitHub repo, maintained for over a decade by strangers. It is called eviltransform. That is its actual name. I want to frame it.
So when your iPhone in Shanghai reports GPS coordinates, those are real. When MapKit draws the streets around you, those are not. The two do not agree, and the gap is what our user was seeing. A small, state-mandated lie in the middle of his Sunday ride.
Every fitness app on the planet has hit this at some point. Strava, Garmin, Polar, all of them. The funny part is that Apple knows. Apple Maps the app handles it internally. The Health app used to, until iOS 18.4 quietly broke the conversion in March 2025. A Chinese developer filed a Feedback (FB17024450), Apple acknowledged it, and then nothing. Fourteen months later, your run in Beijing still looks wrong in Apple's own apps.
We added our own conversion. A small Swift function applied only at render time. All our data stays in real coordinates. Distance, pace, calories: everything that matters keeps computing correctly. The only thing that changes is what you see on the map.
Our user's ride now appears where he actually rode.
P.S. Baidu Maps adds a second offset on top of GCJ-02. Their own, on top of the government's. I do not know why.
Member discussion