地理测绘基础知识(2)-椭球最短距离计算

news2024/12/28 23:41:38

在上一篇中,我们介绍了ECEF坐标系和经纬度的互换。

本篇,主要介绍已知A\B两个点的经纬度,如何求取椭球上的最短距离、路径。

在标准椭球面上,从A点运动到B点,距离如何,轨迹、每个阶段的方向又是如何呢? 要讨论方向,会引出两个概念。第一个是切平面坐标系,这是讨论"方向"的基础。第二个是运动,即考虑不同时刻、不同位置之间的关系与变化规律。

1 切面坐标系

站在地表,一般使用的是东北坐标系ENU,即切平面坐标。从ECEF坐标转换为ENU (East-North-Up)坐标,如下如所示:

ENU

图中,由法向量 t T ⃗ \vec{tT} tT 定义的切平面构成了“天圆地方”的参考平面。法向量就是这个坐标系的Z轴。由于尺度不变,这个坐标系和ECEF坐标系是一个旋转关系。

E(East) 单位矢量在经度、纬度均为0度时,切面坐标系的E轴恰好指向正东,就是ECEF的Y方向,取值{0,1,0} 。当经度提高,在X-方向开始有了投影。坐标轴E和纬度无关。旋转经度 θ \theta θ后得到;ECEF坐标系下,E轴的单位矢量:

E ⃗ = { − sin ⁡ θ , cos ⁡ θ , 0 } \vec E=\{-\sin \theta,\cos \theta,0\} E ={sinθ,cosθ,0}

N(North) 单位矢量在经度、纬度均为0度时,切面坐标系的E轴恰好指向正北,就是ECEF的Z方向,取值{0,0,1} 。当纬度上升时,在X-方向开始有了投影;ECEF坐标系下,N轴的单位矢量:

N ⃗ = { − sin ⁡ φ c o s θ , − sin ⁡ φ sin ⁡ θ , cos ⁡ φ } \vec N=\{-\sin \varphi cos\theta,-\sin \varphi \sin \theta,\cos \varphi\} N ={sinφcosθ,sinφsinθ,cosφ}

U(Up) 单位矢量在经度、纬度均为0度时,切面坐标系的E轴恰好指向{1,0,0}方向。经过纬度旋转、经度旋转后,ECEF坐标系下,U轴的单位矢量:

U ⃗ = { cos ⁡ φ c o s θ , cos ⁡ φ sin ⁡ θ , sin ⁡ φ } \vec U=\{\cos \varphi cos\theta,\cos \varphi \sin \theta,\sin \varphi\} U ={cosφcosθ,cosφsinθ,sinφ}

要计算站在t位置下,查看任意一点 M 的 ENU 坐标,只要执行运算

M E N U ⃗ T = [ E ⃗ N ⃗ U ⃗ ] × ( M E C E F ⃗ − t ⃗ ) T = R × ( M E C E F ⃗ − t ⃗ ) T \vec {M_{ENU}}^T=\begin{bmatrix} {\vec {E} \\ \vec N \\ \vec U}\end{bmatrix} \times \left ( \vec {M_{ECEF}} - \vec t \right )^T =R \times \left ( \vec {M_{ECEF}} - \vec t \right )^T MENU T=[E N U ]×(MECEF t )T=R×(MECEF t )T

上式中坐标都是行向量,转置后是列向量。需要注意的是,这个旋转矩阵R的左逆、右逆都是自身的转置,故而两类坐标的转换就很方便了。

R = [ − sin ⁡ θ cos ⁡ θ 0 − sin ⁡ φ c o s θ − sin ⁡ φ sin ⁡ θ cos ⁡ φ cos ⁡ φ c o s θ cos ⁡ φ sin ⁡ θ sin ⁡ φ ] R = \begin{bmatrix} {-\sin \theta} & {\cos \theta} & 0\\ {-\sin \varphi cos\theta} & {-\sin \varphi \sin \theta} & {\cos \varphi} \\ \cos \varphi cos\theta & \cos \varphi \sin \theta & \sin \varphi \end{bmatrix} R= sinθsinφcosθcosφcosθcosθsinφsinθcosφsinθ0cosφsinφ

R × R T = R T × R = I R\times R^T=R^T \times R=I R×RT=RT×R=I

2 计算椭球轨迹

椭球的最短路径是一个三维空间曲线。在轨迹的各个位置上,由于经纬度不同,椭球的曲率不断变化。同时,理想参考椭球是局部平坦的凸曲面,没有陡峭的局部峰和谷,这使得可以通过"碎步迭代"的方法,较为精确地获得最短路径。

迭代命题:已知起点A、终点B的经纬度,求取在高度H上从A运动到B的最短椭球路径,并计算总距离。
AB

设置距离数值积分量 D D D 初始化为0.

迭代步骤:

(1) 在当前ENU坐标系下确定方向

把 A,B换算到ECEF下,此刻ECEF向量 B − A ⃗ \vec{B-A} BA 在切平面上的投影指示了最佳方向。在A点建立ENU坐标系,A是原点,此时,B的ENU坐标:

B ⃗ E N U = [ E B N B U B ] = R A × ( B ⃗ − A ⃗ ) T \vec {B}_{ENU}=\begin{bmatrix} {E_B \\ N_B \\ U_B}\end{bmatrix}=R_A \times \left ( \vec {B} - \vec A \right )^T B ENU=[EBNBUB]=RA×(B A )T

在ENU坐标系里,方向定义为正北为0度,顺时针递增:

tan ⁡ C = E B N B \tan C = \frac {E_B} {N_B} tanC=NBEB

计算出C后,即可计算ENU单位矢量

C E N U ⃗ = { sin ⁡ C , cos ⁡ C , 0 } \vec{C_{ENU}}=\{ \sin C, \cos C,0 \} CENU ={sinC,cosC,0}

该单位矢量转换到 ECEF下为

C T ⃗ = R A T C E N U ⃗ \vec {C^T} = R_A^T \vec {C_{ENU}} CT =RATCENU

(2) 小步推进

已经知道当前起点A、初始方向C后,在以当前位置A为原点的ENU坐标系下,沿着设置的方向前进一个小距离 Δ \Delta Δ, 得到下一个位置 A’。

由于 Δ \Delta Δ很小,我们认为当前行进的距离,就是以A所在位置为切面的正球上行进的距离。

A 的正球坐标为 A s ⃗ = A ⃗ + { 0 , 0 , − d } \vec {A_s}= \vec A +\{0,0,-d\} As =A +{0,0,d}

同时,方向C的单位矢量不受平移的影响,指向不变, C s ⃗ = C ⃗ \vec {C_s} = \vec C Cs =C

沿着方向矢量 C ⃗ s \vec C_s C s、正球矢量 A s ⃗ \vec {A_s} As 生成的正圆,从矢量 A s ⃗ \vec {A_s} As 处,旋转 ω \omega ω弧度,就是下一个位置的正球坐标。旋转的弧度可以用下式求解。

c o s ω = Δ r A + H cos \omega=\frac{\Delta}{r_A+H} cosω=rA+HΔ

这里关键是通过弧度得到旋转后的矢量A’,需要用到三维旋转,也就是罗德里格旋转公式.

μ ⃗ = A ⃗ s ⊗ C s ⃗ ∣ A ⃗ s ∣ \vec \mu= \frac{\vec A_s \otimes \vec {C_s}}{\left|\vec A_s\right|} μ = A s A sCs

A s ′ ⃗ = c o s ω ⋅ A s ⃗ + ( 1 − cos ⁡ ω ) ( μ ⃗ ⊙ A s ⃗ ) + s i n ω ⋅ μ ⃗ ⊗ A s ⃗ \vec {A_s'}= cos \omega \cdot \vec {A_s} + (1-\cos \omega) (\vec \mu\odot \vec {A_s})+sin\omega \cdot \vec \mu \otimes \vec {A_s} As =cosωAs +(1cosω)(μ As )+sinωμ As

由于法向量本身就是垂直的,因此投影项为0,上式简化为:
A s ′ ⃗ = c o s ω ⋅ A s ⃗ + s i n ω ⋅ μ ⃗ ⊗ A s ⃗ \vec {A'_s}= cos \omega \cdot \vec {A_s}+sin\omega \cdot \vec \mu \otimes \vec {A_s} As =cosωAs +sinωμ As

最后,把正球下的坐标系平移到ECEF

A ’ ⃗ = A s ′ ⃗ + { 0 , 0 , d } \vec {A’}= \vec {A'_s} +\{0,0,d\} A =As +{0,0,d}

通过A’的ECEF,计算A’的经纬度坐标,并设置高度为H。此时,A’的经纬度就是下一位置。

(3) 距离累加

由于 Δ \Delta Δ很小,我们认为当前行进的距离,就是以A所在位置为切面的正球上行进的距离。

D = D + ( r A + H ) ω D=D+(r_A+H)\omega D=D+(rA+H)ω

(4) 继续迭代

推进A到新的位置 A’

A = A ′ A=A' A=A

并转到(1)。

(5)收敛条件

当A、B距离小于 Δ \Delta Δ时,以AB的正球距离为距离,最终确定总距离。

3 进行测试

设置起点与终点,进行测试:

void demo_ellips_geodesic()
{
	printf("\n\n");
	const double LLA_A[] = {31.847774515, 117.292115092, 10000};
	const double LLA_B[] = {37.807300349, -122.366731167,10000};

	const int maxRes = 32768;
	double (* lla)[3] = new double [maxRes][3];
	double (* ecef)[3] = new double [maxRes][3];
	double * distance = new double [maxRes];
	double * direction = new double [maxRes];
	double * err = new double [maxRes];
	using namespace CES_GEOCALC;

	const int step = 1000;

	int res = ellips_geodesic(LLA_A,LLA_B,maxRes,100000/step,lla,ecef,distance,direction,err,false,true,step);

	for(int i=0;i<res;++i)
	{
		printf("I=%d LAT=%12.7lf LON=%12.7lf ALT=%7.1lf DIS=%8.1lf DIR=%12.7lf ERR=%lf\n",
			   i,
			   lla[i][0],lla[i][1],lla[i][2],
			   distance[i],direction[i],err[i]
			   );
	}

	delete [] lla;
	delete [] ecef;
	delete [] distance;
	delete [] direction;
	delete [] err;
}

输出:

I=0 LAT=  31.8477745 LON= 117.2921151 ALT=10000.0 DIS=  1000.0 DIR=  43.0147959 ERR=9113951.151266
I=1 LAT=  32.5040600 LON= 118.0168980 ALT=10000.0 DIS=101000.0 DIR=  43.3985947 ERR=9043525.166938
I=2 LAT=  33.1560649 LON= 118.7522233 ALT=10000.0 DIS=201000.0 DIR=  43.7951513 ERR=8972543.435380
I=3 LAT=  33.8036190 LON= 119.4984456 ALT=10000.0 DIS=301000.1 DIR=  44.2047633 ERR=8901010.433060
I=4 LAT=  34.4465456 LON= 120.2559264 ALT=10000.0 DIS=401000.1 DIR=  44.6277359 ERR=8828930.668846
……
I=102 LAT=  37.8073003 LON=-122.3667312 ALT=10000.0 DIS=10143664.8 DIR= 132.8475527 ERR=0.000000

此轨迹在莫卡托投影下会发生形变,如下图:
测地线

4 完整工程

代码与工程参考

https://gitcode.net/coloreaglestdio/geocalc/-/blob/master/geocalc.h

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

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

相关文章

consul安装启动流程

普通软件包安装 首先cd /opt &#xff0c;将安装包放到该目录下 下载consul安装包 进入consul官网找到自己开发平台对应的安装包下载 https://www.consul.io/downloads.html 或使用命令 wget https://releases.hashicorp.com/consul/1.6.2/consul_1.6.2_linux_amd64.zip (如果…

【K8S系列】深入解析k8s网络插件—Weave Net

序言 做一件事并不难&#xff0c;难的是在于坚持。坚持一下也不难&#xff0c;难的是坚持到底。 文章标记颜色说明&#xff1a; 黄色&#xff1a;重要标题红色&#xff1a;用来标记结论绿色&#xff1a;用来标记论点蓝色&#xff1a;用来标记论点 Kubernetes (k8s) 是一个容器编…

MySQL数据库练习

目录 表结构 建表 插入数据 1、用SQL语句创建学生表student&#xff0c;定义主键&#xff0c;姓名不能重名&#xff0c;性别只能输入男或女&#xff0c;所在系的默认值是 “计算机”。 2、修改student 表中年龄&#xff08;age&#xff09;字段属性&#xff0c;数据类型由…

开源数据库Mysql_DBA运维实战 (修改root密码)

MySQL——修改root密码的4种方法 本文以windows为例为大家详细介绍下MySQL修改root密码的4种方法&#xff0c;大家可以可以根据的自己的情况自由选择&#xff0c;希望对大家有所帮助 方法1&#xff1a; 用SET PASSWORD命令 首先登录MySQL。 格式&#xff1a;mysql> set pass…

linux 学习————LNMP之分布式部署

目录 一、概述 二、LNMP环境部署 三、配置nginx 四、 配置php使nginx能够解析.php 五、配置mysql 六、配置discuz进行登录论坛访问测试 一、概述 LNMP代表 Linux、Nginx、MySQL、PHP&#xff0c;是一种常用的服务器架构。它由以下组件组成&#xff1a; Linux&#xff1a;作…

【2023新教程】树莓派4B开机启动-树莓派第一次启动-树莓派不使用显示器启动-树莓派从购买到启动一步一步完全版!

背景 闲来无事&#xff0c;在咸鱼上买了一个树莓派4B。买来配件都十分齐全&#xff0c;于是就想着启动来测试一下。下面是树莓派无显示器第一次启动的全过程&#xff0c;包含安装系统。 网上的教程大多需要额外使用显示器、鼠标、键盘之类的外设。然而&#xff0c;树莓派本身就…

阿里云服务器是什么?阿里云服务器有什么优缺点?

阿里云服务器是什么&#xff1f;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;云服务器可以降低IT成本提升运维效率&#xff0c;免去企业或个人前期采购IT硬件的成本&#xff0c;阿里云服务器让用户像使用水、电、天然气等公共资源一样便捷、高效地使用服务器…

[数据集][目标检测]骑电动车摩托车不戴头盔数据集VOC格式1385张

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;1385 标注数量(xml文件个数)&#xff1a;1385 标注类别数&#xff1a;2 标注类别名称:["y","n&q…

工业物联网数据桥接教程:Modbus 桥接到 MQTT

Modbus 介绍 Modbus 是一种串行通信协议&#xff0c;用于连接工业自动化设备&#xff0c;最初由 Modicon 公司开发&#xff0c;诞生于 1979 年&#xff0c;现在已成为通用的通讯标准之一&#xff0c;广泛用于工业自动化场景。 Modbus 采用主从模式&#xff0c;支持多种传输方…

jacoco功能测试-代码覆盖率

1、下载 jacoco 官网地址&#xff1a;EclEmma - JaCoCo Java Code Coverage Library 2、拷贝 jar 包 下载好后&#xff0c;找到这两个文件&#xff0c;然后找到被测项目 3、启动 jacocoagent&#xff0c;监控被测项目 java -javaagent:jacocoagent.jarincludes*,outputtcp…

BGP总结

前言 我们从动态路由协议的应用范围可以分为IGP&#xff08;内部网关协议&#xff09;和EGP&#xff08;外部网关协议&#xff09;。 IGP协议追求&#xff1a; 无环&#xff08;选路佳&#xff09;收敛快占用资源少 EGP协议的追求 可控性强&#xff08;管理员可以方便进行…

Rx.NET in Action 第二章学习笔记

Part 1 初入反应式扩展 2 Hello, Rx 本章节涵盖的内容: 不使用Rx的工作方式向项目中添加Rx创建你的第一个Rx应用程序 Rx 的目标是协调和统筹来自社交网络、传感器、用户界面事件等不同来源的基于事件的异步计算。例如&#xff0c;建筑物周围的监控摄像头和移动传感器会在有人靠…

激活函数总结(三):激活函数补充

激活函数总结&#xff08;三&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Softmax激活函数2.2 Softplus激活函数2.3 Mish激活函数2.4 Maxout激活函数 3. 总结 1 引言 在前面的文章中已经介绍了过去大家较为常见的激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PR…

42 | 航空公司客户价值分析

民航的竞争除了三大航空公司之间的竞争之外,还将加入新崛起的各类小型航空公司、民营航空公司,甚至国外航空巨头。航空产品生产过剩,产品同质化特征愈加明显,于是航空公司从价格、服务间的竞争逐渐转向对客户的竞争。 目前航空公司已积累了大量的会员档案信息和其乘坐航班…

vscode debug python 带参数

两种方法 第一种&#xff1a; 1&#xff0c;侧边栏选择运行和调试 2&#xff0c;请先创建一个launch.json文件 3&#xff0c;并选择配置文件为python文件 此时你的工作目录下会多一个目录.vscode和该目录下一个launch.json文件&#xff0c;该文件则配置了你的debug配置。在…

JZ40最小的K个数

题目地址&#xff1a;最小的K个数_牛客题霸_牛客网 题目回顾&#xff1a; 解题思路&#xff1a; 注意本题不需要去重。 最简单的方法&#xff1a;排序后数组顺序是由小到大的&#xff0c;也就是说此时数组前k个数就是我们要求的结果。 整体代码&#xff1a; public ArrayLi…

WPF 界面结构化处理

文章目录 概要一、xaml界面结构化处理二、逻辑树与视觉树 概要 WPF 框架是开源的&#xff0c;但是不能跨平台&#xff0c;可以使用MAUI&#xff0c;这个框架可以跨平台&#xff0c;WPF源码可以在github上下载&#xff0c;下载地址&#xff1a;https://gitbub.com/dotnet/wpf。…

【推荐系统】wss课程-排序

排序01-多目标模型 这节课的内容是推荐系统排序的多目标模型。这节课的内容分两部分。 - 第一部分是模型结构。模型把用户特征、物品特征、统计特征、场景特征作为输入&#xff0c;输出对多个指标的预估。 - 第二部分内容是降采样和校准。在实际的推荐系统中&#xff0c;正负…

Mybatis三剑客(一)在springboot中自动生成Mybatis【generator】

1、pom.xml中新增plugin <plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><overwrite>true</overwrite><…

Dynamic Web TWAIN Crack

Dynamic Web TWAIN Crack 文件编辑 提供 GUI 和非 GUI 图像编辑器 内置基本图像编辑界面&#xff0c;如旋转、裁剪、镜像、翻转、擦除和更改图像大小 支持向图像添加彩色矩形 支持文字注释 提供图像交换功能 支持清除图像的指定区域并用颜色填充清除的区域 内置变焦 提供多图像…