码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 经纬度转笛卡尔坐标


    目录

    前言

    二、默认地球的正球

    1、经纬度转笛卡尔坐标

     2、笛卡尔坐标系转经纬度

    三、默认地球是椭球

            1、 BLH->XYZ

    2、XYZ->BLH

    3、总结


    前言

    工作过程经常遇见需要把经纬度转成笛卡尔坐标系来描述空间物体,但是所谓的笛卡尔坐标,其实看起来就是具备XYZ值的坐标,那么怎么计算?这要将地球看正球还是椭球,不同定义,算法不一样,得到的结果也不一样。

    二、默认地球的正球

    1、经纬度转笛卡尔坐标

    public static double EarthRadius = 6371; // km
    1. public static Point3D LatLonToPoint(double latitude, double longitude)
    2. {
    3. longitude -= 180;
    4. latitude = latitude / 180 * Math.PI;
    5. longitude = longitude / 180 * Math.PI;
    6. return new Point3D(
    7. EarthRadius * Math.Cos(latitude) * Math.Cos(longitude),
    8. EarthRadius * Math.Cos(latitude) * Math.Sin(longitude),
    9. EarthRadius * Math.Sin(latitude));
    10. }

     2、笛卡尔坐标系转经纬度

    1. public static void PointToLatLon(Point3D pt, out double lat, out double lon)
    2. {
    3. lon = Math.Atan2(pt.Y, pt.X) * 180 / Math.PI;
    4. lon += 180;
    5. if (lon > 180) lon -= 360;
    6. if (lon < -180) lon += 360;
    7. double a = Math.Sqrt(pt.X * pt.X + pt.Y * pt.Y);
    8. lat = Math.Atan2(pt.Z, a) * 180 / Math.PI;
    9. }

    三、默认地球是椭球

    一般默认球是椭球时候,使用的坐标系定义是地心地固坐标系。这个坐标系以椭球球心为原点,本初子午面与赤道交线为X轴,赤道面上与X轴正交方向为Y轴,椭球的旋转轴(南北极直线)为Z轴。显然,这是个右手坐标系:

    1、 BLH->XYZ

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

     

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

     

     

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

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

    2、XYZ->BLH

     

     3、总结

    转换公式总结

     实现代码:

    1. #include <iostream>
    2. using namespace std;
    3. const double epsilon = 0.000000000000001;
    4. const double pi = 3.14159265358979323846;
    5. const double d2r = pi / 180;
    6. const double r2d = 180 / pi;
    7. const double a = 6378137.0; //椭球长半轴
    8. const double f_inverse = 298.257223563; //扁率倒数
    9. const double b = a - a / f_inverse;
    10. //const double b = 6356752.314245; //椭球短半轴
    11. const double e = sqrt(a * a - b * b) / a;
    12. void Blh2Xyz(double &x, double &y, double &z)
    13. {
    14. double L = x * d2r;
    15. double B = y * d2r;
    16. double H = z;
    17. double N = a / sqrt(1 - e * e * sin(B) * sin(B));
    18. x = (N + H) * cos(B) * cos(L);
    19. y = (N + H) * cos(B) * sin(L);
    20. z = (N * (1 - e * e) + H) * sin(B);
    21. }
    22. void Xyz2Blh(double &x, double &y, double &z)
    23. {
    24. double tmpX = x;
    25. double temY = y ;
    26. double temZ = z;
    27. double curB = 0;
    28. double N = 0;
    29. double calB = atan2(temZ, sqrt(tmpX * tmpX + temY * temY));
    30. int counter = 0;
    31. while (abs(curB - calB) * r2d > epsilon && counter < 25)
    32. {
    33. curB = calB;
    34. N = a / sqrt(1 - e * e * sin(curB) * sin(curB));
    35. calB = atan2(temZ + N * e * e * sin(curB), sqrt(tmpX * tmpX + temY * temY));
    36. counter++;
    37. }
    38. x = atan2(temY, tmpX) * r2d;
    39. y = curB * r2d;
    40. z = temZ / sin(curB) - N * (1 - e * e);
    41. }
    42. int main()
    43. {
    44. double x = 113.6;
    45. double y = 38.8;
    46. double z = 100;
    47. printf("原大地经纬度坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);
    48. Blh2Xyz(x, y, z);
    49. printf("地心地固直角坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);
    50. Xyz2Blh(x, y, z);
    51. printf("转回大地经纬度坐标:%.10lf\t%.10lf\t%.10lf\n", x, y, z);
    52. }

    参考资料:

    (5条消息) 大地经纬度坐标与地心地固坐标的的转换_charlee44的博客-CSDN博客_地心坐标系转换为经纬坐标

  • 相关阅读:
    python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui-键盘
    day-51 代码随想录算法训练营(19)动态规划 part 12
    设计模式 建造者模式介绍、案例应用、建造者模式和工厂模式的区别
    数据结构——树(树的概念、优缺点、二叉树)
    大赛征集令|首届“万应杯”低代码应用开发大赛报名开启啦!
    Linux查看程序和动态库依赖的动态库
    C++学习笔记(三十二)
    Linux 系统误将 chmod 权限改成 了 000,如何恢复?
    目标检测YOLO实战应用案例100讲-水下机器人视域中小目标检测(中)
    2023最新最热ChatGPT/GPT-4科研论文写作与项目开发及AI绘图实战
  • 原文地址:https://blog.csdn.net/cangqiongxiaoye/article/details/126558266
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号