[学习]RTKLib详解:convkml.c、convrnx.c与geoid.c


本文是 RTKLlib详解 系列文章的一篇,目前该系列文章还在持续总结写作中,以发表的如下,有兴趣的可以翻阅。

[学习] RTKlib详解:功能、工具与源码结构解析
[学习]RTKLib详解:pntpos.c与postpos.c
[学习]RTKLib详解:rtkcmn.c与rtkpos.c
[学习]RTKLib详解:ppp.c与ppp_ar.c
[学习]RTKLib详解:ephemeris.c与rinex.c


文章目录

    • Part A: convkml.c 文件解析
      • 一、文件整体说明
      • 二、执行流程与函数调用关系
      • 三、主要函数说明
        • 3.1 `main`
        • 3.2 `readcmdline`
        • 3.3 `readobsfile`
        • 3.4 `convkml`
        • 3.5 `writekmlhead`
        • 3.6 `writekmlbody`
        • 3.7 `writekmltail`
      • 四、关键算法数学原理与推导
        • 地理坐标系到 ECEF 的转换
    • Part B: convrnx.c 文件解析
      • 一、文件整体说明
      • 二、执行流程与函数调用关系
      • 三、主要函数说明
        • 3.1 `main`
        • 3.2 `readcmdline`
        • 3.3 `initrnx`
        • 3.4 `openfiles`
        • 3.5 `convertrnx`
        • 3.6 `readrawdata`
        • 3.7 `outputrnx`
        • 3.8 `closefiles`
      • 四、关键算法数学原理与推导
        • 时间系统转换
    • Part C: geoid.c 文件解析
      • 一、文件整体说明
      • 二、执行流程与函数调用关系
      • 三、主要函数说明
        • 3.1 `geoid_hgt`
        • 3.2 `load_geoid`
        • 3.3 `interp_geoid`
        • 3.4 `bilin_interp`
      • 四、关键算法数学原理与推导
        • 双线性插值


Part A: convkml.c 文件解析

一、文件整体说明

convkml.c 是 RTKLIB 中用于将 GNSS 数据转换为 KML(Keyhole Markup Language)格式的工具,便于在 Google Earth 等地理可视化软件中展示轨迹、观测点等信息。该文件主要实现了从 RINEX 或 RTKLIB 内部数据结构到 KML 标记语言的转换。

主要功能:

  • 将 GNSS 观测数据转换为 KML 格式。
  • 支持多种显示样式,如路径、标记点、高度剖面图等。
  • 可选输出模式包括静态点、动态路径等。

主要特色:

  • 支持多频段和多系统数据。
  • 提供灵活的样式配置选项。
  • 可导出不同时间分辨率的数据点。

二、执行流程与函数调用关系

程序执行流程如下:

  1. 初始化参数设置。
  2. 读取输入数据(如 RINEX 文件)。
  3. 处理数据并提取位置信息。
  4. 生成 KML 文件内容。
  5. 写入 KML 文件并关闭资源。

函数调用关系如下所示:

main
readcmdline
initopt
readobsfile
convkml
writekmlhead
writekmlbody
writekmldata
writekmltail

其中:

  • readcmdline: 解析命令行参数。
  • initopt: 初始化输出选项。
  • readobsfile: 读取观测文件(RINEX等)。
  • convkml: 主要转换逻辑入口。
  • writekml* 函数负责生成 KML 的各个部分。

三、主要函数说明

3.1 main
int main(int argc, char *argv[])

功能:
主函数,负责接收命令行参数并调度各模块完成 KML 转换。

输入参数:

  • argc: 命令行参数个数。
  • argv[]: 命令行参数数组。

输出参数:

  • 返回状态码(0 表示成功,非零表示错误)。

3.2 readcmdline
void readcmdline(int argc, char *argv[], opt_t *opt)

功能:
解析命令行参数并填充配置结构体 opt

输入参数:

  • argc, argv[]: 命令行参数。
  • opt: 输出参数,包含所有配置选项。

3.3 readobsfile
int readobsfile(const char *file, obs_t *obs, nav_t *nav, opt_t *opt)

功能:
读取观测文件(如 RINEX),并将数据存储到 obsnav 结构体中。

输入参数:

  • file: 输入文件路径。
  • obs: 存储观测数据的结构体指针。
  • nav: 存储导航数据的结构体指针。
  • opt: 配置选项。

返回值:

  • 成功返回 1,失败返回 0。

3.4 convkml
int convkml(FILE *fp, const obs_t *obs, const nav_t *nav, const opt_t *opt)

功能:
核心转换函数,将 GNSS 数据转换为 KML 格式并写入文件。

输入参数:

  • fp: 文件指针。
  • obs, nav, opt: 输入数据与配置。

返回值:

  • 成功返回 1,失败返回 0。

3.5 writekmlhead
void writekmlhead(FILE *fp, const opt_t *opt)

功能:
写入 KML 文件头部信息,包括文档声明、命名空间等。

输入参数:

  • fp: 文件指针。
  • opt: 配置信息。

3.6 writekmlbody
void writekmlbody(FILE *fp, const obs_t *obs, const nav_t *nav, const opt_t *opt)

功能:
写入 KML 主体内容,包括路径、标记点等。

输入参数:

  • fp, obs, nav, opt: 同上。

3.7 writekmltail
void writekmltail(FILE *fp)

功能:
写入 KML 文件尾部标签,结束文档。

输入参数:

  • fp: 文件指针。

四、关键算法数学原理与推导

地理坐标系到 ECEF 的转换

GNSS 接收机通常输出经纬度和高度(LLH),但 KML 使用的是地心坐标系(ECEF)。因此需要进行 LLH 到 ECEF 的转换。

公式如下:

N = a 1 − e 2 sin ⁡ 2 ( ϕ ) x = ( N + h ) cos ⁡ ( ϕ ) cos ⁡ ( λ ) y = ( N + h ) cos ⁡ ( ϕ ) sin ⁡ ( λ ) z = [ N ( 1 − e 2 ) + h ] sin ⁡ ( ϕ ) \begin{aligned} &N = \frac{a}{\sqrt{1 - e^2 \sin^2(\phi)}} \\ &x = (N + h)\cos(\phi)\cos(\lambda) \\ &y = (N + h)\cos(\phi)\sin(\lambda) \\ &z = \left[N(1 - e^2) + h\right]\sin(\phi) \end{aligned} N=1e2sin2(ϕ) ax=(N+h)cos(ϕ)cos(λ)y=(N+h)cos(ϕ)sin(λ)z=[N(1e2)+h]sin(ϕ)

其中:

  • ϕ \phi ϕ: 纬度(弧度)
  • λ \lambda λ: 经度(弧度)
  • h h h: 椭球高
  • a a a: WGS84 长半轴
  • e 2 = 1 − b 2 a 2 e^2 = 1 - \frac{b^2}{a^2} e2=1a2b2: 第一偏心率平方

这个转换是绘制轨迹的基础。


Part B: convrnx.c 文件解析

一、文件整体说明

convrnx.c 是 RTKLIB 中用于将各种原始观测数据(如 BINEX、UBX、RTCM 等)转换为 RINEX 格式的工具。RINEX 是 GNSS 数据的标准格式,广泛用于后处理和分析。

主要功能:

  • 多种原始数据格式转 RINEX。
  • 支持多频段、多系统。
  • 自动识别输入数据格式。

主要特色:

  • 支持自动探测输入数据类型。
  • 提供灵活的时间过滤与输出选项。
  • 可以输出压缩的 RINEX(.crx/.gz)。

二、执行流程与函数调用关系

程序执行流程如下:

  1. 解析命令行参数。
  2. 打开输入/输出文件。
  3. 读取并解析原始数据流。
  4. 转换为 RINEX 格式并写入文件。
  5. 清理资源并退出。

函数调用关系如下:

main
readcmdline
initrnx
openfiles
convertrnx
readrawdata
outputrnx
closefiles

三、主要函数说明

3.1 main
int main(int argc, char *argv[])

功能:
主函数,解析命令行参数并控制整个转换流程。

输入输出:

  • 同前文。

3.2 readcmdline
void readcmdline(int argc, char *argv[], rnxopt_t *opt)

功能:
解析命令行参数并填充 rnxopt_t 结构体。

输入输出:

  • 同前文。

3.3 initrnx
int initrnx(rnxopt_t *opt)

功能:
根据用户配置初始化 RINEX 转换参数。

输入参数:

  • opt: 转换配置结构体。

3.4 openfiles
int openfiles(const char *infile, const char *outfile, FILE **fpin, FILE **fpout, rnxopt_t *opt)

功能:
打开输入和输出文件,支持压缩格式。

输入参数:

  • infile, outfile: 文件路径。
  • fpin, fpout: 文件指针地址。
  • opt: 配置。

3.5 convertrnx
int convertrnx(FILE *fpin, FILE *fpout, rnxopt_t *opt)

功能:
主转换循环,读取原始数据并写入 RINEX。

输入输出:

  • 同上。

3.6 readrawdata
int readrawdata(FILE *fp, unsigned char *buff, int nmax, int format, raw_t *raw)

功能:
读取原始观测数据并解析为内部结构。

输入参数:

  • fp: 输入文件指针。
  • buff: 缓冲区。
  • nmax: 最大读取长度。
  • format: 数据格式(如 RTCM3, UBX 等)。
  • raw: 输出解析后的数据。

返回值:

  • 成功返回字节数,失败返回负值。

3.7 outputrnx
int outputrnx(FILE *fp, const raw_t *raw, const rnxopt_t *opt)

功能:
将解析后的数据按 RINEX 格式写入输出文件。

输入参数:

  • fp, raw, opt: 同上。

3.8 closefiles
void closefiles(FILE *fpin, FILE *fpout)

功能:
关闭输入输出文件句柄。


四、关键算法数学原理与推导

时间系统转换

原始数据中的时间戳可能使用 GPS 时间、UTC、本地时间等,而 RINEX 要求使用 GPS 时间或 UTC。因此需要进行时间系统转换。

GPS 时间与 UTC 的关系为:

t G P S = t U T C + Δ t l e a p t_{GPS} = t_{UTC} + \Delta t_{leap} tGPS=tUTC+Δtleap

其中 Δ t l e a p \Delta t_{leap} Δtleap 是闰秒修正值,需通过星历或头文件获取。


Part C: geoid.c 文件解析

一、文件整体说明

geoid.c 实现了大地高与正常高的相互转换,依赖于大地水准面模型(如 EGM96、EGM2008)。它提供了基于插值方法的大地高与正高之间的转换功能。

主要功能:

  • 计算某一点的大地水准面高(N)。
  • 支持多种大地水准面模型。
  • 提供双线性插值功能。

主要特色:

  • 支持网格化模型数据。
  • 可扩展性强,易于添加新模型。
  • 高效的插值算法。

二、执行流程与函数调用关系

程序执行流程如下:

  1. 加载大地水准面模型文件。
  2. 对给定的地理坐标进行插值计算。
  3. 输出大地水准面高。

函数调用关系如下:

geoid_hgt
load_geoid
interp_geoid
bilin_interp

三、主要函数说明

3.1 geoid_hgt
double geoid_hgt(double lat, double lon, const char *model)

功能:
对外接口,输入经纬度和模型名,返回大地水准面高。

输入参数:

  • lat, lon: 地理纬度和经度(十进制度)。
  • model: 模型名称(如 “egm96_15”)。

返回值:

  • 大地水准面高 N(米)。

3.2 load_geoid
int load_geoid(const char *model, geoid_t *geoid)

功能:
加载指定模型的网格数据到内存。

输入参数:

  • model: 模型名。
  • geoid: 存储模型数据的结构体。

返回值:

  • 成功返回 1,失败返回 0。

3.3 interp_geoid
double interp_geoid(double lat, double lon, const geoid_t *geoid)

功能:
调用双线性插值函数计算某点的大地水准面高。

输入参数:

  • lat, lon: 插值点坐标。
  • geoid: 模型数据结构体。

返回值:

  • 插值结果(米)。

3.4 bilin_interp
double bilin_interp(double x, double y, double *v, int nx, int ny)

功能:
实现双线性插值算法。

输入参数:

  • x, y: 插值点坐标。
  • v: 网格数据数组。
  • nx, ny: 网格尺寸。

返回值:

  • 插值结果。

四、关键算法数学原理与推导

双线性插值

设四个角点分别为:

  • f ( x 1 , y 1 ) f(x_1, y_1) f(x1,y1)
  • f ( x 2 , y 1 ) f(x_2, y_1) f(x2,y1)
  • f ( x 1 , y 2 ) f(x_1, y_2) f(x1,y2)
  • f ( x 2 , y 2 ) f(x_2, y_2) f(x2,y2)

目标点 ( x , y ) (x, y) (x,y) 在矩形区域内,则插值公式为:

f ( x , y ) = ( x 2 − x ) ( y 2 − y ) Δ x Δ y f ( x 1 , y 1 ) + ( x − x 1 ) ( y 2 − y ) Δ x Δ y f ( x 2 , y 1 ) + ( x 2 − x ) ( y − y 1 ) Δ x Δ y f ( x 1 , y 2 ) + ( x − x 1 ) ( y − y 1 ) Δ x Δ y f ( x 2 , y 2 ) f(x,y) = \frac{(x_2 - x)(y_2 - y)}{\Delta x \Delta y} f(x_1,y_1) + \frac{(x - x_1)(y_2 - y)}{\Delta x \Delta y} f(x_2,y_1) + \frac{(x_2 - x)(y - y_1)}{\Delta x \Delta y} f(x_1,y_2) + \frac{(x - x_1)(y - y_1)}{\Delta x \Delta y} f(x_2,y_2) f(x,y)=ΔxΔy(x2x)(y2y)f(x1,y1)+ΔxΔy(xx1)(y2y)f(x2,y1)+ΔxΔy(x2x)(yy1)f(x1,y2)+ΔxΔy(xx1)(yy1)f(x2,y2)

其中 Δ x = x 2 − x 1 \Delta x = x_2 - x_1 Δx=x2x1, Δ y = y 2 − y 1 \Delta y = y_2 - y_1 Δy=y2y1

此方法用于大地水准面模型的离散数据插值。


研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/79453.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 破解aspose.words 18.6 使用

资源包&#xff1a;https://download.csdn.net/download/qq_36598111/90787167 jar包是破解过的&#xff0c;直接可以使用。 引入jar&#xff0c;要引入本地的&#xff0c;不要直接引入仓库的 <dependency><groupId>com.aspose</groupId><artifactId>…

vue使用rules实现表单校验——校验用户名和密码

编写校验规则 常规校验 const rules {username: [{ required: true, message: 请输入用户名, trigger: blur },{ min: 5, max: 16, message: 长度在 5 到 16 个字符, trigger: blur }],password: [{ required: true, message: 请输入密码, trigger: blur },{ min: 5, max: 1…

宝塔服务安装使用的保姆级教程

宝塔介绍&#xff1a; 宝塔面板&#xff08;BT Panel&#xff09; 是一款 国产的服务器运维管理面板&#xff0c;主要用于简化 Linux/Windows 服务器的网站、数据库、FTP、防火墙等管理操作。它通过图形化界面&#xff08;Web端&#xff09;和命令行工具&#xff08;bt 命令&a…

数字化转型-4A架构之数据架构

4A架构系列文章 数字化转型-4A架构&#xff08;业务架构、应用架构、数据架构、技术架构&#xff09; 数字化转型-4A架构之业务架构 数字化转型-4A架构之应用架构 数字化转型-4A架构之数据架构 数字化转型-4A架构之技术架构 数据架构 Data Architecture&#xff08;DA&…

每日脚本 5.11 - 进制转换和ascii字符

前置知识 python中各个进制的开头 二进制 &#xff1a; 0b 八进制 &#xff1a; 0o 十六进制 : 0x 进制转换函数 &#xff1a; bin() 转为2进制 oct() 转换为八进制的函数 hex() 转换为16进制的函数 ascii码和字符之间的转换 &#xff1a; chr(97) 码转为字符 …

Vulnhub Lazysysadmin靶机攻击实战(一)

导语   靶机下载地址 https://download.vulnhub.com/lazysysadmin/Lazysysadmin.zip   靶机信息地址 https://www.vulnhub.com/entry/lazysysadmin-1,205/ 文章目录 信息收集扫描路径提权其他思路探索其他方式找密码总结下载安装好靶机之后启动虚拟机如下所示。 信息收集 我…

【DB2】DB2启动失败报错SQL1042C

在本地某次启动db2时报错SQL1042C&#xff0c;具体报错如下 [db2inst1standby ~]$ db2start 05/07/2025 16:32:53 0 0 SQL1042C An unexpected system error occurred. SQL1032N No start database manager command was issued. SQLSTATE57019在网上百度到说是需要…

Python中的re库详细用法与代码解析

目录 1. 前言 2. 正则表达式的基本概念 2.1 什么是正则表达式&#xff1f; 2.2 常用元字符 3. re库的适应场景 3.1 验证用户输入 3.2 从文本中提取信息 3.3 文本替换与格式化 3.4 分割复杂字符串 3.5 数据清洗与预处理 4. re库的核心功能详解 4.1 re.match()&#…

蓝桥杯2025年第十六届省赛真题-水质检测

C语言代码&#xff1a; #include <stdio.h> #include <string.h>#define MAX_LEN 1000000int main() {char a[MAX_LEN 1], b[MAX_LEN 1];// 使用 scanf 读取字符数组scanf("%s", a);scanf("%s", b);int ans 0;int pre -1;int state -1;i…

65.Three.js案例-使用 MeshNormalMaterial 和 MeshDepthMaterial 创建 3D 图形

65.Three.js案例-使用 MeshNormalMaterial 和 MeshDepthMaterial 创建 3D 图形 实现效果 在该案例中&#xff0c;Three.js 被用来创建一个包含多个 3D 对象的场景。其中包括&#xff1a; 圆环结&#xff08;TorusKnot&#xff09;立方体&#xff08;Box&#xff09;球体&…

Python学习笔记--Django的安装和简单使用(一)

一.简介 Django 是一个用于构建 Web 应用程序的高级 Python Web 框架。Django 提供了一套强大的工具和约定&#xff0c;使得开发者能够快速构建功能齐全且易于维护的网站。Django 遵守 BSD 版权&#xff0c;初次发布于 2005 年 7 月, 并于 2008 年 9 月发布了第一个正式版本 1…

《汽车噪声控制》复习重点

题型 选择 填空 分析 计算 第一章 噪声定义 不需要的声音&#xff0c;妨碍正常工作、学习、生活&#xff0c;危害身体健康的声音&#xff0c;统称为噪声 噪声污染 与大气污染、水污染并称现代社会三大公害 声波基本概念 定义 媒质质点的机械振动由近及远传播&am…

冒泡排序的原理

冒泡排序是一种简单的排序算法&#xff0c;它通过重复地遍历待排序的列表&#xff0c;比较相邻的元素并交换它们的位置来实现排序。具体原理如下&#xff1a; 冒泡排序的基本思想 冒泡排序的核心思想是通过相邻元素的比较和交换&#xff0c;将较大的元素逐步“冒泡”到列表的…

前端npm包发布流程:从准备到上线的完整指南

无论是使用第三方库还是创建和分享自己的工具&#xff0c;npm都为我们提供了一个强大而便捷的平台&#xff0c;然而很多开发者在将自己的代码发布到npm上时往往面临各种困惑和挑战&#xff0c;本篇文章将从准备工作到发布上线&#xff0c;探讨如何让npm包更易发布及避免常见的坑…

使用 CDN 在国内加载本地 PDF 文件并处理批注:PDF.js 5.x 实战指南

PDF.js 是一个强大的开源 JavaScript 库&#xff0c;用于在 Web 浏览器中渲染 PDF 文件。它由 Mozilla 开发&#xff0c;能够将 PDF 文档绘制到 HTML5 Canvas 或 SVG 上&#xff0c;无需任何本机代码或浏览器插件。对于许多需要在网页中展示 PDF 内容的应用场景来说&#xff0c…

网络化:DevOps 工程的必要基础(Networking: The Essential Foundation for DevOps Engineering)

李升伟 编译 理解网络化基础知识 你是否曾想过是什么真正让卓越的DevOps工程师与众人区别开来&#xff1f;答案是网络化。是的&#xff0c;对网络的基本理解不仅仅是有帮助的——它是绝对必要的。在当今以微服务、容器和分布式系统为主宰的互联互通世界中&#xff0c;对网络原…

C++基本知识 —— 缺省参数·函数重载·引用

C基本知识 —— 缺省参数函数重载引用 1. 缺省参数2. 函数重载3. 引用3.1 引用的基础知识3.2 引用的作用3.3 const 引用3.4 指针与引用的关系 1. 缺省参数 什么是缺省参数&#xff1f;缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数的时候&#xff0c;如…

Rust 官方文档:人话版翻译指南

鉴于大部分翻译文档都不太会说人话&#xff0c;本专栏主要内容为 rust 程序设计语言、rust 参考手册、std 库 等官方文档的中译中。

FlySecAgent:——MCP全自动AI Agent的实战利器

最近&#xff0c;出于对人工智能在网络安全领域应用潜力的浓厚兴趣&#xff0c;我利用闲暇时间进行了深入研究&#xff0c;并成功开发了一款小型轻量化的AI Agent安全客户端FlySecAgent。 什么是 FlySecAgent&#xff1f; 这是一个基于大语言模型和MCP&#xff08;Model-Contr…

实战项目5(08)

目录 任务场景一 【r1配置】 【r2配置】 【r3配置】 ​​​​​​​任务场景二 【r1配置】 【r2配置】 ​​​​​​​任务场景一 按照下图完成网络拓扑搭建和配置 任务要求&#xff1a; 通过在路由器R1、R2和R3上配置静态路由&#xff0c;实现网络中各终端PC能够正常…