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即可得到下面的效果。

  1. //引入osg和osgEarth的头文件和命名空间
  2. #include <osgGA/StateSetManipulator>
  3. #include <osgGA/GUIEventHandler>
  4. #include <osgViewer/Viewer>
  5. #include <osgViewer/ViewerEventHandlers>
  6. #include <osgUtil/LineSegmentIntersector>
  7. #include <osgEarth/MapNode>
  8. #include <osgEarth/TerrainEngineNode>
  9. #include <osgEarth/ElevationQuery>
  10. #include <osgEarth/StringUtils>
  11. #include <osgEarth/Terrain>
  12. #include <osgEarthUtil/EarthManipulator>
  13. #include <osgEarthUtil/Controls>
  14. #include <osgEarthUtil/LatLongFormatter>
  15. #include <iomanip>
  16. using namespace osgEarth;
  17. using namespace osgEarth::Util;
  18. using namespace osgEarth::Util::Controls;
  19. static MapNode* s_mapNode = 0L;
  20. static LabelControl* s_posLabel = 0L;
  21. static LabelControl* s_vdaLabel = 0L;
  22. static LabelControl* s_mslLabel = 0L;
  23. static LabelControl* s_haeLabel = 0L;
  24. static LabelControl* s_mapLabel = 0L;
  25. static LabelControl* s_resLabel = 0L;
  26. // An event handler that will print out the elevation at the clicked point
  27. //查询高程的一个事件回调,在场景有事件更新触发时调用,详细参考osg或者osgGA::GUIEventHandler
  28. struct QueryElevationHandler : public osgGA::GUIEventHandler
  29. {
  30. //构造函数
  31. QueryElevationHandler()
  32. : _mouseDown( false ),
  33. _terrain ( s_mapNode->getTerrain() ),
  34. _query ( s_mapNode->getMap() )
  35. {
  36. _map = s_mapNode->getMap();
  37. //初始化最大查询LOD级别
  38. _query.setMaxTilesToCache();
  39. _path.push_back( s_mapNode->getTerrainEngine() );
  40. }
  41. //更新回调,具体的内容可以参考父类,传进来的参数是屏幕坐标xy,和osgViewer
  42. void update( float x, float y, osgViewer::View* view )
  43. {
  44. bool yes = false;
  45. // look under the mouse:
  46. //采用线去对地球做碰撞检测,根据鼠标点击点去检测,得到交点,就是当前点的xyz
  47. osg::Vec3d world;
  48. osgUtil::LineSegmentIntersector::Intersections hits;
  49. //判断求交结果是否为空
  50. if ( view->computeIntersections(x, y, hits) )
  51. {
  52. //得到世界坐标系下面的坐标,就是osg的xyz坐标
  53. world = hits.begin()->getWorldIntersectPoint();
  54. // convert to map coords:
  55. //将其转换为地球的地理坐标,转换方法都照抄即可
  56. GeoPoint mapPoint;
  57. mapPoint.fromWorld( _terrain->getSRS(), world );
  58. // do an elevation query:
  59. ; // 1/10th of a degree
  60. double out_hamsl = 0.0;
  61. double out_resolution = 0.0;
  62. //根据输入参数查询当前点位置的高程,需要设置分辨率,就是查询精度
  63. bool ok = _query.getElevation(
  64. mapPoint,
  65. out_hamsl,
  66. query_resolution,
  67. &out_resolution );
  68. //如果查询成功
  69. if ( ok )
  70. {
  71. // convert to geodetic to get the HAE:
  72. mapPoint.z() = out_hamsl;
  73. GeoPoint mapPointGeodetic( s_mapNode->getMapSRS()->getGeodeticSRS(), mapPoint );
  74. //经纬度坐标的格式化工具,也可以自己用字符串去拼接xyz数字
  75. static LatLongFormatter s_f;
  76. //更新显示的xyz值,label是传入的控件
  77. s_posLabel->setText( Stringify()
  78. << std::)
  79. << s_f.format(mapPointGeodetic.y())
  80. << ", "
  81. << s_f.format(mapPointGeodetic.x()) );
  82. //还可以输出分辨率,椭球体信息等
  83. s_mslLabel->setText( Stringify() << out_hamsl );
  84. s_haeLabel->setText( Stringify() << mapPointGeodetic.z() );
  85. s_resLabel->setText( Stringify() << out_resolution );
  86. yes = true;
  87. }
  88. // finally, get a normal ISECT HAE point.
  89. GeoPoint isectPoint;
  90. isectPoint.fromWorld( _terrain->getSRS()->getGeodeticSRS(), world );
  91. s_mapLabel->setText( Stringify() << isectPoint.alt() );
  92. }
  93. //如果查询不到高程的话
  94. if (!yes)
  95. {
  96. s_posLabel->setText( "-" );
  97. s_mslLabel->setText( "-" );
  98. s_haeLabel->setText( "-" );
  99. s_resLabel->setText( "-" );
  100. }
  101. }
  102. //参数一个是事件的动作,另外一个是对应的操作
  103. bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
  104. {
  105. //判断如果是移动鼠标事件才进行更新当前的坐标显示
  106. if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE &&
  107. aa.asView()->getFrameStamp()->getFrameNumber() % == )
  108. {
  109. osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
  110. update( ea.getX(), ea.getY(), view );
  111. }
  112. return false;
  113. }
  114. //Map对象
  115. const Map* _map;
  116. //地形对象
  117. const Terrain* _terrain;
  118. bool _mouseDown;
  119. //查询高程使用的对象
  120. ElevationQuery _query;
  121. osg::NodePath _path;
  122. };
  123. //main函数,
  124. int main(int argc, char** argv)
  125. {
  126. //这儿两个参数,第一个是命令参数的个数为,后面是字符串数组输入earth文件的路径osg::ArgumentParser arguments(&argc,argv);
  127. //osg的场景
  128. osgViewer::Viewer viewer(arguments);
  129. //构造MapNode,arguments里面有earth文件的路径,命令行输入
  130. s_mapNode = MapNode::load(arguments);
  131. //如果路径不正确或者earth文件错误,没有构造好MapNode
  132. if ( !s_mapNode )
  133. {
  134. OE_WARN << "Unable to load earth file." << std::endl;
  135. ;
  136. }
  137. //建立一个组节点
  138. osg::Group* root = new osg::Group();
  139. //将组节点设置为场景节点
  140. viewer.setSceneData( root );
  141. // install the programmable manipulator.
  142. //设置earth操作器
  143. viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() );
  144. // The MapNode will render the Map object in the scene graph.
  145. //将MapNode添加到组节点中去
  146. root->addChild( s_mapNode );
  147. //下面是设置一个控件,grid的意思是用格网去布局里面的小控件
  148. // Make the readout:
  149. Grid* grid = new Grid();
  150. //设置几个Label文字控件显示在场景中的第行
  151. grid->setControl(,,new LabelControl("Coords (Lat, Long):"));
  152. grid->setControl(,,new LabelControl("Vertical Datum:"));
  153. grid->setControl(,,new LabelControl("Height (MSL):"));
  154. grid->setControl(,,new LabelControl("Height (HAE):"));
  155. grid->setControl(,,new LabelControl("Isect (HAE):"));
  156. grid->setControl(,,new LabelControl("Resolution:"));
  157. //设置几个Label文字控件显示在场景中的第行
  158. s_posLabel = grid->setControl(,,new LabelControl(""));
  159. s_vdaLabel = grid->setControl(,,new LabelControl(""));
  160. s_mslLabel = grid->setControl(,,new LabelControl(""));
  161. s_haeLabel = grid->setControl(,,new LabelControl(""));
  162. s_mapLabel = grid->setControl(,,new LabelControl(""));
  163. s_resLabel = grid->setControl(,,new LabelControl(""));
  164. //得到空间参考,椭球面信息,并显示对应上面的label
  165. const SpatialReference* mapSRS = s_mapNode->getMapSRS();
  166. s_vdaLabel->setText( mapSRS->getVerticalDatum() ?
  167. mapSRS->getVerticalDatum()->getName() :
  168. Stringify() << "geodetic (" << mapSRS->getEllipsoid()->getName() << ")" );
  169. //控件绘制容器
  170. ControlCanvas* canvas = new ControlCanvas();
  171. //将要显示的控件加入到root组节点中去
  172. root->addChild(canvas);
  173. canvas->addControl( grid );
  174. //添加刚刚自定义的查询高程的事件回调
  175. // An event handler that will respond to mouse clicks:
  176. viewer.addEventHandler( new QueryElevationHandler() );
  177. //添加状态显示,窗口改变等事件回调
  178. // add some stock OSG handlers:
  179. viewer.addEventHandler(new osgViewer::StatsHandler());
  180. viewer.addEventHandler(new osgViewer::WindowSizeHandler());
  181. viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
  182. //run
  183. return viewer.run();
  184. }

osgEarth基础入门相关推荐

  1. 用python循环语句求素数_Python基础入门_3条件语句和迭代循环

    Python 基础入门前两篇: Python 基础入门--简介和环境配置 Python基础入门_2基础语法和变量类型 这是第三篇内容,主要简单介绍条件语句和迭代循环语句,内容也比较简单,目录如下: 条 ...

  2. MAYA 2022基础入门学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...

  3. Blender 3.0基础入门学习教程 Introduction to Blender 3.0

    成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...

  4. 三维地形制作软件 World Machine 基础入门学习教程

    <World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...

  5. SketchUp Pro 2021基础入门学习视频教程

    SketchUp Pro 2021基础入门学习视频教程 1280X720 MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 流派:电子学习|语言:英语+中文字幕( ...

  6. Maya基础入门学习教程

    Maya基础入门学习教程 视频:.MKV, 1280x720, 共57节课 时长 4小时25分钟,3GB 语言:英语+中文字幕(根据原英文字幕机译更准确)+原英文字幕 指导老师:Shane Whitt ...

  7. Maya2022基础入门学习教程

    Maya2022基础入门学习教程 Maya 2022 Essential Training Maya2022基础入门学习教程 Maya 2022 Essential Training MP4 |视频: ...

  8. Blender基础入门学习教程 Learning Blender from Scratch

    Blender基础入门学习教程 Learning Blender from Scratch 流派:电子学习| MP4 |视频:h264,1280×720 |音频:aac,48000 Hz 语言:英语+ ...

  9. json vue 对象转数组_vue 基础入门(一)修改

    vue基础入门(一) 1. 什么是vue Vue.js(读音 /vjuː/, 类似于 view) 是一套构建用户界面的渐进式框架. Vue 只关注视图层, 采用自底向上增量开发的设计. Vue 的目标 ...

  10. python 二进制流转图片_Python零基础入门到精通-5.1节:Python程序的执行过程

    教程引言: 系统地讲解计算机基础知识,Python的基础知识, 高级知识,web开发框架,爬虫开发,数据结构与算法,nginx, 系统架构.一步步地帮助你从入门到就业. 5.1.1 在命令行中执行Py ...

最新文章

  1. mysql hy000 1005,mysql – ERROR 1005(HY000):无法创建表(errno:150)
  2. so 加载符号找不到的问题解决
  3. ORACLE约束总结
  4. 7-21 求前缀表达式的值
  5. 基于php响应式网站毕业论文,基于html5与css3的响应式web页面设计与实现.docx
  6. Resource stopwords not found. Please use the NLTK Downloader to obtain the r
  7. 作者:黎建辉(1973-),男,中国科学院计算机网络信息中心研究员、博士生导师...
  8. 1.3 编程基础之算术表达式与顺序执行 10 计算并联电阻的阻值
  9. 软件基本功:测试听着简单,会做的没几个
  10. Python 并口(LPT)打印
  11. 遇到的几个运放精密整流电路
  12. html5 audio duration,记一次vue中获取audio媒体总时长duration遇到的问题
  13. python画图像_使用python绘制SDSS图像
  14. haml VS erb
  15. 3D打印机赋予了海岸生态系统极大的恢复能力
  16. 测试鼠标传感器的软件,鼠标该怎么选择?给大家说下鼠标传感器的差距
  17. 假设用于通信的电文由字符集{a,b,c,d,e,f,g}中的字母构成。它们在电文中出现的频度分别为
  18. qt在表格中如何画线_Qt如何在表格中显示和编辑数据
  19. linux常用命令、linux系统、linux属于什么操作系统、linux系统安装、linux怎么读、linux和windows的区别、linux配置ip地址、linux系统一般用来,在线查询工具
  20. 宽窄依赖以及shuffle的部分源码理解

热门文章

  1. 爬虫 + 数据分析 - 7 CrawlSpider(全站爬取), 分布式, 增量式爬虫
  2. ios 国外账户的创建
  3. 爬虫入门(五):下载豆瓣电影信息
  4. 台式计算机模拟软件,全国计算机一级Office2010+win7版考试模拟软件
  5. 深度卷积神经网络是什么,卷积神经网络结构设计
  6. 解读SOA平台---概念分析
  7. linux下如何创建oracle数据库实例,Linux下新建Oracle数据库实例
  8. PX4(Pixhawk)和Audupilot(APM)的区别与联系
  9. 高性能跳频抗干扰宽带自组网电台
  10. 三菱plc c语言模块,FX5-80SSC-S 三菱PLC简易运动控制器模块