WGS84 / GCJ02(火星坐标)/ BD09 到底是什么?为什么必须转换?
# WGS84 / GCJ02(火星坐标)/ BD09 到底是什么?为什么必须转换?
> 接口:坐标系转换(apiCode=1252)背景科普 · 免费 · 适用人群:所有做位置功能的开发者 · 阅读时间:约 7 分钟
## TL;DR
- **WGS84**:GPS 卫星、手机定位、Google 地图用的"原始"坐标系。
- **GCJ02(火星坐标系)**:国内合规要求下对 WGS84 做了非线性加偏,高德、腾讯、51 地图使用。
- **BD09**:百度在 GCJ02 基础上再叠加一层偏移,百度地图使用。
- 三者之间不能直接混用,否则点位偏移数百米——这就是"为什么必须转换"。
## Why
你大概率听过"火星坐标"这个梗:同样一个真实地点,GPS 读出来的数和地图显示的数对不上。这不是 GPS 坏了,而是国内地图平台对真实坐标做了加密偏移。做位置相关功能的人,必须先理解这三套坐标系的来源,才能正确地把数据"翻译"到目标地图。本篇只讲概念与必要性,转换操作见[5 分钟接入](https://www.showapi.com/guides/coord-convert-quickstart-1252)。
## What
三种坐标系(来源:接口文档说明文字):
| 坐标系 | 别名 | 主要使用方 | 与 WGS84 的关系 |
|------|------|------|------|
| WGS84 | 原始大地坐标系 | 手机 GPS、Google 地图 | 基准,未加偏 |
| GCJ02 | 火星坐标系 | 腾讯、高德、51 地图 | 在 WGS84 上做非线性加偏 |
| BD09 | 百度坐标系 | 百度地图 | 在 GCJ02 上再叠加偏移 |
接口能力边界(来自文档):
| 项 | 值 |
|----|----|
| 支持转换 | WGS84 ↔ GCJ02 ↔ BD09 任意两两互转 |
| 接入点 1 | 坐标系转换(含批量,≤20 点) |
| 接入点 2 | 两点直线距离(返回米) |
## How
概念验证:把同一个 GPS 点分别转成 GCJ02 和 BD09,观察偏移量。
```python
import requests
def convert(app_key, point, to):
lng, lat = point
resp = requests.post(
"https://route.showapi.com/1252-1",
params={"appKey": app_key},
data={"from": "WGS84", "to": to, "location": f"{lng},{lat}"},
timeout=10,
).json()["showapi_res_body"]
return tuple(resp["resultList"][0]["output"])
p = (113.194329, 23.234704)
print("WGS84 原始 :", p)
print("转 GCJ02 :", convert("YOUR_APPKEY", p, "GCJ02")) # 偏移若干十米~百米
print("转 BD09 :", convert("YOUR_APPKEY", p, "BD09")) # 偏移更多
```
cURL:
```bash
curl -X POST "https://route.showapi.com/1252-1?appKey=YOUR_APPKEY" \
-H "content-type: application/x-www-form-urlencoded" \
-d "from=WGS84&to=GCJ02&location=113.194329%2C23.234704"
```
Node.js(fetch):
```javascript
async function convert(appKey, point, to) {
const [lng, lat] = point;
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 10000);
try {
const resp = await fetch(`https://route.showapi.com/1252-1?appKey=${appKey}`, {
method: "POST",
headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ from: "WGS84", to, location: `${lng},${lat}` }),
signal: controller.signal,
});
const res = (await resp.json()).showapi_res_body;
if (res.ret_code !== 0) throw new Error(JSON.stringify(res));
return res.resultList[0].output;
} finally { clearTimeout(timer); }
}
```
## 返回示例与解析
```json
{
"showapi_res_body": {
"from": "WGS84", "to": "GCJ02", "ret_code": 0,
"resultList": [
{ "input": [113.194329, 23.234704], "output": [113.19971018888167, 23.232115136208677] }
]
}
}
```
| 字段 | 说明 |
|------|------|
| `resultList[].output` | 转换后坐标(数组 [经度, 纬度]),可见与 input 已有偏移 |
## 进阶 / 边界
- **偏移是非线性的**:GCJ02 的加偏随位置变化,不是简单加减常量,无法用"统一偏移量"近似还原,必须用正规转换。
- **仅三种系互转**:文档支持 WGS84/GCJ02/BD09 两两转换,不涉及 CGCS2000 等其他坐标系。
- **文档未给"误差/精度"数字**:实际偏移量级因地点而异,本篇不编造具体数值。
## FAQ
**Q1:为什么叫"火星坐标"?**
A:GCJ02 在国内对 WGS84 做了非线性加偏,导致未转换的 GPS 点位"飘"到奇怪的地方,被戏称火星坐标。
**Q2:百度为什么又是一套?**
A:百度在 GCJ02 基础上再叠加了自己的偏移,形成 BD09。
**Q3:Google 地图用哪个系?**
A:WGS84,与手机 GPS 一致,通常无需转换即可对应。
**Q4:能不能用固定偏移量近似还原?**
A:不能,GCJ02 加偏非线性、随位置变化,必须用正规转换接口。
**Q5:本接口支持哪些系互转?**
A:WGS84、GCJ02、BD09 三者任意两两互转。
## 相关能力 / 下一步阅读
- [坐标系转换:5 分钟接入,从第一条 WGS84→GCJ02 结果开始](https://www.showapi.com/guides/coord-convert-quickstart-1252)
- [坐标系转换避坑:点位偏移 500 米、距离算错、坐标系混用](https://www.showapi.com/guides/coord-convert-pitfalls-1252)
- [高德/腾讯/百度/Google 地图坐标互通:坐标系转换在地图集成中的全链路设计](https://www.showapi.com/guides/coord-convert-map-platform-1252)
- **本系列共 12 篇**:查看[坐标系转换指南总目录](https://www.showapi.com/guides/coord-convert-guides-1252)