~ubuntu-branches/debian/sid/osgearth/sid

« back to all changes in this revision

Viewing changes to src/applications/osgearth_elevation/osgearth_elevation.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Pirmin Kalberer
  • Date: 2011-07-14 22:13:36 UTC
  • Revision ID: james.westby@ubuntu.com-20110714221336-94igk9rskxveh794
Tags: upstream-2.0+dfsg
ImportĀ upstreamĀ versionĀ 2.0+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*-c++-*- */
 
2
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 
3
* Copyright 2008-2010 Pelican Mapping
 
4
* http://osgearth.org
 
5
*
 
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.
 
10
*
 
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.
 
15
*
 
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/>
 
18
*/
 
19
 
 
20
#include <osg/Notify>
 
21
#include <osg/Shape>
 
22
#include <osg/ShapeDrawable>
 
23
#include <osg/Geode>
 
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>
 
37
#include <sstream>
 
38
 
 
39
using namespace osgEarth::Drivers;
 
40
 
 
41
static
 
42
osg::MatrixTransform* createFlag()
 
43
{
 
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 );
 
58
    at->addChild( g );
 
59
    at->getOrCreateStateSet()->setMode( GL_LIGHTING, 0 );
 
60
    osg::MatrixTransform* xf = new osg::MatrixTransform();
 
61
    xf->addChild( at );
 
62
    xf->setDataVariance( osg::Object::DYNAMIC );
 
63
    return xf;
 
64
}
 
65
 
 
66
static void
 
67
updateFlag( osg::MatrixTransform* xf, const osg::Matrix& mat, double elev )
 
68
{
 
69
    osg::Geode* g = static_cast<osg::Geode*>( xf->getChild(0)->asGroup()->getChild(0) );
 
70
    std::stringstream buf;
 
71
    buf << elev;
 
72
        std::string bufStr;
 
73
        bufStr = buf.str();
 
74
    static_cast<osgText::Text*>( g->getDrawable(1) )->setText( bufStr );
 
75
    xf->setMatrix( mat );
 
76
}
 
77
 
 
78
// An event handler that will print out the elevation at the clicked point
 
79
struct QueryElevationHandler : public osgGA::GUIEventHandler 
 
80
{
 
81
    QueryElevationHandler(osgEarth::Util::ElevationManager* elevMan, 
 
82
                          const osgEarth::SpatialReference* mapSRS,
 
83
                          osg::MatrixTransform* flag )
 
84
        : _mouseDown(false), _elevMan(elevMan), _flag(flag), _mapSRS(mapSRS) { }
 
85
 
 
86
    void update( float x, float y, osgViewer::View* view )
 
87
    {
 
88
        osgUtil::LineSegmentIntersector::Intersections results;
 
89
        if ( view->computeIntersections( x, y, results, 0x01 ) )
 
90
        {
 
91
            // find the first hit under the mouse:
 
92
            osgUtil::LineSegmentIntersector::Intersection first = *(results.begin());
 
93
            osg::Vec3d point = first.getWorldIntersectPoint();
 
94
            
 
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 );
 
98
            
 
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;
 
106
 
 
107
            if ( _elevMan->getPlacementMatrix(
 
108
                lon_deg, lat_deg, 0,
 
109
                query_resolution, NULL,
 
110
                out_mat, out_elevation, out_resolution ) )
 
111
            {
 
112
                updateFlag( _flag.get(), out_mat, out_elevation );
 
113
            }
 
114
            else
 
115
            {
 
116
                OE_NOTICE
 
117
                    << "getElevation FAILED! at (" << lat_deg << ", " << lon_deg << ")" << std::endl;
 
118
            }
 
119
 
 
120
        }
 
121
    }
 
122
 
 
123
    bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
 
124
    {
 
125
        if ( ea.getEventType() == osgGA::GUIEventAdapter::MOVE )
 
126
        {
 
127
            osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
 
128
            update( ea.getX(), ea.getY(), view );
 
129
        }
 
130
 
 
131
        return false;
 
132
    }
 
133
 
 
134
    bool _mouseDown;
 
135
    osg::ref_ptr<osgEarth::Util::ElevationManager> _elevMan;
 
136
    osg::ref_ptr<osg::MatrixTransform> _flag;
 
137
    osg::ref_ptr<const SpatialReference> _mapSRS;
 
138
};
 
139
 
 
140
 
 
141
int main(int argc, char** argv)
 
142
{
 
143
    osg::ArgumentParser arguments(&argc,argv);
 
144
 
 
145
    osgViewer::Viewer viewer(arguments);
 
146
 
 
147
    // install the programmable manipulator.
 
148
    osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator();
 
149
    viewer.setCameraManipulator( manip );
 
150
 
 
151
        osgEarth::MapNode* mapNode = NULL;
 
152
 
 
153
        osg::Node* loadedNode = osgDB::readNodeFiles( arguments );
 
154
        if (!loadedNode)
 
155
        {
 
156
                // load up a map with an elevation layer:
 
157
                osgEarth::Map* map = new osgEarth::Map();
 
158
 
 
159
                // Add some imagery
 
160
                {
 
161
                        TMSOptions tms( "http://demo.pelicanmapping.com/rmweb/data/bluemarble-tms/tms.xml" );
 
162
            map->addImageLayer( new osgEarth::ImageLayer( "BLUEMARBLE", tms ) );
 
163
                }
 
164
 
 
165
                // Add some elevation
 
166
                {
 
167
                        TMSOptions tms( "http://demo.pelicanmapping.com/rmweb/data/srtm30_plus_tms/tms.xml" );
 
168
            map->addElevationLayer( new osgEarth::ElevationLayer( "SRTM", tms ) );
 
169
                }
 
170
                mapNode = new osgEarth::MapNode( map );
 
171
        }
 
172
        else
 
173
        {
 
174
                mapNode = findTopMostNodeOfType<osgEarth::MapNode>( loadedNode );
 
175
        }
 
176
 
 
177
    osg::Group* root = new osg::Group();
 
178
 
 
179
    // The MapNode will render the Map object in the scene graph.
 
180
    mapNode->setNodeMask( 0x01 );
 
181
    root->addChild( mapNode );
 
182
 
 
183
    // A flag so we can see where we clicked
 
184
    osg::MatrixTransform* flag = createFlag();
 
185
    flag->setNodeMask( 0x02 );
 
186
    root->addChild( flag );
 
187
 
 
188
    viewer.setSceneData( root );
 
189
 
 
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 );
 
194
 
 
195
    // An event handler that will respond to mouse clicks:
 
196
    viewer.addEventHandler( new QueryElevationHandler( elevMan, mapNode->getMap()->getProfile()->getSRS(), flag ) );
 
197
 
 
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()));
 
202
 
 
203
    return viewer.run();
 
204
}