osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_elevation/osgearth_elevation.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003 * Copyright 2008-2010 Pelican Mapping
00004 * http://osgearth.org
00005 *
00006 * osgEarth is free software; you can redistribute it and/or modify
00007 * it under the terms of the GNU Lesser General Public License as published by
00008 * the Free Software Foundation; either version 2 of the License, or
00009 * (at your option) any later version.
00010 *
00011 * This program is distributed in the hope that it will be useful,
00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 * GNU Lesser General Public License for more details.
00015 *
00016 * You should have received a copy of the GNU Lesser General Public License
00017 * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018 */
00019 
00020 #include <osg/Notify>
00021 #include <osg/Shape>
00022 #include <osg/ShapeDrawable>
00023 #include <osg/Geode>
00024 #include <osg/AutoTransform>
00025 #include <osg/MatrixTransform>
00026 #include <osgText/Text>
00027 #include <osgGA/StateSetManipulator>
00028 #include <osgGA/GUIEventHandler>
00029 #include <osgViewer/Viewer>
00030 #include <osgViewer/ViewerEventHandlers>
00031 #include <osgUtil/LineSegmentIntersector>
00032 #include <osgEarth/MapNode>
00033 #include <osgEarth/FindNode>
00034 #include <osgEarth/ElevationQuery>
00035 #include <osgEarthUtil/EarthManipulator>
00036 #include <osgEarthUtil/ObjectLocator>
00037 #include <osg/Depth>
00038 #include <sstream>
00039 #include <iomanip>
00040 
00041 using namespace osgEarth;
00042 using namespace osgEarth::Util;
00043 
00044 static osg::Node*     s_flagNode;
00045 static osgText::Text* s_flagText;
00046 
00047 static
00048 osg::Node* createFlag()
00049 {
00050     osg::Geode* g = new osg::Geode();
00051     osgText::Text* text = new osgText::Text();
00052     text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );
00053     text->setCharacterSize( 24.f );
00054     text->setFont( osgText::readFontFile("arial.ttf") );
00055     text->setBackdropType( osgText::Text::OUTLINE );
00056     text->setText( "00000000000000" );
00057     text->setAutoRotateToScreen( true );
00058     text->setPosition( osg::Vec3d( 0, 0, 0 ) );
00059     text->setDataVariance( osg::Object::DYNAMIC );
00060     g->addDrawable( text );
00061     g->getOrCreateStateSet()->setMode( GL_LIGHTING, 0 );
00062     g->getStateSet()->setAttribute( new osg::Depth(osg::Depth::ALWAYS), 1 );
00063     g->getStateSet()->setRenderBinDetails( 99, "RenderBin" );
00064     g->setDataVariance( osg::Object::DYNAMIC );
00065     g->setCullingActive( false );
00066     g->setNodeMask( 0 );
00067     s_flagText = text;
00068     s_flagNode = g;
00069     return g;
00070 }
00071 
00072 // An event handler that will print out the elevation at the clicked point
00073 struct QueryElevationHandler : public osgGA::GUIEventHandler 
00074 {
00075     QueryElevationHandler(const Map* map, ObjectLocator* flagLocator ) 
00076         : _map(map),
00077           _mouseDown( false ), 
00078           _flagLocator(flagLocator), 
00079           _query(map)
00080     {
00081         _query.setMaxTilesToCache(10);
00082     }
00083 
00084     void update( float x, float y, osgViewer::View* view )
00085     {
00086         osgUtil::LineSegmentIntersector::Intersections results;
00087         if ( view->computeIntersections( x, y, results, 0x01 ) )
00088         {
00089             // find the first hit under the mouse:
00090             osgUtil::LineSegmentIntersector::Intersection first = *(results.begin());
00091             osg::Vec3d point = first.getWorldIntersectPoint();
00092             osg::Vec3d lla;
00093             
00094             // transform it to map coordinates:
00095             _map->worldPointToMapPoint(point, lla);
00096 
00097             // find the elevation at that map point:
00098             osg::Matrixd out_mat;
00099             double query_resolution = 0.1; // 1/10th of a degree
00100             double out_elevation = 0.0;
00101             double out_resolution = 0.0;
00102 
00103             bool ok = _query.getElevation( 
00104                 lla,
00105                 _map->getProfile()->getSRS(),
00106                 out_elevation, 
00107                 query_resolution, 
00108                 &out_resolution );
00109 
00110             if ( ok )
00111             {
00112                 _flagLocator->setPosition( osg::Vec3d(lla.x(), lla.y(), out_elevation) );
00113                 s_flagNode->setNodeMask( ~0 );
00114 
00115                 std::stringstream buf;
00116                 buf << std::fixed << std::setprecision(2) 
00117                     << "Pos: " << lla.x() << ", " << lla.y() << std::endl
00118                     << "Elv: " << out_elevation << "m" << std::endl
00119                     << "X:   " << point.x() << std::endl
00120                     << "Y:   " << point.y() << std::endl
00121                     << "Z:   " << point.z();
00122                 s_flagText->setText( buf.str() );
00123 
00124                 OE_NOTICE << buf.str() << std::endl;
00125             }
00126             else
00127             {
00128                 OE_NOTICE
00129                     << "getElevation FAILED! at (" << point.x() << ", " << point.y() << ")" << std::endl;
00130             }
00131 
00132         }
00133         else
00134         {
00135             s_flagNode->setNodeMask(0);
00136         }
00137     }
00138 
00139     bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
00140     {
00141         if ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE )
00142         {
00143             osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
00144             update( ea.getX(), ea.getY(), view );
00145         }
00146 
00147         return false;
00148     }
00149 
00150     const Map*       _map;
00151     bool             _mouseDown;
00152     ElevationQuery   _query;
00153     ObjectLocator*   _flagLocator;
00154 };
00155 
00156 
00157 int main(int argc, char** argv)
00158 {
00159     osg::ArgumentParser arguments(&argc,argv);
00160 
00161     osgViewer::Viewer viewer(arguments);
00162 
00163         osgEarth::MapNode* mapNode = NULL;
00164 
00165         osg::Node* loadedNode = osgDB::readNodeFiles( arguments );
00166     if (loadedNode)
00167     {
00168                 mapNode = findTopMostNodeOfType<osgEarth::MapNode>( loadedNode );
00169     }
00170 
00171     if ( !mapNode )
00172     {
00173         OE_WARN << "Unable to load earth file." << std::endl;
00174         return -1;
00175     }
00176 
00177     osg::Group* root = new osg::Group();
00178 
00179     // The MapNode will render the Map object in the scene graph.
00180     mapNode->setNodeMask( 0x01 );
00181     root->addChild( mapNode );
00182 
00183     // A flag so we can see where we clicked
00184     ObjectLocatorNode* flag = new ObjectLocatorNode( mapNode->getMap() );
00185     flag->addChild( createFlag() );
00186     flag->setNodeMask( 0x02 );
00187     root->addChild( flag );
00188 
00189     viewer.setSceneData( root );
00190 
00191     // An event handler that will respond to mouse clicks:
00192     viewer.addEventHandler( new QueryElevationHandler( mapNode->getMap(), flag->getLocator() ) );
00193 
00194     // add some stock OSG handlers:
00195     viewer.addEventHandler(new osgViewer::StatsHandler());
00196     viewer.addEventHandler(new osgViewer::WindowSizeHandler());
00197     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
00198 
00199     // install the programmable manipulator.
00200     if ( mapNode->getMap()->isGeocentric() )
00201         viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator() );
00202 
00203     return viewer.run();
00204 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines