gnssroute · 无人机航线 GNSS 工具库
一个零第三方依赖(仅用 Python 标准库)的轻量级库,专门适配大疆(DJI)无人机航测文件(.OBS / .NAV / .MRK),用于从 GNSS 观测数据反演无人机航线、按精度重采样、用真值航点优化,并导出 Cesium 可视化格式。
🎯 典型场景:用大疆自动航线跑完航测后,本工具可直接读取其生成的
OBS / NAV / MRK三类文件, 快速得到可在 Cesium 中回放的高精度航线动画——无需额外转换,开箱即用。
✨ 核心特性
- 大疆文件直读 — 专门适配 DJI 自动航线生成的 RINEX 3.05
.OBS/.NAV文件和.MRKRTK 真值航点,无需格式转换; - 单点定位 SPP — 从 RINEX 观测文件(
.obs+.nav)或简易 CSV 反演无人机实时航线; - 按精度重采样 — 按固定时间间隔(1 s / 0.2 s …)或固定距离(≤1 m / 5 m …)生成指定精度的航线;
- 航点优化 — 用
.mrk真值航点修正 SPP 实时航线(MRK 视为真解),并可再次下采样; - Cesium 可视化 — 输出 CZML / GeoJSON 航线文件,直接在 Cesium 中加载(可在 Cesium Sandcastle 中直接预览);
- 配置文件驱动 — 支持 TOML / JSON / INI 配置,Python 可读取并按配置运行整条流水线。
📦 安装
pip install gnssroute
库本身无需任何第三方包(仅 Python 标准库)。仅当你想用 TOML 写配置时才需要 tomli_w,想用 YAML 配置时需要 pyyaml:
pip install gnssroute[toml-write,yaml]
从源码安装(开发模式):
git clone https://github.com/Jia-SH/dji-gnssroute.git
cd gnssroute
pip install -e .
🚀 快速开始
完整流水线(配置文件驱动)
from gnssroute import pipeline
result = pipeline.process("config.toml")
print(result["final"]) # 优化后的 Trajectory
print(result["written"]) # 输出的 CZML / GeoJSON / CSV 路径
分步调用(更灵活)
from gnssroute.io import csv_io, rinex_nav, rinex_obs
from gnssroute.positioning import spp, satellite
from gnssroute.route import resample, optimize
from gnssroute.export import cesium
# ① SPP:从观测反演实时航线
epochs = csv_io.read_obs_csv("sample_data/obs.csv")
provider = satellite.SyntheticConstellation() # 真实场景用 EphemerisProvider(read_nav(...))
traj = spp.solve_spp(epochs, provider, el_mask_deg=10.0, name="spp_realtime")
# ② 按精度重采样(距离 ≤ 1 m)
traj_1m = resample.resample_by_distance(traj, max_dist=1.0)
# ③ 用 MRK 真值航点优化
waypoints = csv_io.read_waypoints_csv("sample_data/mrk.csv")
traj_opt = optimize.optimize_with_waypoints(traj_1m, waypoints)
# ④ 导出 Cesium 可加载格式
cesium.write_czml(traj_opt, "route.czml")
cesium.write_geojson(traj_opt, "route.geojson")
命令行走通示例
# 生成自包含示例数据
python examples/generate_sample_data.py sample_data
# 跑完整 ①~④ 并打印误差对比
python examples/run_full_pipeline.py
# 配置驱动的 CLI 调用
python -m gnssroute.cli examples/output/demo_config.toml --print-points
示例输出(端到端仿真验证):
[1] SPP recovered 300 points
[2] resampled to 450 points (<=1 m spacing)
[3] optimised with 15 MRK waypoints
[4] wrote Cesium/GeoJSON/CSV to examples/output
[5] RMS error vs truth: SPP=5.58 m -> optimised=0.85 m
航点优化将 RMS 误差从 5.58 m 降至 0.85 m,精度提升约 6.6 倍。
🚁 真实大疆航测端到端案例
examples/run_dji_real.py + examples/config_dji_real.toml 是一条端到端真实案例,
直接读取大疆自动航线生成的三类文件:
| DJI 文件 | 用途 | 本库处理方式 |
|---|---|---|
*.OBS |
RINEX 3.05 多系统观测(伪距) | rinex_obs.read_obs() — 已适配 DJI 的 PRN 格式 |
*.NAV |
RINEX 3.05 广播星历 | rinex_nav.read_nav() — 已适配 DJI 的单/双位 PRN 写法 |
*.MRK |
RTK 固定解真值航点 | mrk.read_mrk() — 专门解析 DJI 的制表符分隔格式 |
跑通「SPP 单点定位 → 1 Hz 重采样 → MRK 真值精化 → Cesium / GeoJSON / CSV 导出」,并打印各阶段实测精度:
python examples/run_dji_real.py path/to/your/dji_survey_folder
📖 完整数据说明、处理流程、精度结论与踩坑笔记见 examples/case_study_dji_mehu_bridge.md(基于真实的湖州梅湖大桥桥梁巡检飞行)。
🧩 核心 API
| 模块 | 关键函数 | 说明 |
|---|---|---|
gnssroute.positioning.spp |
solve_spp(epochs, provider, el_mask_deg, name) |
对每历元做加权最小二乘 SPP,返回 Trajectory |
gnssroute.positioning.satellite |
SatEphemeris, EphemerisProvider, SyntheticConstellation |
卫星位置/钟差计算;真实数据走 EphemerisProvider,示例走 SyntheticConstellation |
gnssroute.route.resample |
resample_by_interval(traj, sec), resample_by_distance(traj, m) |
按时间/距离重采样,保证点距不超过阈值 |
gnssroute.route.optimize |
optimize_with_waypoints(traj, wps), downsample(...) |
用 MRK 残差场(ECEF 分段线性)修正航线 |
gnssroute.export.cesium |
to_czml, to_geojson, write_czml, write_geojson |
输出 Cesium/CesiumJS 可加载航线 |
gnssroute.export.writers |
write_trajectory_csv, write_trajectory_json |
通用数据写出 |
gnssroute.io |
read_obs, read_nav, read_mrk, read_obs_csv, read_trajectory_csv, read_waypoints_csv |
RINEX / MRK / 简易 CSV 读取 |
gnssroute.config |
load_config, save_config, normalize |
配置读写与默认值合并校验 |
gnssroute.pipeline |
process, run_steps |
端到端流水线编排 |
⚙️ 配置文件格式(TOML)
examples/config_demo.toml 给出了完整示例,要点如下:
[input]
obs_path = "sample_data/observation.obs" # RINEX 观测
nav_path = "sample_data/brdc.nav" # RINEX 星历
mrk_path = "sample_data/markers.mrk" # 真值航点
# directory = "sample_data" # 也可按后缀自动发现文件
[spp]
el_mask_deg = 10.0 # 高度角截止
[resample]
by_interval = 0.2 # 秒(与 by_distance 二选一)
# by_distance = 1.0 # 米
[optimize]
enabled = true
downsample_distance = 1.0 # 优化后再次下采样(可选)
[export]
czml = "output/route.czml"
geojson = "output/route.geojson"
csv = "output/route.csv"
base_datetime = "2026-04-16T03:11:00Z"
读取 / 写出配置:
from gnssroute.config import load_config, save_config
cfg = load_config("config.toml")
cfg["resample"]["by_distance"] = 5.0
save_config(cfg, "config_new.toml")
🗺️ 输出与 Cesium 加载
route.czml:CZML 文档,含cartographicDegrees采样位置 + 发光路径path, 在 CesiumJS 中直接Cesium.CzmlDataSource.load('route.czml')即可看到动画航线。route.geojson:LineString要素,可在 Cesium / QGIS 中加载。route.csv:t, lat, lon, height纯数据,便于二次处理。
📂 工程结构
gnssroute/
├── gnssroute/
│ ├── common/ # 地球模型(WGS84)、线性代数、时间、数据类型、插值
│ ├── io/ # RINEX obs/nav、MRK、简易 CSV 读写
│ ├── positioning/ # 卫星星历 + SPP 最小二乘解算
│ ├── route/ # 重采样(时间/距离)、航点优化
│ ├── export/ # Cesium(CZML/GeoJSON)、通用写出
│ ├── config/ # 配置加载/默认值/校验
│ ├── pipeline.py # 端到端编排
│ └── cli.py # 命令行入口
├── examples/ # 自包含示例与完整演示(含真实大疆案例)
└── tests/ # 单元测试(零依赖 runner:tests/run_tests.py)
🧪 测试
python tests/run_tests.py # 零依赖运行全部用例
# 或(已安装 pytest):
python -m pytest tests
测试覆盖:地球模型往返、最小二乘、重采样精度、MRK 优化误差下降、CZML/GeoJSON 结构,以及端到端 SPP 仿真(自生成观测 → SPP 反演 → 优化,验证误差显著下降)。
📄 许可证
本项目基于 MIT License 开源。
🙏 说明
本库内置的
SyntheticConstellation用于无外部 RINEX 时的自包含演示与测试; 接入真实数据时,用EphemerisProvider(rinex_nav.read_nav("brdc.nav"))提供卫星位置即可。
Release files for gnssroute 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| gnssroute-0.1.1.tar.gz | 40.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gnssroute-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 75.3 kB
Release files / gnssroute-0.1.1.tar.gz
| Download URL | gnssroute-0.1.1.tar.gz |
|---|---|
| Size | 40.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d4113352fe16bbf149a9305d89ea7706167e476d9f160b845b230906c557e169
|
|
BLAKE2b-256 checksum How to use checksums |
01a71d30211cb87ffb8e0aa7a8faffbe9723a9b5beb54eedc61ec03ce0ee26e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / gnssroute-0.1.1-py3-none-any.whl
| Download URL | gnssroute-0.1.1-py3-none-any.whl |
|---|---|
| Size | 34.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b463ee44d7c4cbcce3f5ef09331694bb14de940fab3100edea6b903d8f326030
|
|
BLAKE2b-256 checksum How to use checksums |
b6e57e9c5bea79022bf3ec53cb7336b00435dcef8c906de6379992e0bdba57fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency log