# ccvt **Repository Path**: hancic128/ccvt ## Basic Information - **Project Name**: ccvt - **Description**: 命令行坐标转换工具:坐标系互转(WGS84 / GCJ02 / BD09 / CGCS2000)+ 坐标格式互转(十进制度 / 度分秒 / UTM / MGRS)。库 + CLI 双暴露,管道优先,零依赖 binary,下载即用。 - **Primary Language**: Rust - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-09-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: 坐标转换, 单位转换, Cli, GIS ## README # ccvt 命令行坐标转换工具:**坐标系互转**(WGS84 / GCJ02 / BD09 / CGCS2000)+ **坐标格式互转**(十进制度 / 度分秒 / UTM / MGRS)。库 + CLI 双暴露,管道优先,零依赖 binary,下载即用。 ## 简介 ccvt 面向命令行与数据管道,解决两类问题: - **坐标系互转**:数据库存 WGS84,前端要高德(GCJ02)/百度(BD09)坐标;或国土/测绘的 CGCS2000 成果接入地图系 - **格式互转**:GPS 设备输出的度分秒、专业软件的 UTM/MGRS 坐标,统一成十进制度入库 适合的场景: - 地图 / 位置服务开发 — 后端存 WGS84,前端用高德/百度 - GIS / 数据处理 — 地理数据坐标系统一、批量清洗 - 户外 / 测绘 / 记录 — 度分秒、UTM、MGRS 与十进制度互转 ## 功能总览 | 子命令 | 负责 | 转换维度 | 入口 | |--------|------|---------|------| | `convert`(默认) | 坐标系互转 | WGS84 / GCJ02 / BD09 / CGCS2000,12 方向 | `-f`/`-t`(值域=坐标系) | | `fmt` | 格式互转 | 十进制度 / 度分秒 / UTM / MGRS,12 方向 | `-f`/`-t`(值域=格式) | 两者正交:`convert` 换基准、`fmt` 换写法,管道串联可自由组合。 ## 文档 | 文档 | 内容 | |------|------| | [API 文档](docs/api.md) | 完整 API 说明:CLI 全部参数、输入/输出格式、退出码、Rust 库、完整示例 | | [设计文档](docs/design.md) | 定位、算法、精度、性能、项目结构、v1/v2/v3 路线 | ## 支持的坐标系(convert) | 坐标系 | 说明 | |------|------| | `wgs84` | GPS 原始坐标,国际标准 | | `gcj02` | 火星坐标,高德/腾讯地图 | | `bd09` | 百度坐标,在 GCJ02 上再加偏移 | | `cgcs2000` | 中国大地坐标系 2000,国家测绘基准(自然资源/规划/国土常用) | 4 个坐标系共 12 个转换方向(含 WGS84↔CGCS2000 恒等 2 个),无 API 依赖,基于公开算法。 > **CGCS2000 与 WGS84 恒等处理**:`cgcs2000` 与 `wgs84` 视作同一坐标基准(亚米级工程互换),`wgs84 ↔ cgcs2000` 直接透传,`cgcs2000 ↔ gcj02/bd09` 复用 wgs84 路径。精度口径与依据见[设计文档 §13](docs/design.md)。 ## 支持的格式(fmt) | 格式 | 说明 | 示例 | |------|------|------| | `dd` | 十进制度 | `39.9087 116.3975`(纬度 经度) | | `dms` | 度分秒 | `39°54'31"N 116°23'51"E` | | `utm` | UTM(WGS84 基准) | `50S 448502 4417798`(zone 带 easting northing) | | `mgrs` | MGRS(100km 网格,WGS84 基准) | `50SMK485177`(默认 6 位) | 4 种格式共 12 个转换方向,内部统一经十进制度中转。UTM/MGRS 仅基于 WGS84 椭球(CGCS2000 恒等可直接投);GCJ02/BD09 是加密偏移坐标系、无自有 UTM,需先经 `convert` 回到 WGS84。 ## 坐标顺序 - **`convert`**:默认**经度在前**(`lng,lat`)——高德/腾讯/百度 API 全部是 `(lng,lat)`,与核心用户存量数据一致;用 `--order latlng` 切换纬度在前(Google 系习惯)。JSON 用字段名 `lng`/`lat` 区分,CSV 用列名定位,均不依赖顺序。 - **`fmt`**:统一**纬度在前(lat,lng)**——DMS/UTM/MGRS 的天然结构就是纬度在前。`fmt` 结果接 `convert` 时加 `--order latlng`。 ## 安装 下载即用,无运行时依赖(不需要装 Rust / Cargo)。 **从 GitHub Release 下载预编译制品**(由 GitHub Actions 构建): | 平台 | 架构 | 制品 | |------|------|------| | macOS | arm64(Apple Silicon)/ x86_64(Intel) | `ccvt-aarch64-apple-darwin.tar.gz` / `ccvt-x86_64-apple-darwin.tar.gz` | | Windows | 64 位 / 32 位 | `ccvt-x86_64-pc-windows-msvc.zip` / `ccvt-i686-pc-windows-msvc.zip` | | Linux | x86_64 / arm64 / 32 位 | `ccvt-x86_64-unknown-linux-gnu.tar.gz` 等 | 以 macOS arm64 为例: ```bash 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/ # 或放进任意 PATH 目录 ``` > 下载最新版时,把链接里的 `v0.2.0` 换成最新的 tag 版本号即可。 > 也可以在 GitHub Releases 页面手动下载各平台制品。 > 当前最新发布版为 v0.2.0(含 CGCS2000 与 `fmt` 子命令)。 Windows 下载 zip 解压后,将 `ccvt.exe` 加入 PATH 即可。 > 若愿意装 Rust 工具链,也可 `cargo install --path .` 从源码构建。 ### 发布流程 打 tag 即自动构建全部平台制品并发布到 GitHub Release: ```bash git tag v0.2.0 git push origin v0.2.0 ``` 也可在仓库 Actions 页面手动触发 release workflow。 ## 用法 ### convert:坐标系互转 ```bash # 最简(text 输入,默认空格/逗号分隔) echo "116.3975 39.9087" | ccvt -f wgs84 -t gcj02 # CSV 输入(自动检测表头列名) cat db.csv | ccvt -f wgs84 -t gcj02 -i csv # 指定列名 ccvt -f bd09 -t wgs84 -i csv --lat 纬度 --lng 经度 # JSON 输入输出 echo '{"lng":116.3975,"lat":39.9087}' | ccvt -f wgs84 -t gcj02 -i json -o json # 指定分隔符 cat gps.tsv | ccvt -f wgs84 -t gcj02 -s "\t" # 严格模式(部分失败退出码 1) ccvt -f wgs84 -t gcj02 --strict < bad.txt ``` ### fmt:坐标格式互转 ```bash # 度分秒 → 十进制度 ccvt fmt -f dms -t dd "39°54'N 116°24'E" # 十进制度 → 度分秒(--sec-digits 控制小数秒位数) ccvt fmt -f dd -t dms --sec-digits 2 39.9087 116.3975 # 十进制度 → UTM(zone 带 easting northing,WGS84) ccvt fmt -f dd -t utm 39.9087 116.3975 # UTM → 十进制度 ccvt fmt -f utm -t dd "50S 448502 4417798" # 十进制度 → MGRS(--digits 控制精度:4=1km / 6=100m / 8=10m / 10=1m,默认 6) ccvt fmt -f dd -t mgrs 39.9087 116.3975 ccvt fmt -f dd -t mgrs --digits 10 39.9087 116.3975 # MGRS → 十进制度(紧凑或带空格均可) ccvt fmt -f mgrs -t dd "50SMK4850217797" ccvt fmt -f mgrs -t dd "50S ME 32100 18700" ``` fmt 坐标参数:`dd` 为「纬度 经度」两个数值;`dms`/`utm`/`mgrs` 为一个整体串(带空格加引号)。南纬/西经用负号直接传入(如 `ccvt fmt -f dd -t utm -33.8688 151.2093`)。 **输入格式细节** - `dms`:`39°54'N` / `N39°54'` / `39.9087°N`;分隔符 `°`/`'`/`"` 或全角 `′`/`″` 混用;分/秒可带小数;方向符大小写均可 - `utm`:`50S 448502 4417798` 或 `50 S 448502 4417798`(zone+带可连写) - `mgrs`:紧凑 `50SMK4850217797` 或带空格 `50S ME 32100 18700`;数字位数 2/4/6/8/10 ### 辅助命令 ```bash ccvt list / ccvt version / ccvt --help ``` ## 参数 ### convert 参数 | 参数 | 短写 | 必需 | 说明 | |------|------|------|------| | `--from` | `-f` | 是 | 源坐标系(wgs84/gcj02/bd09/cgcs2000) | | `--to` | `-t` | 是 | 目标坐标系(wgs84/gcj02/bd09/cgcs2000) | | `--input-format` | `-i` | 否 | `text`(默认)/`csv`/`json` | | `--output-format` | `-o` | 否 | `text`(默认)/`json` | | `--order` | — | 否 | `lnglat`(默认,经度在前)/`latlng` | | `--lat` | — | 否 | CSV 纬度列名,默认自动检测 | | `--lng` | — | 否 | CSV 经度列名,默认自动检测 | | `--sep` | `-s` | 否 | text 输入分隔符(默认空格/逗号) | | `--strict` | — | 否 | 严格模式,部分失败退出 1 | ### fmt 参数 | 参数 | 短写 | 必需 | 说明 | |------|------|------|------| | `--from` | `-f` | 是 | 源格式(dms/dd/utm/mgrs) | | `--to` | `-t` | 是 | 目标格式(dms/dd/utm/mgrs) | | `--sec-digits` | — | 否 | 目标为 dms 时的小数秒位数(0-6,默认 0) | | `--digits` | — | 否 | 目标为 mgrs 时的数字位数(2/4/6/8/10,默认 6) | ### JSON 字段映射(convert) - 读取:`lng`/`lat`(优先),兼容 `longitude`/`latitude`、`x`/`y` 别名;数组形态 `[lng,lat]` 也接受。 - 写出:统一 `{"lng":…,"lat":…}`。 ### CSV 边界(convert) - 无表头或表头无匹配列 → 报错退出 2,提示用 `--lat`/`--lng`。 - `--lat`/`--lng` 缺一个 → 报错退出 2。 - 列名自动检测:大小写不敏感,识别 `lng/lon/longitude/x`、`lat/y`。 ## 批量任务与退出码 **convert** 为批量管道:三态 **ok**(stdout)、**warn**(stderr)、**skip**(stderr)。 **输出流规则:只有成功结果写 stdout;一切 warn/skip/报错只写 stderr**,保证管道下游拿到干净的转换结果。 | 退出码 | 含义 | |------|------| | `0` | 至少一行成功 | | `1` | `--strict` 且部分失败 | | `2` | 全部失败(或参数错误) | **fmt** 为单次转换:成功 `0`;解析/参数错误 `2`。 ## 精度 - **convert 正向**(WGS84→GCJ02、GCJ02→BD09):直接套用公开偏移公式,一次计算。 - **convert 反向**(GCJ02→WGS84、BD09→WGS84、BD09→GCJ02):**迭代逼近**——用正向公式算偏移、修正输入、重复至收敛(阈值 1e-9°,通常 ≤5 次),达到机器精度。 - **CGCS2000**:与 WGS84 恒等(亚米级工程互换),透传不引入数值变换。 - **fmt UTM/MGRS**:Snyder 横向墨卡托公式(WGS84),正反算亚米级,参考 proj/pyproj 验证(容差 1m 内)。 - **fmt dms**:纯格式换算,机器精度。 - 输入精度多高,输出就多高,不额外截断。 ### 性能 - 纯算法:百万点 <0.1s(Rust),比 Python/JS 快一个数量级。 - 含 I/O 管道:实测 0.9s / 100 万行(release),差距缩小至约 2-5x。 详细设计与验证结论见[`docs/design.md`](docs/design.md);完整 API 说明与使用文档见[`docs/api.md`](docs/api.md)。 ## 场景示例 ```bash # 1. 数据库导出(WGS84)→ 高德前端 cat db.csv | ccvt -f wgs84 -t gcj02 -i csv # 2. GPS 日志 → 百度地图 cat gps.txt | ccvt -f wgs84 -t bd09 # 3. 高德坐标 → 数据库(转回 WGS84) curl api | ccvt -f gcj02 -t wgs84 -i json -o json # 4. 百度 → 高德 ccvt -f bd09 -t gcj02 -i csv < bd.csv # 5. 非标准表头 ccvt -f wgs84 -t gcj02 -i csv --lat 纬度 --lng 经度 < china.csv # 6. 国土/测绘成果(CGCS2000)→ 高德地图 ccvt -f cgcs2000 -t gcj02 -i csv < survey.csv # 7. GPS 度分秒日志 → WGS84 十进制 ccvt fmt -f dms -t dd "39°54'N 116°24'E" # 8. WGS84 十进制 → MGRS(记录/对表用) ccvt fmt -f dd -t mgrs 39.9087 116.3975 # 9. 跨基准 + 跨格式:GCJ02 度分秒 → WGS84 UTM ccvt fmt -f dms -t dd "39°54'N 116°24'E" | ccvt -f wgs84 -t gcj02 --order latlng ``` ## Rust 库 ```rust // 坐标系互转 use ccvt::convert::wgs84_to_gcj02; let (lng, lat) = wgs84_to_gcj02(116.3975, 39.9087); // 格式互转 use ccvt::fmt::{dd_to_mgrs, dd_to_utm}; let (zone, band, easting, northing) = dd_to_utm(39.9087, 116.3975).unwrap(); let mgrs = dd_to_mgrs(39.9087, 116.3975, 10).unwrap(); // "50SMK4850217797" ``` 库入口 `convert::convert(lng, lat, from, to)` 支持任意坐标系方向;`fmt::run` 为格式互转统一入口。也支持在 Python 中调用: ```python import subprocess subprocess.run(["ccvt", "-f", "wgs84", "-t", "gcj02"], input="116.3975 39.9087") ``` ## 测试 ```bash cargo test ``` 内置已知坐标向量(北京、上海、广州等 7 个多地区固定点 × 6 方向 + CGCS2000 恒等/等价路径),参考值来自独立实现 gcoord,并附交叉验证脚本(`scripts/xcheck_gcoord.sh`)防止算法回归。`fmt` 的 UTM/MGRS 参考值来自 pyproj/mgrs 独立生成(8 个全球点,10 位 MGRS 逐位一致),见 `tests/fmt.rs`。 ## License MIT