Python 实战:把一份 CSV 里的 GPS 经纬度批量转成高德坐标
# Python 实战:把一份 CSV 里的 GPS 经纬度批量转成高德坐标
> 接口:坐标系转换(apiCode=1252,接入点 1)· 免费 · 返回 JSON · 适用人群:数据分析、运营、开发者 · 阅读时间:约 7 分钟
## TL;DR
- 用标准库 `csv` 读表,把 GPS 的 WGS84 经纬度按每批 ≤20 个点调接口转成 GCJ02(高德/腾讯系)。
- 转换结果写回新列,结合指数退避重试与超时,可直接落地到生产数据清洗。
- 同一坐标重复出现时可先去重,节省免费档位(见[成本管控](https://www.showapi.com/guides/coord-convert-cache-1252))。
## Why
手里一份门店表、车辆表、打卡记录,全是 GPS(WGS84)经纬度,但要在高德地图展示。逐条手转不现实。本篇给一段可直接运行的脚本:读 CSV → 分批转换 → 写回新列,拿到就能用。
## What
前置条件:已获取 AppKey([AppKey 管理](https://www.showapi.com/console#/myApp)),理解批量上限 20 点/次(见[坐标系转换(批量)](https://www.showapi.com/guides/coord-convert-batch-1252))。
| 项 | 值 |
|----|----|
| 接口地址 | `https://route.showapi.com/1252-1?appKey={your_appKey}` |
| 关键参数 | `from=WGS84`、`to=GCJ02`、`location`(`;` 分隔,≤20 点) |
假设输入 CSV 含列 `id,lng,lat`,目标输出新增 `gcj02_lng,gcj02_lat`。
## How
**步骤 1:准备输入 `points.csv`**:
```csv
id,lng,lat
1,113.194329,23.234704
2,113.20,23.24
3,113.21,23.25
```
**步骤 2:运行转换脚本**:
```python
import csv, requests, time
APP_KEY = "YOUR_APPKEY"
BATCH = 20
def convert(points):
# points: [(lng, lat), ...] ≤20
location = ";".join(f"{lng},{lat}" for lng, lat in points)
for attempt in range(3):
try:
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"]]
except Exception as e:
if attempt == 2:
raise
time.sleep(2 ** attempt)
with open("points.csv", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
out_rows = []
for i in range(0, len(rows), BATCH):
chunk = rows[i:i + BATCH]
pts = [(float(r["lng"]), float(r["lat"])) for r in chunk]
converted = convert(pts)
for r, (clng, clat) in zip(chunk, converted):
r["gcj02_lng"], r["gcj02_lat"] = clng, clat
out_rows.append(r)
with open("points_gcj02.csv", "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=["id", "lng", "lat", "gcj02_lng", "gcj02_lat"])
w.writeheader()
w.writerows(out_rows)
print("已写出 points_gcj02.csv,共", len(out_rows), "行")
```
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%3B113.20%2C23.24"
```
Node.js(fetch,单批):
```javascript
async function convert(points, appKey) {
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); }
}
```
## 返回示例与解析
```json
{
"showapi_res_body": {
"ret_code": 0,
"resultList": [
{ "input": [113.194329, 23.234704], "output": [113.19971018888167, 23.232115136208677] }
]
}
}
```
| 字段 | 说明 |
|------|------|
| `resultList[].output` | 转换后的 GCJ02 坐标,写回 `gcj02_lng/gcj02_lat` |
## 进阶 / 边界
- **去重省额度**:同一坐标重复出现时,先用集合去重再调接口,结果回填,可显著减少请求数。
- **本地缓存**:相同 `from/to/坐标` 结果幂等,可缓存(见[成本管控](https://www.showapi.com/guides/coord-convert-cache-1252))。
- **经纬度范围校验**:写入前校验经度 -180~180、纬度 -90~90,避免脏数据报错。
## FAQ
**Q1:CSV 列名一定要叫 lng/lat 吗?**
A:不必须,脚本里按你的实际列名读取即可,关键是把"经度,纬度"正确拼进 `location`。
**Q2:一次能处理多少行?**
A:脚本按每批 20 点循环,任意行数都可处理;行数越多请求越多,注意免费档位。
**Q3:能直接转成百度坐标吗?**
A:可以,把 `to=GCJ02` 改成 `to=BD09` 即可。
**Q4:转换失败会中断整个文件吗?**
A:脚本带 3 次指数退避重试;仍失败会抛异常,建议生产环境改为记录失败行并继续。
**Q5:能缓存结果提速吗?**
A:能,且推荐——相同坐标转换结果不变(见成本管控篇)。
## 相关能力 / 下一步阅读
- [坐标系转换(批量):一次性转换最多 20 个 GPS 点位](https://www.showapi.com/guides/coord-convert-batch-1252)
- [免费接口的成本管控:坐标系转换的本地缓存与批量合并策略](https://www.showapi.com/guides/coord-convert-cache-1252)
- [高德/腾讯/百度/Google 地图坐标互通:坐标系转换在地图集成中的全链路设计](https://www.showapi.com/guides/coord-convert-map-platform-1252)
- **本系列共 12 篇**:查看[坐标系转换指南总目录](https://www.showapi.com/guides/coord-convert-guides-1252)