ccvt 是命令行坐标转换工具:坐标系互转(WGS84 / GCJ02 / BD09 / CGCS2000)+ 坐标格式互转(十进制度 / 度分秒 / UTM / MGRS)。库 + CLI 双暴露,管道优先,零依赖 binary,下载即用。
ccvt 版本更新记录(v0.1.1 / v0.2.0)
v0.2.0(2026-08-10)
新增 fmt 子命令:坐标格式互转
- 支持 度分秒 / 十进制度 / UTM / MGRS 四种格式,12 个转换方向,
-f/-t通用入口(与convert对称) - 度分秒解析兼容多种写法(
39°54'N、N39°54'、全角′″、小数分/秒),输出可调小数秒位数(--sec-digits) - UTM 正反算:WGS84 基准、Snyder 横向墨卡托公式,zone 1-60、纬度带 C–X、南半球假偏移,亚米级精度
- MGRS 编码/解码:标准 100km 网格字母,
--digits控制精度(4=1km / 6=100m / 8=10m / 10=1m,默认 6) - 与
convert正交:convert换基准、fmt换格式,管道串联实现「4 基准 × 4 格式」任意组合 - 验证:8 个全球参考点(北京/上海/悉尼/伦敦/赤道等),UTM/MGRS 参考值由 pyproj/mgrs 独立生成,10 位 MGRS 与 pyproj 逐位一致
v0.1.1(2026-08-10)
新增 CGCS2000 坐标系
- 第 4 个坐标系(国家 2000 大地坐标系,自然资源/规划/国土行业常用)
- 与 WGS84 恒等处理(亚米级工程互换):
wgs84 ↔ cgcs2000透传,其余方向复用 wgs84 路径 - 转换方向由 6 个扩展至 12 个
v0.1.0(2026-08-06,首发)
- WGS84 / GCJ02 / BD09 三坐标系 6 方向互转
- 库 + CLI 双暴露、管道优先、text/csv/json 输入、text/json 输出
- 三态退出码(0/1/2)、
--order坐标顺序、--strict严格模式 - 反向转换迭代逼近到机器精度(优于外部库一步近似逆的 0.5–2m 误差)
- 零依赖 binary,GitHub Actions 构建 7 平台制品
- 性能:100 万点含管道 0.9s
快速体验
# 安装(macOS arm64)
curl -LO https://github.com/Angryshark128/ccvt/releases/download/v0.2.0/ccvt-aarch64-apple-darwin.tar.gz
tar -xzf ccvt-aarch64-apple-darwin.tar.gz
sudo mv ccvt /usr/local/bin/
# 坐标系互转
echo "116.3975 39.9087" | ccvt -f wgs84 -t gcj02
# 格式互转(v0.2.0 新增)
ccvt fmt -f dd -t utm 39.9087 116.3975 # 十进制 → UTM
ccvt fmt -f dd -t mgrs 39.9087 116.3975 # 十进制 → MGRS
ccvt fmt -f dms -t dd "39°54'N 116°24'E" # 度分秒 → 十进制
ccvt fmt -f mgrs -t dd "50S ME 32100 18700" # MGRS → 十进制
一、要解决的问题
在中国做地图开发,几乎每个人都踩过同一个坑:坐标系不统一。
- WGS84:GPS 原始坐标,数据库、硬件上报、国际 API 多用这个。
- GCJ02(火星坐标):高德、腾讯地图在用,与真实经纬度偏移 100–500 米。
- BD09:百度坐标,在 GCJ02 上再叠一层偏移。
「后端存 WGS84、前端高德要 GCJ02」每天都在发生。前端生态(Gcoord、coordtransform)成熟了,但后端 / 数据管道场景一直缺趁手的工具——要装 npm 依赖、写胶水脚本、海量数据时性能跟不上。ccvt 就是一条命令,在管道里批量转换。
本机实测:
$ echo "116.3975 39.9087" | ccvt -f wgs84 -t gcj02
116.40374357265176 39.91010349934476
$ echo '{"lng":116.3975,"lat":39.9087}' | ccvt -f wgs84 -t gcj02 -i json -o json
{"lat":39.91010349934476,"lng":116.40374357265176}
二、解决方案:支持哪些功能
技术选型:Rust + clap + serde,GitHub Actions 发布 7 个平台制品。
功能清单
① 6 个转换方向——三个坐标系两两互转,无 API 依赖,纯公开算法:
wgs84->gcj02 : 116.40374357265176 39.91010349934476
wgs84->bd09 : 116.4101165864734 39.91644274963076
gcj02->wgs84 : 116.3912588656213 39.90729875233756
gcj02->bd09 : 116.40387297451515 39.915043351185915
bd09->wgs84 : 116.38487338089874 39.900991708020854
bd09->gcj02 : 116.39110932980803 39.90238879122332
② 3 种输入、2 种输出:
| 格式 | 说明 |
|---|---|
text | 默认,空格/逗号分隔,可 -s 指定分隔符 |
csv | 自动识别表头列名(lng/lon/longitude/x、lat/y),也可 --lng/--lat 指定 |
json | 单点对象或数组;兼容 longitude/latitude/x/y 别名和 [lng,lat] 形态 |
输出统一 text(lng lat)或 JSON({"lng":…,"lat":…})。
③ 管道与错误处理——成功结果只写 stdout,一切 warn/报错走 stderr;三态退出码(0 至少成功 / 1 严格模式部分失败 / 2 全失败或参数错)。空行跳过。
④ 坐标顺序可控——默认 lng,lat(高德/百度习惯),--order latlng 切到 Google 系习惯;JSON 用字段名、CSV 用列名定位,不依赖顺序。
精度与性能
- 反向方向(GCJ02→WGS84、BD09→WGS84、BD09→GCJ02)用迭代逼近:公开的反向公式是「减去偏移」的近似式(固有误差 0.5–2m),改为用正向公式算偏移、迭代修正至收敛(阈值 1e-9°),往返误差达到机器精度(<1e-9°)。
往返验证(wgs84 → gcj02 → wgs84):
输入 116.3975 39.9087
转回 116.39749999999995 39.90869999999997 ← 误差 < 1e-13
- 境外点原样返回:超出中国国境范围(公开公式有效域)的坐标不做偏移。
- 性能:纯算法百万点 <0.1s;含 I/O 管道实测约 1s / 100 万行(release)。
结构
代码分层很直白:input.rs 把三种输入格式统一成 (lng, lat),convert.rs 纯计算(不感知输入来源),output.rs 格式化。解析层再复杂,算法层永远只面对一组数值。
三、期间面临的挑战
1. 反向精度被外部库「带偏」。最初用 gcoord(JS 独立实现)生成测试参考值,一跑反向方向差异 ~1e-6°——查了半天发现是 gcoord 自己用了一步近似逆,ccvt 反而更准:gcoord 与 coordtransform 在这个方向互相分歧 98/100 个点。结论:参考实现也可能是近似,交叉验证要先量化对方误差再定容差,否则会把正确结果"改错"。
2. 设计文档里的「闭式逆」是错的。文档写「BD09→GCJ02 用闭式逆」,实现时发现公开闭式逆是近似式(往返误差 ~1e-5°),改为迭代逼近后达机器精度。结论:公开算法资料的「标准答案」也可能是近似的,实现前先验证往返误差。
3. JSON 输入形态爆炸。单点对象、数组、点数组、字段别名……最后收敛成一个 parse_json 函数、全部规约成内部 (lng, lat)。结论:用统一内部表示兜住所有形态,解析层复杂、算法层永远简单。
四、经验收获
- 求逆向,优先迭代逼近而不是一步近似式——只要正向映射可算,用正向迭代求逆通常能拿到机器精度,可迁移到任何「正向可算、反向难」的映射。
- 参考实现不是金标准,第三方库 / 公开公式也可能是近似,交叉验证前先量化对方误差。
- 管道工具黄金法则:成功走 stdout、告警走 stderr,让下游永远消费干净数据。
- 隐式约定靠结构兜底——JSON 用字段名、CSV 用列名、text 才依赖顺序,把最容易错位的坐标顺序交给格式自身解决。
五、代码与安装
仓库:github.com/Angryshark1… (MIT License,Rust,无运行时依赖)
安装(macOS arm64 示例,下载预编译制品):
curl -LO https://github.com/Angryshark128/ccvt/releases/latest/download/ccvt-aarch64-apple-darwin.tar.gz
tar -xzf ccvt-aarch64-apple-darwin.tar.gz
sudo mv ccvt /usr/local/bin/
Windows 解压 zip 加 PATH;Linux 同理。也可 cargo build --release 源码构建。
运行:
# text 输入
echo "116.3975 39.9087" | ccvt -f wgs84 -t gcj02
# CSV 批量(自动识别表头)
cat db.csv | ccvt -f wgs84 -t gcj02 -i csv
# JSON API 转换
curl api | ccvt -f wgs84 -t gcj02 -i json -o json
# 非标准表头
ccvt -f wgs84 -t gcj02 -i csv --lat 纬度 --lng 经度 < china.csv
# 严格模式
ccvt -f wgs84 -t gcj02 --strict < bad.txt
Rust 库调用:
use ccvt::convert::wgs84_to_gcj02;
let (lng, lat) = wgs84_to_gcj02(116.3975, 39.9087);