大地经纬度坐标与地心地固坐标的的转换

简介: 大地经纬度坐标与地心地固坐标的的转换

大地经纬度坐标与地心地固坐标的的转换

目录

1. 概述

要解决这个问题首先得理解地球椭球这个概念,这里直接用武汉大学《大地测量学基础》(孔详元、郭际明、刘宗全)的解释吧:

大地经纬度坐标系是地理坐标系的一种,也就是我们常说的经纬度坐标+高度。经纬度坐标用的虽然多,但是很多人并没有理解经纬度的几何意义:纬度是一种线面角度,是坐标点P的法线与赤道面的夹角(注意这个法线不一定经过球心);经度是面面角,是坐标点P所在的的子午面与本初子午面的夹角。这也是为什么经度范围是-180 ~ +180,纬度范围却是-90 ~ +90:

地心地固坐标系就是我们常用的笛卡尔空间直角坐标系了。这个坐标系以椭球球心为原点,本初子午面与赤道交线为X轴,赤道面上与X轴正交方向为Y轴,椭球的旋转轴(南北极直线)为Z轴。显然,这是个右手坐标系:

显然,两者都是表达的都是空间中某点P,只不过一个是经纬度坐标(BLH),一个是笛卡尔坐标(XYZ);两者是可以相互转换的。

2. 推导

2.1. BLH->XYZ

将P点所在的子午椭圆放在平面上,以圆心为坐标原点,建立平面直接坐标系:

对照地心地固坐标系,很容易得出:

Z=yX=xcosLY=xsinL(1)(1){Z=yX=x⋅cosLY=x⋅sinL

那么,关键问题在于求子午面直角坐标系的x,y。过P点作原椭球的法线Pn,他与子午面直角坐标系X轴的夹角为B;过P点作子午椭圆的切线,它与X轴的夹角为(90°+B):

图1

根据椭圆的方程,位于椭圆的P点满足:

x2a2+y2b2=1(1.2)(1.2)x2a2+y2b2=1

对x求导,有:

dydx=b2a2xy(2)(2)dydx=−b2a2⋅xy

又根据解析几何可知,函数曲线(椭圆)某一点(就是P点)的倒数为该点切线的斜率,也就是正切值:

dydx=tan(90o+B)=cotB(3)(3)dydx=tan(90o+B)=−cotB

联立公式(2)(3),可得:

y=x(1e2)tanB(4)(4)y=x(1−e2)tanB

其中,e为椭圆第一偏心率:

e=a2b2ae=−a2−b2a

令Pn的距离为N,那么显然有:

x=NcosB(4-2)(4-2)x=NcosB

根据(4)式可得:

y=N(1e2)sinB(4-3)(4-3)y=N(1−e2)sinB

将其带入(1)式,可得到椭球上P点的坐标为:

X=NcosBcosLY=NcosBsinLZ=N(1e2)sinB(5)(5){X=NcosBcosLY=NcosBsinLZ=N(1−e2)sinB

那么唯一的未知量就是Pn的长度N了,将(4)式带入到椭圆方程式(1.2):

x2a2+x2(1e2)2tan2Bb2=1x2a2+x2(1−e2)2tan2Bb2=1

化简,得:

x=acosB1e2sin2B(6)(6)x=acosB1−e2sin2B

联立式(5)式(6),得:

N=a1e2sin2B(6)(6)N=a1−e2sin2B

通过式(5)式(6),可以计算椭球上某一点的坐标。但这个点并不是我们真正要求的点,我们要求的点P(B,L,H)是椭球面沿法向量向上H高度的点:

P点在椭球面上的点为P0P0,那么根据矢量相加的性质,有:

P=P0+Hn(6)(6)P=P0+H⋅n

其中,P0P0也就是式(5),而n是P0P0在椭球面的法线单位矢量。

矢量在任意位置的方向都是一样的,那么我们可以假设存在一个单位球(球的半径为单位1),将法线单位矢量移动到球心位置,可得法线单位矢量为:

n=cosBcosLcosBsinLsinB(7)(7)n=[cosBcosLcosBsinLsinB]

因此有:

P=XYZ=(N+H)cosBcosL(N+H)cosBsinL[N(1e2)+H]sinB(8)(8)P=[XYZ]=[(N+H)cosBcosL(N+H)cosBsinL[N(1−e2)+H]sinB]

其中:

N=a1e2sin2B(9)(9)N=a1−e2sin2B

2.2. XYZ->BLH

根据式(8),可知:

YX=(N+H)cosBsinL(N+H)cosBcosL=tanLYX=(N+H)cosBsinL(N+H)cosBcosL=tanL

因此有:

L=arctan(YX)(10)(10)L=arctan(YX)

不过纬度B就不是那么好算了,首先需要计算法线Pn在赤道两侧的长度。根据图1,有:

y=PQsinBy=PQsinB

与式(4-3)比较可得:

PQ=N(1e2)PQ=N(1−e2)

显然,由于:

Pn=N=PQ+QnPn=N=PQ+Qn

有:

Qn=Ne2Qn=Ne2

接下来如下图所示,对图1做辅助线:

有:

⎪ ⎪ ⎪⎪ ⎪ ⎪PP′′=ZOP′′=x2+y2PP′′′=OKp=QKpsinB=Ne2sinBP′′P′′′=PP′′′+PP′′{PP″=ZOP″=x2+y2PP‴=OKp=QKpsinB=Ne2sinBP″P‴=PP‴+PP″

因而可得:

tanB=Z+Ne2sinBx2+y2(11)(11)tanB=Z+Ne2sinBx2+y2

这个式子两边都有待定量B,需要用迭代法进行求值。具体可参看代码实现,初始的待定值可取tanB=zx2+y2tanB=zx2+y2

大地纬度B已知,那么求高度H就非常简单了,直接根据式(8)中的第三式逆推可得:

H=ZsinBN(1e2)(12)(12)H=ZsinB−N(1−e2)

汇总三式,可得:

⎪ ⎪ ⎪⎪ ⎪ ⎪L=arctan(YX)tanB=Z+Ne2sinBx2+y2H=ZsinBN(1e2){L=arctan(YX)tanB=Z+Ne2sinBx2+y2H=ZsinB−N(1−e2)

3. 实现

根据前面的推导过程,具体的C/C++代码实现如下:

#include <iostream>
using namespace std;
const double epsilon = 0.000000000000001;
const double pi = 3.14159265358979323846;
const double d2r = pi / 180;
const double r2d = 180 / pi;
const double a = 6378137.0;   //椭球长半轴
const double f_inverse = 298.257223563;     //扁率倒数
const double b = a - a / f_inverse;
//const double b = 6356752.314245;      //椭球短半轴
const double e = sqrt(a * a - b * b) / a;
void Blh2Xyz(double &x, double &y, double &z)
{
  double L = x * d2r;
  double B = y * d2r;
  double H = z;
  double N = a / sqrt(1 - e * e * sin(B) * sin(B));
  x = (N + H) * cos(B) * cos(L);
  y = (N + H) * cos(B) * sin(L);
  z = (N * (1 - e * e) + H) * sin(B);
}
void Xyz2Blh(double &x, double &y, double &z)
{
  double tmpX =  x;
  double temY = y ;
  double temZ = z;
  double curB = 0;
  double N = 0; 
  double calB = atan2(temZ, sqrt(tmpX * tmpX + temY * temY)); 
  
  int counter = 0;
  while (abs(curB - calB) * r2d > epsilon  && counter < 25)
  {
    curB = calB;
    N = a / sqrt(1 - e * e * sin(curB) * sin(curB));
    calB = atan2(temZ + N * e * e * sin(curB), sqrt(tmpX * tmpX + temY * temY));
    counter++;  
  }      
  
  x = atan2(temY, tmpX) * r2d;
  y = curB * r2d;
  z = temZ / sin(curB) - N * (1 - e * e); 
}
int main()
{
  double x = 113.6;
  double y = 38.8;
  double z = 100;    
     
  printf("原大地经纬度坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);
  Blh2Xyz(x, y, z);
  printf("地心地固直角坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);
  Xyz2Blh(x, y, z);
  printf("转回大地经纬度坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);   
}

其最关键的还是计算大地纬度B时的迭代过程,其余的计算都只是套公式。数值计算中的很多算法都是采用迭代趋近的方法来趋近一个最佳解。最后的运行结果如下:

4. 参考

  1. 大地坐标与地心坐标相互转换
  2. World Geodetic System 1984 (WGS84)

分类: 大地测量学

标签: 地心坐标 , 大地坐标 , wgs84 , 地球 , 大地测量

相关文章
在Linux中,如何查看系统上运行的进程?
在Linux中,如何查看系统上运行的进程?
|
4月前
|
算法 数据可视化
基于MATLAB/Simulink的四旋翼无人机仿真程序实现
基于MATLAB/Simulink的四旋翼无人机仿真程序实现
376 3
QtSingleApplication 实现单例模式 【实际项目,亲测可用哈】
QtSingleApplication 实现单例模式 【实际项目,亲测可用哈】
QtSingleApplication 实现单例模式 【实际项目,亲测可用哈】
|
11月前
|
机器学习/深度学习 传感器 安全
2025年华为杯E题|高速列车轴承智能故障诊断问题|思路、代码、论文|持续更新中....
2025年华为杯E题|高速列车轴承智能故障诊断问题|思路、代码、论文|持续更新中....
985 0
|
运维 监控 测试技术
自动化运维工具的设计与实现
【8月更文挑战第31天】在现代软件开发中,自动化运维是提高效率、减少错误的关键。本文将探讨如何设计并实现一个自动化运维工具,通过具体代码示例展示其构建过程。我们将从需求分析入手,逐步深入到工具的设计思路、核心功能实现以及最终的部署与测试。文章旨在为读者提供清晰的自动化运维工具开发指导和实践参考。
|
Python
【Python】已解决:AttributeError: module ‘sys’ has no attribute ‘setdefaultencoding’
【Python】已解决:AttributeError: module ‘sys’ has no attribute ‘setdefaultencoding’
958 0
|
前端开发
controller层设计
MVC架构下,我们的web工程结构会分为三层,自下而上是dao层,service层和controller层。controller层为控制层,主要处理外部请求。调用service层,一般情况下,controller层不应该包含业务逻辑,controller的功能应该有以下五点: ⑴、接收请求并解析参数 ⑵、业务逻辑执行成功做出响应 ⑶、异常处理 ⑷、转换业务对象 ⑸、调用 Service 接口
|
机器学习/深度学习 数据采集 存储
技术赋能下的能源智慧管理:MyEMS 开源系统的架构创新与应用深化
在全球能源转型与“双碳”战略推动下,MyEMS作为基于Python的开源能源管理系统,凭借模块化架构与AI技术,助力重点用能单位实现数字化、智能化能源管理。系统支持多源数据采集、智能分析、设备数字孪生与自适应优化控制,全面满足国家级能耗监测要求,并已在制造、数据中心、公共建筑等领域成功应用,助力节能降碳,推动绿色可持续发展。
405 0
KyLinV10 安装realtek-r8125 2.5G网卡驱动。
KyLinV10 安装realtek-r8125 2.5G网卡驱动。
|
Python Windows
在 Windows 平台下打包 Python 多进程代码为 exe 文件的问题及解决方案
在使用 Python 进行多进程编程时,在 Windows 平台下可能会出现将代码打包为 exe 文件后无法正常运行的问题。这个问题主要是由于在 Windows 下创建新的进程需要复制父进程的内存空间,而 Python 多进程机制需要先完成父进程的初始化阶段后才能启动子进程,所以在这个过程中可能会出现错误。此外,由于没有显式导入 Python 解释器,也会导致 Python 解释器无法正常工作。为了解决这个问题,我们可以使用函数。
1132 5

热门文章

最新文章