1 /* -*-c++-*- */
2 /* osgEarth - Geospatial SDK for OpenSceneGraph
3  * Copyright 2019 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 <osgEarthUtil/MouseCoordsTool>
21 #include <osgEarth/MapNode>
22 #include <osgEarth/TerrainEngineNode>
23 
24 using namespace osgEarth;
25 using namespace osgEarth::Util;
26 
27 //-----------------------------------------------------------------------
28 
MouseCoordsTool(MapNode * mapNode,LabelControl * label,Formatter * formatter)29 MouseCoordsTool::MouseCoordsTool( MapNode* mapNode, LabelControl* label, Formatter* formatter ) :
30 _mapNode( mapNode )
31 {
32     _mapNodePath.push_back( mapNode->getTerrainEngine() );
33 
34     if ( label )
35     {
36         addCallback( new MouseCoordsLabelCallback(label, formatter) );
37     }
38 }
39 
40 void
addCallback(MouseCoordsTool::Callback * cb)41 MouseCoordsTool::addCallback( MouseCoordsTool::Callback* cb )
42 {
43     _callbacks.push_back( cb );
44 }
45 
46 bool
handle(const osgGA::GUIEventAdapter & ea,osgGA::GUIActionAdapter & aa)47 MouseCoordsTool::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
48 {
49     if (ea.getEventType() == ea.MOVE || ea.getEventType() == ea.DRAG)
50     {
51         osg::Vec3d world;
52         if ( _mapNode->getTerrain()->getWorldCoordsUnderMouse(aa.asView(), ea.getX(), ea.getY(), world) )
53         {
54             GeoPoint map;
55             map.fromWorld( _mapNode->getMapSRS(), world );
56 
57             for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); ++i )
58                 i->get()->set( map, aa.asView(), _mapNode );
59         }
60         else
61         {
62             for( Callbacks::iterator i = _callbacks.begin(); i != _callbacks.end(); ++i )
63                 i->get()->reset( aa.asView(), _mapNode );
64         }
65     }
66 
67     return false;
68 }
69 
70 //-----------------------------------------------------------------------
71 
MouseCoordsLabelCallback(LabelControl * label,Formatter * formatter)72 MouseCoordsLabelCallback::MouseCoordsLabelCallback( LabelControl* label, Formatter* formatter ) :
73 _label    ( label ),
74 _formatter( formatter )
75 {
76     //nop
77 }
78 
79 void
set(const GeoPoint & mapCoords,osg::View * view,MapNode * mapNode)80 MouseCoordsLabelCallback::set( const GeoPoint& mapCoords, osg::View* view, MapNode* mapNode )
81 {
82     if ( _label.valid() )
83     {
84         osg::Vec3d eye, center, up;
85         view->getCamera()->getViewMatrixAsLookAt(eye, center, up);
86         osg::Vec3d world;
87         mapCoords.toWorld(world);
88         double range = (eye-world).length();
89 
90         if ( _formatter )
91         {
92             _label->setText( Stringify()
93                 <<  _formatter->format( mapCoords )
94                 << ", " << mapCoords.z()
95                 << "; RNG:" << range
96                 << "  |  "
97                 << mapCoords.getSRS()->getName() );
98         }
99         else
100         {
101             _label->setText( Stringify()
102                 << std::fixed
103                 << mapCoords.x()
104                 << ", " << mapCoords.y()
105                 << ", " << mapCoords.z()
106                 << "; RNG:" << range
107                 << "  |  "
108                 << mapCoords.getSRS()->getName() );
109         }
110     }
111 }
112 
113 void
reset(osg::View * view,MapNode * mapNode)114 MouseCoordsLabelCallback::reset( osg::View* view, MapNode* mapNode )
115 {
116     if ( _label.valid() )
117     {
118         _label->setText( "" );
119         _label->setText(Stringify() << "No data  |  " << mapNode->getMapSRS()->getName() );
120     }
121 }
122 
123 //-----------------------------------------------------------------------
124