前言

本章为osgearth_annotation示例分析,示例中采用osgEarth提供的类,绘制标签、线、billboard、遮盖图、墙等内容。

运行时,在生成的可执行路径下,打开命令框,输入:

osgearth_annotationd.exe xxx.earth

为方便测试,这里直接将文件路径写在程序中,直接执行加载earth文件。

效果如下:

addChild关系以及简单类关系

代码分析

#include <osgEarth/MapNode>#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>#include <osgEarthAnnotation/ImageOverlay>
#include <osgEarthAnnotation/CircleNode>
#include <osgEarthAnnotation/RectangleNode>
#include <osgEarthAnnotation/EllipseNode>
#include <osgEarthAnnotation/PlaceNode>
#include <osgEarthAnnotation/LabelNode>
#include <osgEarthAnnotation/LocalGeometryNode>
#include <osgEarthAnnotation/FeatureNode>
#include <osgEarthAnnotation/ModelNode>#include <osgEarthAnnotation/AnnotationEditing>
#include <osgEarthAnnotation/ImageOverlayEditor>#include <osgEarthSymbology/GeometryFactory>#include <osgViewer/Viewer>
#include <osgDB/ReadFile>// 读取earth文件需要加入头文件using namespace osgEarth;
using namespace osgEarth::Annotation;
using namespace osgEarth::Features;
using namespace osgEarth::Util;//------------------------------------------------------------------int
usage( char** argv )
{OE_WARN << "Usage: " << argv[0] << " <earthfile>" << std::endl;return -1;
}//------------------------------------------------------------------int
main(int argc, char** argv)
{osg::Group* root = new osg::Group();// [1 begin] 方式一:通过传入的earth文件参数初始化地球界面// try to load an earth file.//osg::ArgumentParser arguments(&argc,argv);//osgViewer::Viewer viewer(arguments);//viewer.setCameraManipulator( new EarthManipulator() );load an earth file and parse demo arguments//osg::Node* node = MapNodeHelper().load(arguments, &viewer);//if ( !node )//    return usage(argv);//root->addChild( node );// find the map node that we loaded.//MapNode* mapNode = MapNode::findMapNode(node);//if ( !mapNode )//    return usage(argv);// [1 end]// [2 begin] 方式二,通过readNodeFile方式加载earth文件。方便调试代码测试const std::string earthFile = "F:/osgData/Data/earth_image/china-simple.earth";osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(earthFile);// 将earth文件作为一个节点if (!node.valid())return -1;osg::ref_ptr<osgEarth::MapNode> mapNode;mapNode = dynamic_cast<osgEarth::MapNode*>(node.get());// 强制转换为地图节点osg::ref_ptr<osgEarth::Util::EarthManipulator> em;em = new osgEarth::Util::EarthManipulator;if (!mapNode.valid())return -1;em->setNode(mapNode);//因为设置了节点,将忽略“焦点”,节点不会序列化到Config中em->getSettings()->setArcViewpointTransitions(true);// 获取当前操纵器设置对象的句柄,并转为弧形osgViewer::Viewer viewer;viewer.setCameraManipulator(em);// 为主摄像机设置相机操作器root->addChild(node);// 将地图节点放入根节点,根节点再放入场景。其实也可以直接将node放入场景// [2 end]// Group to hold all our annotation elements.// 后面所有的元素结点均添加到annoGroup结点下osg::Group* annoGroup = new osg::Group();MapNode::get(node)->addChild( annoGroup );// Make a group for labelsosg::Group* labelGroup = new osg::Group();annoGroup->addChild( labelGroup );osg::Group* editGroup = new osg::Group();MapNode::get(node)->addChild( editGroup );// Style our labels:Style labelStyle;labelStyle.getOrCreate<TextSymbol>()->alignment() = TextSymbol::ALIGN_CENTER_CENTER;// label的对齐方式labelStyle.getOrCreate<TextSymbol>()->fill()->color() = Color::Yellow;// 设置文本颜色// A lat/long SRS for specifying points.// 可以理解为 获取 空间参考系,有了参考系,就可以给经纬高进而在指定位置进行绘制const SpatialReference* geoSRS = mapNode->getMapSRS()->getGeographicSRS();//--------------------------------------------------------------------// A series of place nodes (an icon with a text label){Style pm;pm.getOrCreate<IconSymbol>()->url()->setLiteral( "../data/placemark32.png" );// 图标资源pm.getOrCreate<IconSymbol>()->declutter() = true;pm.getOrCreate<TextSymbol>()->halo() = Color("#5f5f5f");// 文本颜色// bunch of pins:// GeoPoint 此构造方式中,默认模式为地形高度,贴地标签,高度为0labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -74.00, 40.71), "New York"      , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -77.04, 38.85), "Washington, DC", pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS,-118.40, 33.93), "Los Angeles"   , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -71.03, 42.37), "Boston"        , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS,-157.93, 21.35), "Honolulu"      , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, 139.75, 35.68), "Tokyo"         , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -90.25, 29.98), "New Orleans"   , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -80.28, 25.82), "Miami"         , pm));labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS,-117.17, 32.72), "San Diego"     , pm));// test with an LOD:osg::LOD* lod = new osg::LOD();// 通过lod设置显示范围lod->addChild( new PlaceNode(GeoPoint(geoSRS, 14.68, 50.0), "Prague", pm), 0.0, 2e6);labelGroup->addChild( lod );// absolute altitude:// GeoPoint 设置了绝对高度。另一个模式是地形以上的高度。labelGroup->addChild( new PlaceNode(GeoPoint(geoSRS, -87.65, 41.90, 1000, ALTMODE_ABSOLUTE), "Chicago", pm));}//--------------------------------------------------------------------// a box that follows lines of latitude (rhumb line interpolation, the default)// and flashes on and off using a cull callback.// 使用剔除回调打开和关闭闪烁{struct C : public osg::NodeCallback {// 重载操作符,并实现回调动画void operator()(osg::Node* n, osg::NodeVisitor* nv) {static int i=0;i++;if (i % 100 < 50)traverse(n, nv);}};Geometry* geom = new Polygon();geom->push_back( osg::Vec3d(0,   40, 0) );geom->push_back( osg::Vec3d(-60, 40, 0) );geom->push_back( osg::Vec3d(-60, 60, 0) );geom->push_back( osg::Vec3d(0,   60, 0) );Feature* feature = new Feature(geom, geoSRS);feature->geoInterp() = GEOINTERP_RHUMB_LINE;// 差值方式,直线模式Style geomStyle;geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Cyan;// 线颜色geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 5.0f;// 线宽geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000; // 细分大小geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;// 贴地形geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;// GPU渲染贴地几何体FeatureNode* fnode = new FeatureNode(feature, geomStyle);fnode->addCullCallback(new C());// 将回调方法设置到节点中annoGroup->addChild( fnode );LabelNode* label = new LabelNode("Rhumb line polygon", labelStyle);label->setPosition(GeoPoint(geoSRS, -30, 50));labelGroup->addChild(label);}//--------------------------------------------------------------------// another rhumb box that crosses the antimeridian{Geometry* geom = new Polygon();// Geometry是Polygon的父类的父类geom->push_back( -160., -30. );geom->push_back(  150., -20. );geom->push_back(  160., -45. );geom->push_back( -150., -40. );Style geomStyle;Feature* feature = new Feature(geom, geoSRS);feature->geoInterp() = GEOINTERP_RHUMB_LINE;geomStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::Lime;geomStyle.getOrCreate<LineSymbol>()->stroke()->width() = 3.0f;geomStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000;geomStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;geomStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;FeatureNode* gnode = new FeatureNode(feature, geomStyle);annoGroup->addChild( gnode );LabelNode* label = new LabelNode("Antimeridian polygon", labelStyle);label->setPosition(GeoPoint(geoSRS, -175, -35));labelGroup->addChild(label);}//--------------------------------------------------------------------// A path using great-circle interpolation.使用大圆插值的路径。// Keep a pointer to it so we can modify it later on.FeatureNode* pathNode = 0;{Geometry* path = new LineString();path->push_back( osg::Vec3d(-74, 40.714, 0) );   // New Yorkpath->push_back( osg::Vec3d(139.75, 35.68, 0) ); // TokyoFeature* pathFeature = new Feature(path, geoSRS);pathFeature->geoInterp() = GEOINTERP_GREAT_CIRCLE;// 圆形差值方法Style pathStyle;pathStyle.getOrCreate<LineSymbol>()->stroke()->color() = Color::White;pathStyle.getOrCreate<LineSymbol>()->stroke()->width() = 1.0f;pathStyle.getOrCreate<LineSymbol>()->stroke()->smooth() = true;pathStyle.getOrCreate<LineSymbol>()->tessellationSize() = 75000;pathStyle.getOrCreate<PointSymbol>()->size() = 8;// 线上绘制点的尺寸pathStyle.getOrCreate<PointSymbol>()->fill()->color() = Color::Red;// 点颜色pathStyle.getOrCreate<PointSymbol>()->smooth() = true;pathStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;pathStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_GPU;pathStyle.getOrCreate<RenderSymbol>()->depthOffset()->enabled() = true;//OE_INFO << "Path extent = " << pathFeature->getExtent().toString() << std::endl;pathNode = new FeatureNode(pathFeature, pathStyle);annoGroup->addChild( pathNode );LabelNode* label = new LabelNode("Great circle path", labelStyle);label->setPosition(GeoPoint(geoSRS,-170, 61.2));labelGroup->addChild(label);}//--------------------------------------------------------------------// Two circle segments around New Orleans.{Style circleStyle;circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Cyan, 0.5);circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;// 悬垂CircleNode* circle = new CircleNode();circle->set(GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE),Distance(300, Units::KILOMETERS),// 距离和单位circleStyle, Angle(-45.0, Units::DEGREES),// 角度Angle(45.0, Units::DEGREES),true);// 绘制并显示circle,如果注释掉此句,则不会显示图形。annoGroup->addChild( circle );// 为circle添加编辑点,让editGroup来管理circle的编辑点editGroup->addChild( new CircleNodeEditor(circle) );}{Style circleStyle;circleStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Red, 0.5);circleStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;circleStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;CircleNode* circle = new CircleNode();circle->set(GeoPoint(geoSRS, -90.25, 29.98, 1000., ALTMODE_RELATIVE),Distance(300, Units::KILOMETERS),circleStyle,Angle(45.0, Units::DEGREES),Angle(360.0 - 45.0, Units::DEGREES),true);// true-使用0-360度,如果为false,则需要使用弧度annoGroup->addChild( circle );editGroup->addChild( new CircleNodeEditor(circle) );}//--------------------------------------------------------------------// An extruded ellipse around Miami.{Style ellipseStyle;ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Orange, 0.75);// 多边形填充色ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSL 多边形高度,单位mEllipseNode* ellipse = new EllipseNode();ellipse->set(GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE),// 地形之上的高度Distance(250, Units::MILES),// 长半轴Distance(100, Units::MILES),// 短半轴Angle   (0, Units::DEGREES),// 旋转角度ellipseStyle,Angle(45.0, Units::DEGREES),// 开始角度Angle(360.0 - 45.0, Units::DEGREES), // 结束角度true); // 角度制annoGroup->addChild( ellipse );editGroup->addChild( new EllipseNodeEditor(ellipse) );}{Style ellipseStyle;ellipseStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Blue, 0.75);ellipseStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSLEllipseNode* ellipse = new EllipseNode();ellipse->set(GeoPoint(geoSRS, -80.28, 25.82, 0.0, ALTMODE_RELATIVE),Distance(250, Units::MILES),Distance(100, Units::MILES),Angle   (0, Units::DEGREES),ellipseStyle, Angle(-40.0, Units::DEGREES), Angle(40.0, Units::DEGREES), true);annoGroup->addChild( ellipse );editGroup->addChild( new EllipseNodeEditor(ellipse) );}//--------------------------------------------------------------------{// A rectangle around San DiegoStyle rectStyle;rectStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::Green, 0.5);rectStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;// 贴地rectStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;RectangleNode* rect = new RectangleNode(GeoPoint(geoSRS, -117.172, 32.721),Distance(300, Units::KILOMETERS ),Distance(600, Units::KILOMETERS ),rectStyle);annoGroup->addChild( rect );editGroup->addChild( new RectangleNodeEditor(rect) );}    //--------------------------------------------------------------------// An extruded polygon roughly the shape of Utah. Here we demonstrate the// FeatureNode, where you create a geographic geometry and use it as an// annotation.{Geometry* utah = new Polygon();utah->push_back( -114.052, 37.0   );utah->push_back( -109.054, 37.0   );utah->push_back( -109.054, 41.0   );utah->push_back( -111.040, 41.0   );utah->push_back( -111.080, 42.059 );utah->push_back( -114.080, 42.024 );Style utahStyle;utahStyle.getOrCreate<ExtrusionSymbol>()->height() = 250000.0; // meters MSLutahStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(Color::White, 0.8);// 有高度的多边形,且没有顶Feature*     utahFeature = new Feature(utah, geoSRS);FeatureNode* featureNode = new FeatureNode(utahFeature, utahStyle);annoGroup->addChild( featureNode );}//--------------------------------------------------------------------// an image overlay.{ImageOverlay* imageOverlay = 0L;osg::ref_ptr<osg::Image> image = osgDB::readRefImageFile( "../data/USFLAG.TGA" );// 读取图片,支持多种格式:ive jpg png gif rgb rgba TGAif (image.valid()){imageOverlay = new ImageOverlay(mapNode, image.get());// 创建一个遮盖图imageOverlay->setBounds( Bounds( -100.0, 35.0, -90.0, 40.0) );// 设置边界annoGroup->addChild( imageOverlay );editGroup->addChild( new ImageOverlayEditor(imageOverlay) );}}//--------------------------------------------------------------------// a model node with auto scaling.{Style style;style.getOrCreate<ModelSymbol>()->autoScale() = true;// 打开模型自动缩放style.getOrCreate<ModelSymbol>()->url()->setLiteral("../data/red_flag.osg.50.scale");// 自动放大50倍。在模型后面追加倍数和scale,就会对应缩放这么多倍ModelNode* modelNode = new ModelNode(mapNode, style); modelNode->setPosition(GeoPoint(geoSRS, -100, 52));annoGroup->addChild(modelNode);}//--------------------------------------------------------------------// initialize the viewer:    viewer.setSceneData( root ); // 剔除小特征阈值viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);return viewer.run();
}

osgEarth示例分析——osgearth_annotation相关推荐

  1. osgEarth示例分析——osgearth_skyview

    前言 本示例分析osgearth操作深空场景,或者是银河系场景,可以想象人拿着相机站在地球表面上观看天空/银河系的场景. 重点是相机操作器的使用. 在命令框输入执行程序,在data路径下有加载的图,且 ...

  2. osgEarth示例分析——osgearth_manip

    前言 本示例主要演示osgEarth的事件处理的用法,内容比较多,这部分功能也很重要. 输入命令依然采用china-simple.earth的示例,加上了模型,但是模型并没有看到,可能是因为模型没有放 ...

  3. osgEarth示例分析——osgearth_elevation

    前言 osgearth_elevation示例,展示了如何通过点击地球获取不同定义下的高程数据.包括:MSL高程.HAE高程.EGM96高程.点击按钮,可以移除高程图层. MSL高程:是mean se ...

  4. osgEarth示例分析——osgearth_graticule

    前言 本示例最具有借鉴的功能:绘制网格.网格上的文字显示.拾取地球的坐标.在地球网格示例中,可以设置4种网格.执行命令如下: // --geodetic osgearth_graticuled.exe ...

  5. osgEarth示例分析——osgearth_srstest

    前言 osgearth_srstest示例,主要涉及到两个坐标系转换,wgs84→egm96  wgs84→plate-carre wgs84:World Geodetic System 1984,是 ...

  6. osgEarth示例分析——osgearth_eci

    前言 osgearth_eci示例,展示了J2000的天体坐标系和ECEF地固系的转换,绘制坐标系,以及读取卫星参数绘制卫星的功能.绘制卫星轨迹,添加差值效果和未添加差值的效果. 关于卫星两行根数的数 ...

  7. osgEarth示例分析——osgearth_terrainprofile

    前言 osgearth_terrainprofile示例,涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类),用来计算两个点连线之间的地形数据.左下角会根据点击的起 ...

  8. osgEarth示例分析——osgearth_features

    前言 osgearth_features示例,主要演示如何通过代码方式加载shp文件,并设置其样式.在执行时,通过不同 的命令,得到不一样的效果. cmd执行命令: // rasterize 光栅化, ...

  9. osgEarth示例分析——osgearth_los

    前言 osgearth_los示例,创建了模型动画路径.透视的用法.透视的顾名思义:两个点连线,从A到B,视线不被遮挡,则绘制绿色,视线被遮挡的部分,则设置为红色.此示例,加载earth文件时,需要加 ...

最新文章

  1. 找工作刷题--------Java相关
  2. Hadoop大数据分布式文件系统hdfs的Java操作
  3. python 下载拉钩教育AES加密视频
  4. 安卓第一行代码第3版pdf_SPECFEM2D用户手册——第3章 网格生成——3.1 如何使用SPECFEM2D...
  5. BugkuCTF-Crypto题Crack it
  6. 保存文件_wps文件保存在哪里
  7. MyIfmHttpClient
  8. CSS经典书写技巧之(二)
  9. 前端vue实现PDF预览
  10. vlookup使用步骤_vlookup函数的使用方法
  11. python怎么用sin_python怎么打sin
  12. APICloud教程
  13. 济南公积金 销户 提取
  14. 小红书的大致运营思路是怎样的?
  15. 神经网络的三种训练方法,神经网络训练过程详解
  16. 学习设计到底应该学习figma、sketch还是PS
  17. 2015百度面试题--对10亿个32位整数去重和排序
  18. spring-session(一)揭秘
  19. CHP城市猎人系统开发
  20. Navicat、PDMan、DBeaver三者ER图比较

热门文章

  1. java重置按钮功能函数_Bootstrap按钮功能之查询按钮和重置按钮
  2. 基于RSSI测距的多边定位法(附代码与讲解视频)
  3. BLS 签名和基于 BLS 签名的门限签名
  4. zookeeper为什么是CP原则
  5. RegularJS 0.2.12 发布,JavaScript MVC 框架
  6. 异地多活场景下的数据同步之道
  7. Win10家庭版找不到组策略gpedit.msc
  8. 互联网项目团队成员及能力组成的金字塔和倒金字塔模型
  9. 用Ai(adobe illustrator)制作文字放射效果
  10. mysql中常用的三种插入数据的语句