• osgEarth示例分析——osgearth_geodetic_graticule


    前言

    osgearth_geodetic_graticule示例,是展示网格控制的案例。可以修改网格的显隐、经纬度label的显隐及颜色、以及是否让经纬度label靠边缘显示、整个网格图层的显隐控制。

    cmd 命令框输入:

    osgearth_geodetic_graticuled.exe earth_image\china-simple.earth

    效果

    左上角是5个ui按钮

     代码分析

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. using namespace osgEarth;
    13. using namespace osgEarth::Util;
    14. using namespace osgEarth::Symbology;
    15. namespace ui = osgEarth::Util::Controls;
    16. // osgearth\src\osgEarthUtil\ExampleResources 文件中的宏定义如下:
    17. #define OE_UI_HANDLER(X) \
    18. struct X : public osgEarth::Util::Controls::ControlEventHandler { \
    19. App& _app; X(App& app):_app(app) { } \
    20. void onValueChanged(osgEarth::Util::Controls::Control*) { _app. X (); } \
    21. void onClick(osgEarth::Util::Controls::Control*) { _app. X (); } }
    22. int
    23. usage( char** argv, const std::string& msg )
    24. {
    25. OE_NOTICE
    26. << msg << std::endl
    27. << "USAGE: " << argv[0] << " file.earth" << std::endl;
    28. return -1;
    29. }
    30. const osg::Vec4 colors[4] = { osg::Vec4(1,1,1,1), osg::Vec4(1,0,0,1), osg::Vec4(1,1,0,1), osg::Vec4(0,1,0,1) };
    31. struct App
    32. {
    33. // 显示经纬线,并自动放置label
    34. GeodeticGraticule* graticule;
    35. int gridColorIndex;
    36. int edgeColorIndex;
    37. App(GeodeticGraticule* g)
    38. {
    39. graticule = g;
    40. gridColorIndex = 0;// 网格颜色索引,用于更改网格颜色
    41. edgeColorIndex = 1;// 是否靠边显示经纬度的label
    42. }
    43. // 改变经纬度标签的颜色
    44. void cycleStyles()
    45. {
    46. // Could also use the get/setGridLabelStyle API here, but this demonstrates
    47. // changing the options and calling dirty() or apply().
    48. // 改变label标签颜色
    49. Style gridLabelStyle = graticule->options().gridLabelStyle().get();
    50. gridColorIndex = (gridColorIndex+1)%4;
    51. gridLabelStyle.getOrCreate()->fill()->color() = colors[gridColorIndex];
    52. graticule->options().gridLabelStyle() = gridLabelStyle;
    53. // 当label标签靠近边缘显示时,也同时改变边缘label的颜色
    54. Style edgeLabelStyle = graticule->options().edgeLabelStyle().get(); //graticule->getEdgeLabelStyle();
    55. edgeColorIndex = (edgeColorIndex+1)%4;
    56. edgeLabelStyle.getOrCreate()->fill()->color() = colors[edgeColorIndex];
    57. graticule->options().edgeLabelStyle() = edgeLabelStyle;
    58. graticule->dirty();
    59. }
    60. // 切换网格标签可见性
    61. void toggleGridLabels()
    62. {
    63. bool vis = graticule->getGridLabelsVisible();
    64. graticule->setGridLabelsVisible(!vis);
    65. }
    66. // 切换标签到边缘显示或者网格上显示
    67. void toggleEdgeLabels()
    68. {
    69. // 需要先判断是否地球放大到可以在边缘显示label
    70. bool vis = graticule->getEdgeLabelsVisible();
    71. graticule->setEdgeLabelsVisible(!vis);
    72. }
    73. // 切换网格可见性
    74. void toggleGrid()
    75. {
    76. bool vis = graticule->getGridLinesVisible();
    77. graticule->setGridLinesVisible(!vis);
    78. }
    79. // 切换图层可见性(网格和标签一起控制)
    80. void toggleLayer()
    81. {
    82. bool vis = graticule->getVisible();
    83. graticule->setVisible(!vis);
    84. }
    85. };
    86. // 定义一个宏,继承osgEarth::Util::Controls::ControlEventHandler,
    87. // 实现以下结构体的点击方法
    88. // new 每一个结构体时,需要传入app,且app对应的方法与该结构体同名。
    89. OE_UI_HANDLER(cycleStyles);
    90. OE_UI_HANDLER(toggleGridLabels);
    91. OE_UI_HANDLER(toggleEdgeLabels);
    92. OE_UI_HANDLER(toggleGrid);
    93. OE_UI_HANDLER(toggleLayer);
    94. ui::Control* makeUI(App& app)
    95. {
    96. ui::VBox* b = new ui::VBox();// 垂直布局
    97. b->addChild(new ui::ButtonControl("Change styles", new cycleStyles(app)));// 改变经纬度标签的颜色
    98. b->addChild(new ui::ButtonControl("Toggle grid labels", new toggleGridLabels(app)));// 切换经纬度label显隐
    99. b->addChild(new ui::ButtonControl("Toggle edge labels", new toggleEdgeLabels(app)));// 当地球放大后,可以实现切换label在边缘显示和中间显示
    100. b->addChild(new ui::ButtonControl("Toggle grid visibility", new toggleGrid(app)));// 切换经纬网格显隐,label保留
    101. b->addChild(new ui::ButtonControl("Toggle layer visibility", new toggleLayer(app)));// 经纬网格和label一起显隐,即整个图层的显隐
    102. return b;
    103. }
    104. int
    105. main(int argc, char** argv)
    106. {
    107. osg::ArgumentParser arguments(&argc,argv);
    108. osgViewer::Viewer viewer(arguments);
    109. // 初始化默认状态
    110. GLUtils::setGlobalDefaults(viewer.getCamera()->getOrCreateStateSet());
    111. // 设置图形操作以调用查看器图形窗口的实现。
    112. viewer.setRealizeOperation(new GL3RealizeOperation());
    113. // 所有示例均设置为-1.0,猜测应该是禁用 最小特征剔除像素尺寸 功能
    114. viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);
    115. // load the .earth file from the command line.
    116. MapNode* mapNode = MapNode::load(arguments);
    117. if ( !mapNode )
    118. return usage( argv, "Failed to load a map from the .earth file" );
    119. viewer.setSceneData(mapNode);
    120. viewer.setCameraManipulator( new EarthManipulator() );
    121. // 经纬网格类
    122. GeodeticGraticule* graticule = new GeodeticGraticule();
    123. // 将此类加入到map图层中
    124. mapNode->getMap()->addLayer(graticule);
    125. // ui控制
    126. App app(graticule);
    127. // 将控件与OSG视图关联。
    128. ui::ControlCanvas* canvas = ui::ControlCanvas::getOrCreate(&viewer);
    129. // 将ui控件组加入到canvas中
    130. canvas->addControl(makeUI(app));
    131. // 设置事件处理器和操作器
    132. viewer.addEventHandler(new osgViewer::StatsHandler());
    133. viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    134. return viewer.run();
    135. }

  • 相关阅读:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task
    python 网络爬虫全流程教学,从入门到实战(requests+bs4+存储文件)
    Kotlin高仿微信-第6篇-主页-我的
    处理一对多的映射关系
    自学JavaScript第五天- JS 进阶:jQuery
    传感器特点汇总
    21天学习挑战赛—Python学习记录第一篇
    4.4 文件管理
    现代修谱,如何处理族员离婚再娶,配偶携子改嫁同服弟等情况
    Python学习第1天:Python和Vscode环境安装
  • 原文地址:https://blog.csdn.net/qq_34732729/article/details/128156027