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