地心地固坐标系WGS84经纬度与笛卡尔直角坐标系相互转换的推导、理解与代码实现(C++和matlab)

news2024/11/26 14:59:12

目录

  • 一、大地坐标系现状简析
    • 1.1 我国
    • 1.2 美国
    • 1.3 日本
  • 二、经纬度坐标(L,B,H)与直角坐标系坐标(X,Y,Z)相互转换
    • 2.1 正解(L,B,H)——>(X,Y,Z)
      • 2.1.1 数学推导
      • 2.1.2 C++代码实现
      • 2.1.3 matlab代码实现
    • 2.2 反解(X,Y,Z)——>(L,B,H)
      • 2.2.1 数学推导
      • 2.2.2 C++代码实现
      • 2.2.3 matlab代码实现



一、大地坐标系现状简析

1.1 我国

  解放后在我国大陆地区曾先后使用了三种坐标系。其一,于1954年引入了苏联1942年普尔科沃坐标系(PULK0V01942),经局部平差建立了“1954年北京坐标系(BJ54)”,使用克拉索夫斯基(Krassowsky)椭球,原点位于前苏联普尔科沃;其二,在20世纪70年代末期,利用天文大地测量资料通过统一整体平差,建立了“1980年国家大地坐标系”,使用UGG75椭球,大地原点位于陕西省西安市北泾阳县永乐镇,又称“1980年西安大地坐标系”;其三,在1980年国家大地坐标系基础上建立“新1954年北京坐标系”,恢复使用了克拉索夫斯基椭球,有利于新坐标成果的使用和新、旧图的拼接。
  未来几年,我国将逐渐使用新一代大地坐标系“2000国家大地坐标系”(China Geodetic Coordinate System2000,CGCS2000)。其定义与协议地球参考系的定义一致,即原点是包括海洋和大气的整个地球质心,初始定向由1984.0时国际时间局定向给定,定向的时间演化使得地壳无整体旋转。

1.2 美国

  美国国防部以军事目的获取全球地面定位信息,相继建立了多个全球地心坐标系。美国国防部于1984年继WGS60、WGS66、WGS72之后建立起来第四个世界大地坐标系世界大地坐标系(World Geodetic System1984,WGS84)。WGS84规定其原点在地球质心、Z轴指向BH1984.0定义的协议地球极方向、X轴指向BH1984.0的零子午面和协议地球极赤道的交点,Y轴与X、Z轴构成右手地心地固ECEF直角坐标系。

1.3 日本

  日本在1918年之前,使用的是“日本东京1892年大地坐标系(JTD1892)”,又称“旧东京坐标系”,坐标原点在东京麻布旧东京天文台(旧海军观象台)子午仪中心点,采用1841年贝塞尔椭球,a=6377397.155米,1/f=299.1528。由于东京坐标系与WGS84坐标系的差异产生的问题日益突出。于是,2001年6月日本新测量法明确规定了其新的大地基准应该与WGS84保持一致,同时新建立的“日本大地基准2000(JGD2000)”取代了“东京坐标系”。东京坐标系通过中间坐标系Tokyo97与JGD2000大地坐标系(水平)相连,Tokyo97采用东京坐标系原点和贝塞尔参考椭球,轴向与1TRF94一致。东京坐标系坐标首先通过平差或网格内插变换至Tokyo97后,然后再变换至TRF94。这样便形成了JGD2000大地坐标系(水平),它采用GRS80椭球。

二、经纬度坐标(L,B,H)与直角坐标系坐标(X,Y,Z)相互转换

  以目前使用最为广泛的WGS84的经纬度坐标进行转换,是基于同一基准的大地坐标系转换。

2.1 正解(L,B,H)——>(X,Y,Z)

2.1.1 数学推导

在这里插入图片描述
  如上示意图,求大地坐标系中点P(L,B,H)在大地空间直角坐标系的坐标(X,Y,Z)分为三步:

  1. 首先,求得P点在其子午线平面坐标系O-xy内坐标(x,y)与纬度B的关系:

在这里插入图片描述

  1. 其次,求得子午线平面坐标(x,y)在大地空间直角坐标系坐标(X,Y,Z):
    在这里插入图片描述

  2. 最后,求得大地坐标系坐标P(L,B,H)在大地空间直角坐标系中的坐标(X,Y,Z):
    在这里插入图片描述

以上公式中:
a:长半轴,取 6378137m;
b:短半轴,取 6356752.3142451793m;
e^2:椭球偏心率
N:椭圆曲率半径
在这里插入图片描述

2.1.2 C++代码实现

原代码:lla2xyz.cpp

#include <iostream>
#include <math.h>
#include <iomanip>
constexpr double DEG_TO_RAD_LOCAL = 3.1415926535897932 / 180.0;

void LLA2XYZ(double longitude, double latitude, double height, double& X, double& Y, double& Z)
{
    double lon = longitude * DEG_TO_RAD_LOCAL;      //经度
    double lat = latitude * DEG_TO_RAD_LOCAL;
    double hei = height;

    // variable
    double a = 6378137.0;       //地球赤道半径 ,单位是 m
    double b = 6356752.31424518;    //地球短半轴 ,单位是 m
    //double E = (a * a - b * b) / (a * a);   // E = e^2
    //std::cout << "E= "<< E << std::endl;
    //double N = a/(sqrt(1-E*sin(lat)*sin(lat)));
    double N = a/(sqrt(1-((a * a - b * b) / (a * a)) * sin(lat) * sin(lat)));
    //std::cout << "N= "<< N << std::endl;

    X =(N + hei ) * cos(lat) * cos(lon);
    Y =(N + hei ) * cos(lat) * sin(lon);
    Z =((b * b * N)/ (a * a) + hei) * sin(lat) ;
}

int main()
{
    
    double longitude = 116.17;
    double latitude = 40.22;
    double height = 36.77;
    double X;
    double Y;
    double Z;

    LLA2XYZ(longitude, latitude, height, X, Y, Z);
    
    std::cout<<setiosflags(std::ios::fixed)<<"x:"<<X<<std::endl;
    std::cout<<setiosflags(std::ios::fixed)<<"y:"<<Y<<std::endl;
    std::cout<<setiosflags(std::ios::fixed)<<"z:"<<Z<<std::endl;
    return 0;
}

查看计算结果:

g++ lla2xyz.cpp -o lla2xyz
./lla2xyz

在这里插入图片描述

2.1.3 matlab代码实现

原代码:LLA2XYZ.m

%% WGS84经纬度LLA转直角坐标系XYZ
% 东经正数,西经为负数
% 北纬为正数,南纬为负数
% 输入参数1:纬度;输入参数2:经度;输入参数3:高度
% 经纬度单位:度;高度单位:米
% 东经116.17° 北纬40.22° 高度36.77m
function [x,y,z]=LLA2XYZ(latitude,longitude,height)
a = 6378137.0;%单位m
b = 6356752.31424518;%单位m
E = (a * a - b * b) / (a * a);

COSLAT = cos(latitude * pi / 180);
SINLAT = sin(latitude * pi / 180);
COSLONG = cos(longitude * pi / 180);
SINLONG = sin(longitude * pi / 180);
N = a / (sqrt(1 - E * SINLAT * SINLAT));
NH = N + height;
x = NH * COSLAT * COSLONG;
y = NH * COSLAT * SINLONG;
z = (b * b * N / (a * a) + height) * SINLAT;
end

查看计算结果:

[x,y,z] = LLA2XYZ(40.22 , 116.17 , 36.77 )

在这里插入图片描述

2.2 反解(X,Y,Z)——>(L,B,H)

2.2.1 数学推导

  对于大地空间直角坐标(X,Y,Z)计算对应的大地坐标(L,B,H)通常也分三部分:求解大地经度、求解大地纬度和计算大地高。

  1. 大地经度的解算
    根据正解公式,可以得到:
    在这里插入图片描述

  2. 大地高的解算
    解得经度后:
    在这里插入图片描述

  3. 大地纬度解算
    大地纬度解算通常使用迭代方法和直接方法。
    在这里插入图片描述

迭代法公式:
在这里插入图片描述
直接法公式:
在这里插入图片描述

2.2.2 C++代码实现

原代码:xyz2lla.cpp

#include <iostream>
#include <math.h>
#include <iomanip>
constexpr double DEG_TO_RAD_LOCAL = 3.1415926535897932 / 180.0;
constexpr double RAD_TO_DEG_LOCAL = 180.0 /3.1415926535897932;

void XYZ2LLA(  double X, double Y, double Z,double& longitude, double& latitude,double& altitude)
{
double a, b, c, d;
		double Longitude;// 经度
		double Latitude;// 纬度
		double Altitude;// 海拔高度
		double p, q;
		double N;
		a = 6378137.0;
		b = 6356752.31424518;
		c = sqrt(((a * a) - (b * b)) / (a * a));
		d = sqrt(((a * a) - (b * b)) / (b * b));
		p = sqrt((X * X) + (Y * Y));
		q = atan2((Z * a), (p * b));
		
		longitude = atan2(Y, X);
		N = a / sqrt(1 - ((c * c) * sin(latitude)* sin(latitude)));
		altitude = (p / cos(latitude)) - N;
		latitude = atan2((Z + (d * d) * b * pow(sin(q), 3)), (p - (c * c) * a * pow(cos(q), 3)));
		
		longitude = longitude * RAD_TO_DEG_LOCAL;
		latitude = latitude * RAD_TO_DEG_LOCAL;
}

int main()
{
    
    double longitude;
    double latitude ;
    double altitude ;
    double X=-2150931.511720;
    double Y=4377053.846931;
    double Z=4096692.121877;

    XYZ2LLA(X,Y,Z,longitude, latitude, altitude);
    
    std::cout<<setiosflags(std::ios::fixed)<<"longitude:"<<longitude<<std::endl;
    std::cout<<setiosflags(std::ios::fixed)<<"latitude:"<<latitude<<std::endl;
    std::cout<<setiosflags(std::ios::fixed)<<"altitude:"<<altitude<<std::endl;
    return 0;
}

查看计算结果:

g++ xyz2lla.cpp -o xyz2lla
./xyz2lla

在这里插入图片描述

2.2.3 matlab代码实现

原代码:XYZ2LLA.m

%% WGS84直角坐标系转经纬度
% 东经正数,西经为负数
% 北纬为正数,南纬为负数
% 输入参数1:纬度;输入参数2:经度;输入参数3:高度
% 经纬度单位:度;高度单位:米
function [latitude,longitude,height]=XYZ2LLA(x,y,z)
 
a = 6378137.0;
b = 6356752.31424518;
c = sqrt(((a * a) - (b * b)) / (a * a));
d = sqrt(((a * a) - (b * b)) / (b * b));
p = sqrt((x * x) + (y * y));
q = atan((z * a)/ (p * b));
longitude = atan(y/x);
latitude = atan((z + (d * d) * b * sin(q)^3)/(p - (c * c) * a * cos(q)^3));
N = a / sqrt(1 - ((c * c) * sin(latitude)^2));
height = (p / cos(latitude)) - N;
longitude = longitude * 180.0 / pi+180;
latitude = latitude * 180.0 / pi;
end

查看计算结果:

[latitude,longitude,height]=XYZ2LLA(-2150931.511720,4377053.846931,4096692.121877)

在这里插入图片描述

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

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

相关文章

文件描述符和缓冲区

文章目录文件操作符系统调用接口文件接口的简单实用实验一&#xff1a;打开文件写入信息实验二&#xff1a;read接口读取文件返回值和fd联想到数组下标OS怎么管理文件呢&#xff1f;先描述再组织。一切皆文件012的操作文件描述符的分配规则&#xff1a;输出重定向的原理。追加重…

Apache Kyuubi、Spark Thrift Server与Hive Server2

HiveServer2和Spark Thrift Server HiveServer2和Spark Thrift Server&#xff0c;两者其实都是提供一个常驻的SQL服务&#xff0c;用来对外提供高性能的SQL引擎能力&#xff0c;不过两者又有些偏差&#xff0c;主要是HS2是独立的Server&#xff0c;可组成集群&#xff0c;而S…

【进阶】C语言第三课:升级你的指针(2)

目录 &#x1f347;前言&#x1f347;&#xff1a; 一、数组参数&#x1f920;&#xff1a; 1.一维数组传参&#x1f348;&#xff1a; 2.二维数组传参&#x1f349;&#xff1a; 二、指针参数&#x1f929;&#xff1a; 1.一级指针传参&#x1f34a;&#xff1a; 2.二级指针…

【论文写作】课程总结

文章目录1、前言2、概述3、摘要与关键字4、引言5、相关工作6、理论7、实验8、总结1、前言 《论文写作》不仅是本人认为的在本学期收获较大的一门&#xff0c;也是最重要的课程之一。因为作为研究生&#xff0c;论文是必不可少的一部分。论文是就自己研究方向中所得到的成果的一…

网络设备的运行隐患怎么排除?日常的例行维护绝对不能少,收藏本文,轻松拿捏各种场景!

设备稳定运行一方面依赖于完备的网络规划&#xff0c;另一方面&#xff0c;也需要通过日常的维护发现并消除设备的运行隐患。 日常维护怎么才能进行呢&#xff1f;有哪些必要的步骤呢&#xff1f; 记住这五步&#xff1a; 1、设备环境检查 设备运行环境正常是保证设备正常运…

PreScan快速入门到精通第四十二讲点云传感器

点云传感器(PCS)是一种理想化的传感器,用于构建高数据率和高更新率的点云数据。该传感器的实际应用包括检测算法的开发、激光雷达系统的设计和验证或HIL验证。同时具备竖直方向的FOV相关信息,支持4D成像雷达系统的仿真开发。 该传感器具有固定但可配置的模式,并针对性能(…

分享一些冷门但却很实用的css样式

在平常的代码工作中&#xff0c;有很多冷门不常用的css样式标签。有些偏门、冷门的标签一般都记不住&#xff0c;想起来的时候就又会去现找&#xff0c;很影响工作效率&#xff0c;现在&#xff0c;把这些标签都统一整理一下用的少但是超级实用的css样式。 ::-Webkit-Input-Pla…

0基础转行学软件测试,哪些技术是必须要掌握的?

作为近些年非常热门的IT岗位&#xff0c;软件测试-受到越来越多应届毕业生和诸多转行群体的青睐。为了满足同学们对软件测试的学习要求&#xff0c;测试猿课堂将在本文为大家详细讲述成为自动化软件测试工程师必须要具备的能力体系。 软件测试的学习体系总的来讲可以分为五个阶…

Redis框架(十一):大众点评项目 乐观锁解决超卖问题 悲观锁解决一人一单问题

大众点评项目 基于Session的短信登录需求&#xff1a;乐观锁解决超卖问题 悲观锁解决一人一单问题业务代码总结SpringCloud章节复习已经过去&#xff0c;新的章节Redis开始了&#xff0c;这个章节中将会回顾Redis实战项目 大众点评 主要依照以下几个原则 基础实战的Demo和Codi…

数字IC后端设计如何快速入门?(内附学习视频)

虽然2022年IC行业门槛有所提高&#xff0c;但这也抵挡不住同学们对转行IC行业的热情&#xff0c;数字后端设计的发展前景和高薪也在众多岗位中脱颖而出&#xff0c;那么数字IC后端设计如何快速入门&#xff1f;下面IC修真院就带大家来了解一下。 数字后端工程师是做什么的&…

Docker:自定义镜像上传阿里云

目录 一.jdkv.1.0的制作 启动虚拟机&#xff0c;进入centos 创建文件夹上传jdk的安装包,和在同级目录下编写Dockerfile文件 执行Dockerfile文件&#xff0c;初次依赖镜像的时候会下载相应镜像​​​​​​​ 二.jdk2.0的制作 三.jdk3.0的制作 四.将制作好的镜像上传阿里云…

一文解读机密容器的崛起和发展

在 2022 云栖大会龙蜥峰会云原生专场上&#xff0c;来自阿里云操作系统技术专家冯世舫和Intel 系统软件工程部高级研发经理朱江云分享了《机密容器的崛起和发展》技术演讲&#xff0c;以下为本次演讲内容&#xff1a; 机密容器是 CNCF 的 一个 Sandbox 项目&#xff0c;用于解…

第一章 linux的发展

第一章 linux的发展一、操作系统的出现二、linux的出现三、linux的发展一、操作系统的出现 大部分先进产品的出现必定是为了军事服务的&#xff0c;起初的大型计算机也同样是为了军事服务的&#xff0c;而操作计算机的人也不是程序员&#xff0c;而是科学家。二战时期&#xf…

DVWA靶场中SQL注入

DVWA靶场中SQL注入1.DVWA靶场中SQL注入1.1.SQL Injection1.1.1.Low级别1.1.2.Medium级别1.1.3.High级别1.2.SQL Injection(Blind)1.2.1.方式1.2.2.Low级别1.2.3.Medium级别1.2.4.High级别1.DVWA靶场中SQL注入 1.1.SQL Injection 1.1.1.Low级别 1&#xff09;判断注入类型当输…

高中数理化杂志高中数理化杂志社高中数理化编辑部2022年第21期目录

高考全关注《高中数理化》投稿&#xff1a;cn7kantougao163.com 直线与圆的方程高考热点赏析 廖永福; 1-4 一道课本例题到一道高考试题的衍变之路 高磊; 4-8 圆的多种定义形式在解题中的应用 李光彬;邵建凤; 9-10 从2021年全国新高考Ⅰ卷第21题说起 王菊;张琥;…

碳交易机制下考虑需求响应的综合能源系统优化运行(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

接口测试(五)—— PyMySQL增删改查、数据库工具类封装

目录 数据库操作应用场景 一、PyMySQL操作数据库 1、安装PyMySQL 2、PyMySQL操作步骤 3、事务的概念 4、PyMySQL连接数据库 4.1 建立连接方法 4.2 入门案例 5、PyMySQL操作数据库 5.1 SQL 语法 5.2 数据库查询 5.3 案例&#xff08;查询&#xff09; 5.4 数据库UI…

代码随想录训练营第七天

专题&#xff1a;哈希表 题目&#xff1a;四数相加 题目简单&#xff1a;把四个数组分成两队&#xff0c;然后用map&#xff0c;保存前两个数组的元素之和&#xff0c;&#xff08;key,val&#xff09;key保存的是前两个数组的元素之和的数值&#xff0c;val保存的是数值对应…

PDF设置密码保护的两种方法

PDF文件可以根据需要&#xff0c;设置两种密码来保护文件。 需要保护文件内容&#xff0c;不想PDF被随意打开&#xff0c;我们可以设置打开密码&#xff0c;这样只有输入正确的密码才能打开文件。 在编辑器中打开PDF后&#xff0c;找到菜单中【保护】选项下的【密码加密】&am…

SpringCloud01

1.认识微服务 随着互联网行业的发展&#xff0c;对服务的要求也越来越高&#xff0c;服务架构也从单体架构逐渐演变为现在流行的微服务架构。这些架构之间有怎样的差别呢&#xff1f; 1.0.学习目标 了解微服务架构的优缺点 1.1.单体架构 单体架构&#xff1a;将业务的所有功能集…