2
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
3
* Copyright 2008-2010 Pelican Mapping
6
* osgEarth is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>
22
#include <osg/ShapeDrawable>
24
#include <osg/AutoTransform>
25
#include <osg/MatrixTransform>
26
#include <osgText/Text>
27
#include <osgGA/StateSetManipulator>
28
#include <osgGA/GUIEventHandler>
29
#include <osgViewer/Viewer>
30
#include <osgViewer/ViewerEventHandlers>
31
#include <osgUtil/LineSegmentIntersector>
32
#include <osgEarth/MapNode>
33
#include <osgEarth/FindNode>
34
#include <osgEarthUtil/EarthManipulator>
35
#include <osgEarthUtil/ElevationManager>
36
#include <osgEarthDrivers/tms/TMSOptions>
39
using namespace osgEarth::Drivers;
42
osg::MatrixTransform* createFlag()
44
osg::Cylinder* c = new osg::Cylinder( osg::Vec3d(0,0,0), 2.0f, 250.f );
45
osg::Geode* g = new osg::Geode();
46
g->addDrawable( new osg::ShapeDrawable( c ) );
47
osgText::Text* text = new osgText::Text();
48
text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );
49
text->setCharacterSize( 72.f );
50
text->setBackdropType( osgText::Text::OUTLINE );
51
text->setText( "00000000000000" );
52
text->setAutoRotateToScreen( true );
53
text->setPosition( osg::Vec3d( 0, 0, 125 ) );
54
text->setDataVariance( osg::Object::DYNAMIC );
55
g->addDrawable( text );
56
osg::AutoTransform* at = new osg::AutoTransform();
57
at->setAutoScaleToScreen( true );
59
at->getOrCreateStateSet()->setMode( GL_LIGHTING, 0 );
60
osg::MatrixTransform* xf = new osg::MatrixTransform();
62
xf->setDataVariance( osg::Object::DYNAMIC );
67
updateFlag( osg::MatrixTransform* xf, const osg::Matrix& mat, double elev )
69
osg::Geode* g = static_cast<osg::Geode*>( xf->getChild(0)->asGroup()->getChild(0) );
70
std::stringstream buf;
74
static_cast<osgText::Text*>( g->getDrawable(1) )->setText( bufStr );
78
// An event handler that will print out the elevation at the clicked point
79
struct QueryElevationHandler : public osgGA::GUIEventHandler
81
QueryElevationHandler(osgEarth::Util::ElevationManager* elevMan,
82
const osgEarth::SpatialReference* mapSRS,
83
osg::MatrixTransform* flag )
84
: _mouseDown(false), _elevMan(elevMan), _flag(flag), _mapSRS(mapSRS) { }
86
void update( float x, float y, osgViewer::View* view )
88
osgUtil::LineSegmentIntersector::Intersections results;
89
if ( view->computeIntersections( x, y, results, 0x01 ) )
91
// find the first hit under the mouse:
92
osgUtil::LineSegmentIntersector::Intersection first = *(results.begin());
93
osg::Vec3d point = first.getWorldIntersectPoint();
95
// transform it to map coordinates:
96
double lat_rad, lon_rad, height;
97
_mapSRS->getEllipsoid()->convertXYZToLatLongHeight( point.x(), point.y(), point.z(), lat_rad, lon_rad, height );
99
// query the elevation at the map point:
100
double lat_deg = osg::RadiansToDegrees( lat_rad );
101
double lon_deg = osg::RadiansToDegrees( lon_rad );
102
osg::Matrixd out_mat;
103
double query_resolution = 0.1; // 1/10th of a degree
104
double out_elevation = 0.0;
105
double out_resolution = 0.0;
107
if ( _elevMan->getPlacementMatrix(
109
query_resolution, NULL,
110
out_mat, out_elevation, out_resolution ) )
112
updateFlag( _flag.get(), out_mat, out_elevation );
117
<< "getElevation FAILED! at (" << lat_deg << ", " << lon_deg << ")" << std::endl;
123
bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
125
if ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE )
127
osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
128
update( ea.getX(), ea.getY(), view );
135
osg::ref_ptr<osgEarth::Util::ElevationManager> _elevMan;
136
osg::ref_ptr<osg::MatrixTransform> _flag;
137
osg::ref_ptr<const SpatialReference> _mapSRS;
141
int main(int argc, char** argv)
143
osg::ArgumentParser arguments(&argc,argv);
145
osgViewer::Viewer viewer(arguments);
147
// install the programmable manipulator.
148
osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator();
149
viewer.setCameraManipulator( manip );
151
osgEarth::MapNode* mapNode = NULL;
153
osg::Node* loadedNode = osgDB::readNodeFiles( arguments );
156
// load up a map with an elevation layer:
157
osgEarth::Map* map = new osgEarth::Map();
161
TMSOptions tms( "http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml" );
162
map->addImageLayer( new osgEarth::ImageLayer( "BLUEMARBLE", tms ) );
165
// Add some elevation
167
TMSOptions tms( "http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml" );
168
map->addElevationLayer( new osgEarth::ElevationLayer( "SRTM", tms ) );
170
mapNode = new osgEarth::MapNode( map );
174
mapNode = findTopMostNodeOfType<osgEarth::MapNode>( loadedNode );
177
osg::Group* root = new osg::Group();
179
// The MapNode will render the Map object in the scene graph.
180
mapNode->setNodeMask( 0x01 );
181
root->addChild( mapNode );
183
// A flag so we can see where we clicked
184
osg::MatrixTransform* flag = createFlag();
185
flag->setNodeMask( 0x02 );
186
root->addChild( flag );
188
viewer.setSceneData( root );
190
// AN elevation manager that is tied to the map node:
191
osgEarth::Util::ElevationManager* elevMan = new osgEarth::Util::ElevationManager( mapNode->getMap() );
192
elevMan->setTechnique( osgEarth::Util::ElevationManager::TECHNIQUE_PARAMETRIC );
193
elevMan->setMaxTilesToCache( 10 );
195
// An event handler that will respond to mouse clicks:
196
viewer.addEventHandler( new QueryElevationHandler( elevMan, mapNode->getMap()->getProfile()->getSRS(), flag ) );
198
// add some stock OSG handlers:
199
viewer.addEventHandler(new osgViewer::StatsHandler());
200
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
201
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));