高德/腾讯/百度/Google 地图坐标互通:坐标系转换在地图集成中的全链路设计
# 高德/腾讯/百度/Google 地图坐标互通:坐标系转换在地图集成中的全链路设计
> 接口:坐标系转换(apiCode=1252,接入点 1)· 免费 · 返回 JSON · 适用人群:全栈工程师、产品经理 · 阅读时间:约 8 分钟
## TL;DR
- 高德/腾讯用 **GCJ02**,百度用 **BD09**,GPS 设备/Google 用 **WGS84**——直接混用会偏移数百米。
- 全链路是「拿到原始坐标 → 转成目标地图坐标系 → 打点」,转换只是其中一步。
- 中文地图 SDK 只认自己的坐标系;把 GPS 的 WGS84 转成对应系再打点才能对齐。
## Why
你做外卖、出行、打卡、物流轨迹时,点位"飘"了几百米,几乎都是坐标系不一致导致的。地图平台各自加偏:高德/腾讯在 WGS84 基础上做了 GCJ02 偏移,百度又在 GCJ02 基础上叠加了 BD09 偏移。不做转换就拿 GPS 直接打点,偏移必然发生。本篇给出一套可直接落地的集成设计。
## What
前置条件:已跑通单点转换(见[坐标系转换:5 分钟接入](https://www.showapi.com/guides/coord-convert-quickstart-1252))。
四类地图对应的坐标系(来自接口文档说明):
| 地图 / 数据源 | 坐标系 |
|------|------|
| 高德地图、腾讯地图、51地图 | GCJ02 |
| 百度地图 | BD09 |
| 手机 GPS、Google 地图 | WGS84 |
接口速览(接入点 1):
| 项 | 值 |
|----|----|
| 接口地址 | `https://route.showapi.com/1252-1?appKey={your_appKey}` |
| 请求方式 | POST / GET |
| 关键参数 | `from`(WGS84/GCJ02/BD09)、`to`(同)、`location`(经度,纬度;最多 20 点) |
## How
以「前端展示在高德地图」为例,链路如下:
**步骤 1:服务端转换**。在后端拿到 GPS(WGS84)后转成 GCJ02,再把转换结果下发给前端,避免在前端暴露 AppKey。
```python
import requests
def wgs84_to_gcj02(app_key, points):
# points: [(lng, lat), ...],单次最多 20 个
location = ";".join(f"{lng},{lat}" for lng, lat in points)
resp = requests.post(
"https://route.showapi.com/1252-1",
params={"appKey": app_key},
data={"from": "WGS84", "to": "GCJ02", "location": location},
timeout=10,
).json()
body = resp["showapi_res_body"]
if body.get("ret_code") != 0:
raise RuntimeError(body)
return [tuple(it["output"]) for it in body["resultList"]]
```
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 wgs84ToGcj02(appKey, points) {
const location = points.map(([lng, lat]) => `${lng},${lat}`).join(";");
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: "GCJ02", location }),
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.map(it => it.output);
} finally { clearTimeout(timer); }
}
```
**步骤 2:前端打点**。把转换后的 GCJ02 坐标交给高德/腾讯 JS API 直接打点(它们认 GCJ02)。若目标是百度地图,则 `to=BD09` 后再用百度地图 JS API。
## 返回示例与解析
```json
{
"showapi_res_code": 0,
"showapi_res_body": {
"from": "WGS84", "to": "GCJ02", "ret_code": 0,
"resultList": [
{ "input": [113.194329, 23.234704], "output": [113.19971018888167, 23.232115136208677] }
]
}
}
```
| 字段 | 说明 |
|------|------|
| `resultList[].output` | 转换后的坐标(数组 [经度, 纬度]),直接喂给对应地图 SDK |
## 进阶 / 边界
- **不要在浏览器暴露 AppKey**:转换应在后端做,前端只拿到已转换坐标。
- **目标系要跟地图 SDK 一致**:高德/腾讯用 GCJ02、百度用 BD09,转错系仍然偏移。
- **多点在客户端渲染**:见[前端可视化:把转换后的坐标点在地图上画出来](https://www.showapi.com/guides/coord-convert-map-render-1252)。
## FAQ
**Q1:为什么不直接用 GPS 在高德上打点?**
A:高德使用 GCJ02,GPS 是 WGS84,两者差一个加偏量,直接打点会偏移数百米。
**Q2:百度地图要转成什么系?**
A:BD09(百度在 GCJ02 基础上又做了偏移)。
**Q3:Google 地图用哪个系?**
A:WGS84,与手机 GPS 一致;若把 GPS 展示在 Google 地图上通常无需转换。
**Q4:一次能转换多少个点给前端?**
A:接入点 1 单次最多 20 个点;更多点需分批或后端循环(见[坐标系转换(批量)](https://www.showapi.com/guides/coord-convert-batch-1252))。
**Q5:转换结果能缓存吗?**
A:同一 `from`/`to`/坐标的转换结果幂等,可本地缓存以节省免费档位(见[免费接口的成本管控](https://www.showapi.com/guides/coord-convert-cache-1252))。
## 相关能力 / 下一步阅读
- [坐标系转换:5 分钟接入,从第一条 WGS84→GCJ02 结果开始](https://www.showapi.com/guides/coord-convert-quickstart-1252)
- [坐标系转换(批量):一次性转换最多 20 个 GPS 点位](https://www.showapi.com/guides/coord-convert-batch-1252)
- [前端可视化:把转换后的坐标点在地图上画出来](https://www.showapi.com/guides/coord-convert-map-render-1252)
- **本系列共 12 篇**:查看[坐标系转换指南总目录](https://www.showapi.com/guides/coord-convert-guides-1252)