浅谈osgEarth操控器类的createLocalCoordFrame函数如何将局部坐标系的点转为世界坐标系下的Martix(ENU坐标)
在osgEarth操控器类的EarthManipulator中的如下函数:
void EarthManipulator::setLookAt(const osg::Vec3d& center,double azim,double pitch,double range,const osg::Vec3d& posOffset)
{setCenter( center );.... // 其它代码略
}void EarthManipulator::setCenter( const osg::Vec3d& worldPos )
{_center = worldPos;createLocalCoordFrame( worldPos, _centerLocalToWorld );.... // 其它代码略
}
如上代码在osgEarth操控器EarthManipulator类的setLookAt函数调setCenter函数设置相机视点看向的位于地球上的某焦点区域的中心_center。_center是世界坐标系表示的点,也即是地心地固坐标系表示的点。setCenter函数调用createLocalCoordFrame函数,其代码如下:
bool
EarthManipulator::createLocalCoordFrame( const osg::Vec3d& worldPos, osg::CoordinateFrame& out_frame ) const
{if ( _srs.valid() ){osg::Vec3d mapPos;_srs->transformFromWorld( worldPos, mapPos );_srs->createLocalToWorld( mapPos, out_frame );}return _srs.valid();
}
其中:
_srs->transformFromWorld( worldPos, mapPos );
是将地心地固坐标系表示的点worldPos转为经度、纬度、高程坐标系(一般为WGS84)下的点,并保存到mapPos变量中。按上面的调用流程来看,就是将_center转为经纬度、高程坐标系下的坐标,并保存到mapPos变量中。如下代码:
_srs->createLocalToWorld( mapPos, out_frame );
将mapPos变即最开始的_center转为经纬度高程后的坐标再转为out_frame。上述createLocalToWorld函数到底是干什么用的呢?断点跟踪到底层代码:
bool
SpatialReference::createLocalToWorld(const osg::Vec3d& xyz, osg::Matrixd& out_local2world ) const
{if (!valid())return false;if ( isProjected() && !isCube() ){....// 其它代码略}else if ( isGeocentric() ){....// 其它代码略}else{// convert to ECEF:osg::Vec3d ecef;if ( !transform(xyz, getGeocentricSRS(), ecef) )return false;// and create the matrix.out_local2world = _ellipsoid.geocentricToLocalToWorld(ecef);}return true;
}
在else语句中又将经纬度、高程坐标系下的_center转回地心地固坐标,接下来通过geocentricToLocalToWorld将这个地心地固坐标下的_center进行转换:
osg::Matrix
Ellipsoid::geocentricToLocalToWorld(const osg::Vec3d& geoc) const
{osg::Matrix m;EM.computeLocalToWorldTransformFromXYZ(geoc.x(), geoc.y(), geoc.z(), m);return m;
}
发现上述代码调用了osg里面的函数:
inline void EllipsoidModel::computeLocalToWorldTransformFromXYZ(double X, double Y, double Z, osg::Matrixd& localToWorld) const
{double latitude, longitude, height;convertXYZToLatLongHeight(X,Y,Z,latitude,longitude,height);localToWorld.makeTranslate(X,Y,Z);computeCoordinateFrame(latitude, longitude, localToWorld);
}
这个函数前面很简单:又将地心地固坐标的_center转成经纬度、高程坐标系坐标;这个函数后面断点跟进去如下:
inline void EllipsoidModel::computeCoordinateFrame(double latitude, double longitude, osg::Matrixd& localToWorld) const
{// Compute up vectorosg::Vec3d up ( cos(longitude)*cos(latitude), sin(longitude)*cos(latitude), sin(latitude));// Compute east vectorosg::Vec3d east (-sin(longitude), cos(longitude), 0);// Compute north vector = outer product up x eastosg::Vec3d north = up ^ east;// set matrixlocalToWorld(0,0) = east[0];localToWorld(0,1) = east[1];localToWorld(0,2) = east[2];localToWorld(1,0) = north[0];localToWorld(1,1) = north[1];localToWorld(1,2) = north[2];localToWorld(2,0) = up[0];localToWorld(2,1) = up[1];localToWorld(2,2) = up[2];
}
可以看出,上面这个函数就是生成了一个旋转矩阵,再结合上面的那个平移的代码:
localToWorld.makeTranslate(X,Y,Z);
可以看出,生成的这个矩阵是一个旋转平移矩阵。而且是先旋转,后平移。 上面坐标结合下图很容易理解:

图1 坐标转换图
经过这么多转换后,_center向东、向北,向天方向的姿态就出来了,如下:

图2 ECEF、ENU、BLH坐标系
淡绿色坐标系为东北天(ENU)坐标系,经过这么多次转换后,_center就相当于三个淡绿色坐标系的原点(说明:在osgEarth操控器中,程序初始流程刚进入时,_center其实是位于图2中的1位置处,即地心地固坐标系Y轴负半轴和赤道圆交点处,这里为了便于观察,将ENU放到易于观察的角度了)。另外:图2中灰色的X、Y、Z轴表示的地心地固坐标系(ECEF),桔黄色表示的是经纬度坐标系(BLH)。
地心地固坐标系和ENU坐标系之间的换算,可以参考如下博文:
地心地固坐标系(ECEF)与站心坐标系(ENU)的转换。
参考链接:
osgearth 代码 hack(一) GeoTransfrom 如何工作
相关文章:
浅谈osgEarth操控器类的createLocalCoordFrame函数如何将局部坐标系的点转为世界坐标系下的Martix(ENU坐标)
在osgEarth操控器类的EarthManipulator中的如下函数: void EarthManipulator::setLookAt(const osg::Vec3d& center,double azim,double pitch,double range,const osg::Vec3d& posOffset) {setCenter( center );.... //…...
PHP程序员和Python程序员的职业前景怎么样?我来聊聊自己的体会
大家好,今天我们来聊一下程序员这个职业的特点。在讲这个话题之前,我先说一下我自己的情况:我在福州和深圳做了8年左右的程序员,然后回到老家,在家里面为福州的一个公司做远程开发。目前已经在老家做了将近3年。 今天…...
【MATLAB图像处理实用案例详解(8)】—— 图像数字水印算法
目录 一、背景意义二、基本原理三、算法介绍3.1 数字水印嵌入3.2 数字水印提取 四、程序实现 一、背景意义 数字水印技术作为信息隐藏技术的一个重要分支,是将信息(水印)隐藏于数字图像、视频、音频及文本文档等数字媒体中,从而实现隐秘传输、存储、标注…...
最全的免费SSL证书申请方式
在SSL广泛普及的今天,申请一张免费的SSL证书是一件非常容易的事情。这里为大家总结当前阶段(2023年)拥有一张免费SSL证书的方式。首推的方式为来此加密网站,文章后面会有详细的介绍。 下面介绍几种获取免费SSL证书的方式,大家可以根据自己的…...
Ceph入门到精通-CrushMap算法概述
下面是伪代码object到osd的伪代码 locator =object_name obj_hash =hash(locator) pg =obj_hash %num_pg OSDs_for_pg =crush(pg) # returns a list of OSDs primary =osds_for_pg[0] replicas =osds_for_pg[1:] defcrush(pg): all_osds=[osd.0,osd.1,osd.2,...] resu…...
如何利用API做好电商,接口如何凋用关键字
一.随着互联网的快速发展,电子商务成为了众多企业的首选模式,而开放API则成为了电商业务中不可或缺的部分。API(Application Programming Interface),即应用程序接口,是软件系统不同组件之间交互的约定。电…...
Give me a logic game idea about economics
Here’s an logic game idea about economics: Game name: “Economics Tycoon” Game Objective: Build an economic empire and grow from a small business owner to a global tycoon. Gameplay: Start with a small business and limited resources. Manage your compa…...
测试之路,2023年软件测试市场领域有哪些变化?突破走得更远...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Python自动化测试&…...
配置Windows终端直接执行Python脚本,无需输入“python“
配置Windows终端直接执行Python脚本,无需输入"python" 1. 将Python加入环境变量2. 将Python后缀加入环境变量PATHEXT中3. 修改Python脚本的默认打开方式4. *将Python脚本命令加入环境变量*5. 测试 在Linux系统中,在Python脚本的开头指定Python…...
IDEA快捷键
文章目录 快捷键介绍重点掌握CtrlAltShiftCtrl AltCtrl ShiftAlt ShiftCtrl Shift Alt其他 快捷键介绍 重点掌握 psvmmain函数sout输出soutv带变量名输出.sout变量.调用 输出变量值.if布尔值.调用 生成if语句.for数组类型变量.for 生成for语句.var补全接收的变量&#x…...
关于c++指针数组的要设置初值的情况
在大多数情况下,都应该对指针数组进行初始化,以避免出现未知的值和潜在的未定义行为。指针数组在定义时必须指定元素个数,如果未指定元素值,则需要对其进行显式初始化。如果未初始化数组,则未知的值可能指向无效的内存…...
泰克RSA306B频谱分析仪测试信道功率方法
泰克RSA306B实时频谱分析仪是一种用于无线信号分析的仪器。它可以实时监控无线信号的频谱,帮助用户分析信号特征,掌握信号的功率、频率、调制等关键信息。在无线通信中,信道功率是一个非常重要的指标,它反映了信号在传输过程中的强…...
深度学习技巧应用12-神经网络训练中批归一化的应用
大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用12-神经网络训练中批归一化的应用,在深度学习中,批归一化(Batch Normalization,简称BN)是一种重要的技巧,它在许多神经网络中都得到了广泛应用。本文将详细介绍批归一化的原理和应用,并结合PyTorch框架构建一个简…...
Masonry使用以及源码解析(未完待续
文章目录 Masonry使用约束约束优先级 以及 intrinsicContentSize相关问题 Masonry:iOS12Masonry源码解析下面是使用make.width点语法后的全部内部调用过程: Masonry使用 约束 在写Masonry之前,我想先来聊聊约束的基础知识,我们首先要了解一…...
118-Linux_数据库_索引
文章目录 一.索引是什么?二.索引为什么选择b树三.测试索引1.在mysql中创建数据库 test_indexdb2.在test_indexdb中创建表 test_index3.运行程序向表中插入1万条数据,都是字符串4. 查询验证 一.索引是什么? 索引是一种特殊的文件,它包含着对数据表里所…...
macos和windows区别 macos怎么运行windows程序
在我们使用电脑时,重要的是电脑内应用,而系统不过是运行软件的“容器”。日常生活中,我们常见的操作系统是macos和windows,那么macos和windows区别在哪?这两款操作系统的区别很大。macos怎么运行windows程序࿱…...
一起Talk Android吧(第五百四十二回:无进度值ProgressBar)
文章目录 概念介绍使用资源文件实现使用默认设置修改风格使用动画资源 使用代码实现经验总结 各位看官们大家好,上一回中咱们说的例子是"ProgressBar总结",本章回中介绍的例子是" 无进度值ProgressBar"。闲话休提,言归正转…...
Oracle DataGuard奇怪的ORA-16494错误
Oracle数据库DataGuard数据无法同步,主库查询v$archive_dest出现ORA-16494错误。 数据库版本Oracle 12.1.0.2.0: SQL> select * from v$version;BANNER --------------------------------------------------------------------------------CON_ID --…...
《花雕学AI》Poe 一站式 AI 工具箱:ChatGPT4 体验邀请,亲,不要错过哦!
你有没有想过,如果你能在同一个平台上体验多种不同的 AI 模型,和他们进行有趣、有用、有深度的对话,甚至还能轻松地分享你的对话给其他人,那该有多好?如果你有这样的想法,那么你一定不能错过 Poe 一站式 AI…...
AttributeError: module ‘lib‘ has no attribute ‘X509_V_FLAG_CB_ISSUER_CHECK‘
terminal运行报错AttributeError: module lib has no attribute X509_V_FLAG_CB_ISSUER_CHECK 解决: pip install pyOpenSSL --upgrade...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
高效的后台管理系统——可进行二次开发
随着互联网技术的迅猛发展,企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心,成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统,它不仅支持跨平台应用,还能提供丰富…...
