osgEarth基础入门
osgEarth是基于三维引擎osg开发的三维数字地球引擎库,在osg基础上实现了瓦片调度插件,可选的四叉树调度插件,更多的地理数据加载插件(包括GDAL,ogr,WMS,TMS,VPB,filesystem等),再结合一套地理投影转换插件,这样就能够实现高效处理加载调度地理数据在三维地球上的显示,实现三维虚拟地球。
想要实现一个简单的基于osgEarth的三维地球,有两种方式,这两种方式是互通的。一种基于XML标签的earth文件加载,另外一种是采用C++代码,本质是一样的,osgEarth内部支持直接解析XML标签文件,转换为代码实现,具体参考tests文件夹例子,代码则参考application下面例子。但是大多数情况下,你需要更灵活掌控性更强的代码来实现功能,因为只有一个加载了基础数据的三维地球是只能看,不能解决实际问题的,需要界面通常采用QT,更多的三维渲染和仿真业务则由osg来完成。因此学好osg是做这一切的基础。
osgEarth的特点:支持加载常见的栅格数据(影像和DEM),但是大数据必须建立金字塔,设置为地理投影,想要高效率最好处理为瓦片,这样也便于部署在服务端。矢量数据,最好尽可能的简化,因为大的矢量会十分影响渲染速度,当然也可以对矢量栅格化处理加快速度,对于模型的话,大数据量一定要做LOD或者pageLod。
osgEarth程序的常规流程:
创建osgViewer---->创建MapNode---->设置Earth操作器---->设置场景参数----->run
MapNode是继承自osg的Node,是osgEarth中地球节点,你所添加的影像,DEM,模型都包含在MapNode中,因为它们都加入到Map中,Map则类似二维中的Map可以添加各种图层。剩余的不管是模型节点Node,或者是标注Node,还是其他的都是可以直接添加到MapNode中或者另外的Group中。
Earth操作器则和其他osg操作器一样,只不过专门为三维地球浏览定制,具体参数可以设置。
场景参数则主要有自动地形裁剪,最小裁剪像素等其他优化场景的参数。
下面就简单阐述一个小例子说明:
代码功能主要实现了查询实时高程,并显示XYZ坐标的功能。
使用命令app.exe test.earth即可得到下面的效果。
- //引入osg和osgEarth的头文件和命名空间
- #include <osgGA/StateSetManipulator>
- #include <osgGA/GUIEventHandler>
- #include <osgViewer/Viewer>
- #include <osgViewer/ViewerEventHandlers>
- #include <osgUtil/LineSegmentIntersector>
- #include <osgEarth/MapNode>
- #include <osgEarth/TerrainEngineNode>
- #include <osgEarth/ElevationQuery>
- #include <osgEarth/StringUtils>
- #include <osgEarth/Terrain>
- #include <osgEarthUtil/EarthManipulator>
- #include <osgEarthUtil/Controls>
- #include <osgEarthUtil/LatLongFormatter>
- #include <iomanip>
- using namespace osgEarth;
- using namespace osgEarth::Util;
- using namespace osgEarth::Util::Controls;
- static MapNode* s_mapNode = 0L;
- static LabelControl* s_posLabel = 0L;
- static LabelControl* s_vdaLabel = 0L;
- static LabelControl* s_mslLabel = 0L;
- static LabelControl* s_haeLabel = 0L;
- static LabelControl* s_mapLabel = 0L;
- static LabelControl* s_resLabel = 0L;
- // An event handler that will print out the elevation at the clicked point
- //查询高程的一个事件回调,在场景有事件更新触发时调用,详细参考osg或者osgGA::GUIEventHandler
- struct QueryElevationHandler : public osgGA::GUIEventHandler
- {
- //构造函数
- QueryElevationHandler()
- : _mouseDown( false ),
- _terrain ( s_mapNode->getTerrain() ),
- _query ( s_mapNode->getMap() )
- {
- _map = s_mapNode->getMap();
- //初始化最大查询LOD级别
- _query.setMaxTilesToCache();
- _path.push_back( s_mapNode->getTerrainEngine() );
- }
- //更新回调,具体的内容可以参考父类,传进来的参数是屏幕坐标xy,和osgViewer
- void update( float x, float y, osgViewer::View* view )
- {
- bool yes = false;
- // look under the mouse:
- //采用线去对地球做碰撞检测,根据鼠标点击点去检测,得到交点,就是当前点的xyz
- osg::Vec3d world;
- osgUtil::LineSegmentIntersector::Intersections hits;
- //判断求交结果是否为空
- if ( view->computeIntersections(x, y, hits) )
- {
- //得到世界坐标系下面的坐标,就是osg的xyz坐标
- world = hits.begin()->getWorldIntersectPoint();
- // convert to map coords:
- //将其转换为地球的地理坐标,转换方法都照抄即可
- GeoPoint mapPoint;
- mapPoint.fromWorld( _terrain->getSRS(), world );
- // do an elevation query:
- ; // 1/10th of a degree
- double out_hamsl = 0.0;
- double out_resolution = 0.0;
- //根据输入参数查询当前点位置的高程,需要设置分辨率,就是查询精度
- bool ok = _query.getElevation(
- mapPoint,
- out_hamsl,
- query_resolution,
- &out_resolution );
- //如果查询成功
- if ( ok )
- {
- // convert to geodetic to get the HAE:
- mapPoint.z() = out_hamsl;
- GeoPoint mapPointGeodetic( s_mapNode->getMapSRS()->getGeodeticSRS(), mapPoint );
- //经纬度坐标的格式化工具,也可以自己用字符串去拼接xyz数字
- static LatLongFormatter s_f;
- //更新显示的xyz值,label是传入的控件
- s_posLabel->setText( Stringify()
- << std::)
- << s_f.format(mapPointGeodetic.y())
- << ", "
- << s_f.format(mapPointGeodetic.x()) );
- //还可以输出分辨率,椭球体信息等
- s_mslLabel->setText( Stringify() << out_hamsl );
- s_haeLabel->setText( Stringify() << mapPointGeodetic.z() );
- s_resLabel->setText( Stringify() << out_resolution );
- yes = true;
- }
- // finally, get a normal ISECT HAE point.
- GeoPoint isectPoint;
- isectPoint.fromWorld( _terrain->getSRS()->getGeodeticSRS(), world );
- s_mapLabel->setText( Stringify() << isectPoint.alt() );
- }
- //如果查询不到高程的话
- if (!yes)
- {
- s_posLabel->setText( "-" );
- s_mslLabel->setText( "-" );
- s_haeLabel->setText( "-" );
- s_resLabel->setText( "-" );
- }
- }
- //参数一个是事件的动作,另外一个是对应的操作
- bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
- {
- //判断如果是移动鼠标事件才进行更新当前的坐标显示
- if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE &&
- aa.asView()->getFrameStamp()->getFrameNumber() % == )
- {
- osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
- update( ea.getX(), ea.getY(), view );
- }
- return false;
- }
- //Map对象
- const Map* _map;
- //地形对象
- const Terrain* _terrain;
- bool _mouseDown;
- //查询高程使用的对象
- ElevationQuery _query;
- osg::NodePath _path;
- };
- //main函数,
- int main(int argc, char** argv)
- {
- //这儿两个参数,第一个是命令参数的个数为,后面是字符串数组输入earth文件的路径osg::ArgumentParser arguments(&argc,argv);
- //osg的场景
- osgViewer::Viewer viewer(arguments);
- //构造MapNode,arguments里面有earth文件的路径,命令行输入
- s_mapNode = MapNode::load(arguments);
- //如果路径不正确或者earth文件错误,没有构造好MapNode
- if ( !s_mapNode )
- {
- OE_WARN << "Unable to load earth file." << std::endl;
- ;
- }
- //建立一个组节点
- osg::Group* root = new osg::Group();
- //将组节点设置为场景节点
- viewer.setSceneData( root );
- // install the programmable manipulator.
- //设置earth操作器
- viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() );
- // The MapNode will render the Map object in the scene graph.
- //将MapNode添加到组节点中去
- root->addChild( s_mapNode );
- //下面是设置一个控件,grid的意思是用格网去布局里面的小控件
- // Make the readout:
- Grid* grid = new Grid();
- //设置几个Label文字控件显示在场景中的第行
- grid->setControl(,,new LabelControl("Coords (Lat, Long):"));
- grid->setControl(,,new LabelControl("Vertical Datum:"));
- grid->setControl(,,new LabelControl("Height (MSL):"));
- grid->setControl(,,new LabelControl("Height (HAE):"));
- grid->setControl(,,new LabelControl("Isect (HAE):"));
- grid->setControl(,,new LabelControl("Resolution:"));
- //设置几个Label文字控件显示在场景中的第行
- s_posLabel = grid->setControl(,,new LabelControl(""));
- s_vdaLabel = grid->setControl(,,new LabelControl(""));
- s_mslLabel = grid->setControl(,,new LabelControl(""));
- s_haeLabel = grid->setControl(,,new LabelControl(""));
- s_mapLabel = grid->setControl(,,new LabelControl(""));
- s_resLabel = grid->setControl(,,new LabelControl(""));
- //得到空间参考,椭球面信息,并显示对应上面的label
- const SpatialReference* mapSRS = s_mapNode->getMapSRS();
- s_vdaLabel->setText( mapSRS->getVerticalDatum() ?
- mapSRS->getVerticalDatum()->getName() :
- Stringify() << "geodetic (" << mapSRS->getEllipsoid()->getName() << ")" );
- //控件绘制容器
- ControlCanvas* canvas = new ControlCanvas();
- //将要显示的控件加入到root组节点中去
- root->addChild(canvas);
- canvas->addControl( grid );
- //添加刚刚自定义的查询高程的事件回调
- // An event handler that will respond to mouse clicks:
- viewer.addEventHandler( new QueryElevationHandler() );
- //添加状态显示,窗口改变等事件回调
- // add some stock OSG handlers:
- viewer.addEventHandler(new osgViewer::StatsHandler());
- viewer.addEventHandler(new osgViewer::WindowSizeHandler());
- viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
- //run
- return viewer.run();
- }
osgEarth基础入门相关推荐
- 用python循环语句求素数_Python基础入门_3条件语句和迭代循环
Python 基础入门前两篇: Python 基础入门--简介和环境配置 Python基础入门_2基础语法和变量类型 这是第三篇内容,主要简单介绍条件语句和迭代循环语句,内容也比较简单,目录如下: 条 ...
- MAYA 2022基础入门学习教程
流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...
- Blender 3.0基础入门学习教程 Introduction to Blender 3.0
成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...
- 三维地形制作软件 World Machine 基础入门学习教程
<World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...
- SketchUp Pro 2021基础入门学习视频教程
SketchUp Pro 2021基础入门学习视频教程 1280X720 MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 流派:电子学习|语言:英语+中文字幕( ...
- Maya基础入门学习教程
Maya基础入门学习教程 视频:.MKV, 1280x720, 共57节课 时长 4小时25分钟,3GB 语言:英语+中文字幕(根据原英文字幕机译更准确)+原英文字幕 指导老师:Shane Whitt ...
- Maya2022基础入门学习教程
Maya2022基础入门学习教程 Maya 2022 Essential Training Maya2022基础入门学习教程 Maya 2022 Essential Training MP4 |视频: ...
- Blender基础入门学习教程 Learning Blender from Scratch
Blender基础入门学习教程 Learning Blender from Scratch 流派:电子学习| MP4 |视频:h264,1280×720 |音频:aac,48000 Hz 语言:英语+ ...
- json vue 对象转数组_vue 基础入门(一)修改
vue基础入门(一) 1. 什么是vue Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标 ...
- python 二进制流转图片_Python零基础入门到精通-5.1节:Python程序的执行过程
教程引言: 系统地讲解计算机基础知识,Python的基础知识, 高级知识,web开发框架,爬虫开发,数据结构与算法,nginx, 系统架构.一步步地帮助你从入门到就业. 5.1.1 在命令行中执行Py ...
最新文章
- mysql hy000 1005,mysql – ERROR 1005(HY000):无法创建表(errno:150)
- so 加载符号找不到的问题解决
- ORACLE约束总结
- 7-21 求前缀表达式的值
- 基于php响应式网站毕业论文,基于html5与css3的响应式web页面设计与实现.docx
- Resource stopwords not found. Please use the NLTK Downloader to obtain the r
- 作者:黎建辉(1973-),男,中国科学院计算机网络信息中心研究员、博士生导师...
- 1.3 编程基础之算术表达式与顺序执行 10 计算并联电阻的阻值
- 软件基本功:测试听着简单,会做的没几个
- Python 并口(LPT)打印
- 遇到的几个运放精密整流电路
- html5 audio duration,记一次vue中获取audio媒体总时长duration遇到的问题
- python画图像_使用python绘制SDSS图像
- haml VS erb
- 3D打印机赋予了海岸生态系统极大的恢复能力
- 测试鼠标传感器的软件,鼠标该怎么选择?给大家说下鼠标传感器的差距
- 假设用于通信的电文由字符集{a,b,c,d,e,f,g}中的字母构成。它们在电文中出现的频度分别为
- qt在表格中如何画线_Qt如何在表格中显示和编辑数据
- linux常用命令、linux系统、linux属于什么操作系统、linux系统安装、linux怎么读、linux和windows的区别、linux配置ip地址、linux系统一般用来,在线查询工具
- 宽窄依赖以及shuffle的部分源码理解
热门文章
- 爬虫 + 数据分析 - 7 CrawlSpider(全站爬取), 分布式, 增量式爬虫
- ios 国外账户的创建
- 爬虫入门(五):下载豆瓣电影信息
- 台式计算机模拟软件,全国计算机一级Office2010+win7版考试模拟软件
- 深度卷积神经网络是什么,卷积神经网络结构设计
- 解读SOA平台---概念分析
- linux下如何创建oracle数据库实例,Linux下新建Oracle数据库实例
- PX4(Pixhawk)和Audupilot(APM)的区别与联系
- 高性能跳频抗干扰宽带自组网电台
- 三菱plc c语言模块,FX5-80SSC-S 三菱PLC简易运动控制器模块