前言
本示例最具有借鉴的功能:绘制网格、网格上的文字显示、拾取地球的坐标。在地球网格示例中,可以设置4种网格。执行命令如下:
// --geodetic
osgearth_graticuled.exe --geodetic earth_image\china-simple.earth
// --utm
osgearth_graticuled.exe --utm earth_image\china-simple.earth
// --mgrs
osgearth_graticuled.exe --mgrs earth_image\china-simple.earth
// --gars
osgearth_graticuled.exe --gars earth_image\china-simple.earth
运行状态如下:
--geodetic 显示经纬网格,且左上角是经纬高,WGS84坐标系下。
--utm 地球上显示的字符,左上角显示坐标信息,WGS84坐标系
--utm 仅左上角显示坐标信息,高程为负值,是因为没有添加高程值,WGS84坐标系
--utm 仅左上角显示坐标信息,高程为负值,是因为没有添加高程值,WGS84坐标系
类结构分析
不同的坐标系网格图层,适用不同的坐标格式化方式。
GARS坐标系:“GARS”经常作为“Global Area Reference System”的缩写来使用,中文表示:“全球区域参考系统”。
Geodetic坐标系: 是一种地球参考系和地心坐标系。它有WGS60、WGS66、WGS72、WGS84等,是全球定位系统(GPS)的参考构架。
UTM坐标系:UTM(Universal Transverse Mercator Grid System,通用横墨卡托格网系统)坐标是一种平面直角坐标,这种坐标格网系统及其所依据的投影已经广泛用于地形图,作为卫星影像和自然资源数据库的参考格网以及要求精确定位的其他应用。
MGRS坐标系:军事格网参考系 (MGRS) 是一种基于格网的参考系,用于在通用横轴墨卡托投影 (UTM) 和通用极方位立体投影 (UPS) 格网系中以字母数字字符串的形式表示位置。与定义特定点不同,MGRS 坐标定义的是地球表面上的某个区域。完全限定的 MGRS 字符串长度为 15 个字符,由以下三个部分组成:格网区域标识、100,000 平方米标识符以及东移/北移。
左上角显示经纬度信息的ui控件关系图:
代码分析
#include <osg/Notify>
#include <osgGA/StateSetManipulator>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgEarth/MapNode> // 地图节点
#include <osgEarthUtil/EarthManipulator> // 地球操作器
#include <osgEarthUtil/MouseCoordsTool> // 将鼠标下的地图坐标打印到LabelControl中的工具。
#include <osgEarthUtil/MGRSFormatter> // 将坐标数据格式化为MGRS。
#include <osgEarthUtil/LatLongFormatter> // 格式化大地坐标(纬度/经度)。
#include <osgEarthUtil/GeodeticGraticule> // 处理网格
#include <osgEarthUtil/MGRSGraticule> // MGRS网格
#include <osgEarthUtil/UTMGraticule> // UTM网格
#include <osgEarthUtil/GARSGraticule> // GARS网格
using namespace osgEarth::Util;
using namespace osgEarth::Annotation;
int
usage( const std::string& msg )
{
OE_NOTICE
<< msg << std::endl
<< "USAGE: osgearth_graticule [options] file.earth" << std::endl
<< " --geodetic : display a Lat/Long graticule" << std::endl
<< " --utm : display a UTM graticule" << std::endl
<< " --mgrs : display an MGRS graticule" << std::endl
<< " --gars : display a GARS graticule" << std::endl;
return -1;
}
//------------------------------------------------------------------------
int
main(int argc, char** argv)
{
// 执行时,程序名 + earth路径
osg::ArgumentParser arguments(&argc,argv);
osgViewer::Viewer viewer(arguments);
// parse command line:
bool isUTM = arguments.read("--utm");
bool isMGRS = arguments.read("--mgrs");
bool isGeodetic = arguments.read("--geodetic");
bool isGARS = arguments.read("--gars");
// load the .earth file from the command line.
MapNode* mapNode = MapNode::load( arguments );
if ( !mapNode )
return usage( "Failed to load a map from the .earth file" );
// install our manipulator:
viewer.setCameraManipulator( new EarthManipulator() );
// root scene graph:
osg::Group* root = new osg::Group();
root->addChild( mapNode );
// 坐标格式器的接口类
Formatter* formatter = 0L;
if ( isUTM )
{
UTMGraticule* gr = new UTMGraticule(); // UTM网格
mapNode->getMap()->addLayer(gr); // 将UTM网格加入到图层
formatter = new MGRSFormatter();
std::cout << "isUTM,Universal Transverse Mercator Grid System,通用横墨卡托格网系统" << std::endl;
}
else if ( isMGRS )
{
MGRSGraticule* gr = new MGRSGraticule();
mapNode->getMap()->addLayer(gr);
formatter = new MGRSFormatter();
std::cout << "isMGRS,军事格网参考系 (MGRS) " << std::endl;
}
else if ( isGARS )
{
GARSGraticule* gr = new GARSGraticule();
mapNode->getMap()->addLayer(gr);
formatter = new LatLongFormatter();
std::cout << "isGARS: Global Area Reference System--全球区域参考系统" << std::endl;
}
else // if ( isGeodetic )
{
GeodeticGraticule* gr = new GeodeticGraticule();
mapNode->getMap()->addLayer(gr);
formatter = new LatLongFormatter();
std::cout << "isGeodetic,大地测量地心坐标系" << std::endl;
}
// mouse coordinate readout:
ControlCanvas* canvas = new ControlCanvas();// 将控件与OSG视图关联对象
root->addChild( canvas );
VBox* vbox = new VBox();// 垂直布局,垂直堆叠控件的容器。
canvas->addControl( vbox );
LabelControl* readout = new LabelControl();// 包含字符串的控件
vbox->addControl( readout );
MouseCoordsTool* tool = new MouseCoordsTool( mapNode );//将鼠标下地图坐标写入控件
tool->addCallback( new MouseCoordsLabelCallback(readout, formatter) );
viewer.addEventHandler( tool );
// disable the small-feature culling
viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);
// set a near/far ratio that is smaller than the default. This allows us to get
// closer to the ground without near clipping. If you need more, use --logdepth
viewer.getCamera()->setNearFarRatio(0.0001);
// finalize setup and run.
viewer.setSceneData( root );
viewer.addEventHandler(new osgViewer::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new osgViewer::ThreadingHandler());
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
return viewer.run();
}