Atlaslog / Field Notes / Coordinates & projections
Field note · Coordinates & projections
Same points converted twice: offset grows from 555 m to 1110 m
Quick answer
The backend already stores GCJ-02 but records no CRS tag, so the frontend converts again. GCJ-02 encryption is not idempotent: f(f(x)) keeps adding the same north-east increment instead of undoing it.
Symptom
- Beijing Guomao 116.397428, 39.909230 should become 116.403672, 39.910634 (555.6 m) but the map shows 116.409922, 39.912036, about 1110 m away.
- The error direction stays north-east, so it looks like a larger datum offset rather than a reversed conversion.
- The whole POI layer moves by the same doubled distance, which no longer looks like survey error.
Checklist
- Take one known point, subtract the interface value from the on-map value to get the actual offset vector.
- Compute the single-pass WGS84 to GCJ-02 result and compare it with the API return; a match means the backend already converted.
- Copy the API response into gcoord.transform and run it once in the console to see whether it moves another ~555 m.
- Search the frontend for a global coordinate middleware or an axios response interceptor doing the conversion.
- Check whether the stored rows carry any CRS marker at all; if not, the pipeline is guessing.
Fix
Convert exactly once, preferably at the data-production end, and write the CRS into the payload so downstream code never has to infer it.
Code
const a = turf.point([116.397428, 39.909230]); // WGS84 原始点
const b = turf.point([116.403672, 39.910634]); // 应得 GCJ-02
const c = turf.point([116.409922, 39.912036]); // 实际渲染点
turf.distance(a, b, { units: 'meters' }); // 555.6
turf.distance(a, c, { units: 'meters' }); // 1110.2
turf.distance(b, c, { units: 'meters' }); // 554.6{
"type": "FeatureCollection",
"coordSys": "GCJ02",
"features": [
{ "type": "Feature",
"properties": { "name": "国贸" },
"geometry": { "type": "Point", "coordinates": [116.403672, 39.910634] } }
]
}
const SRC = 'WGS84', DST = 'GCJ02';
function normalize(fc, target) {
const from = fc.coordSys || 'WGS84';
if (from === target) return fc; // 已经一致,直接返回
return gcoord.transform(fc, gcoord[from], gcoord[target]);
}
const data = normalize(resp.data, 'GCJ02');
Watch out
- Trying to invert the double conversion numerically: f(f(x)) cannot be undone by subtracting the offset, polluted rows must be re-exported from the original WGS84 source.
- Adding a third conversion to 'fix' the doubled offset, which pushes the layer another 555 m north-east.
English edition written for Atlaslog from the original Chinese field note. Code is unchanged and runs as-is.
Atlaslog (2026). Same points converted twice: offset grows from 555 m to 1110 m. https://www.jingweizhi.com/en/cookbook/gcj02-double-convert.html (accessed 2026-11-03).