osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthUtil/FeatureEditing.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 <osgEarthUtil/FeatureEditing>
00021 #include <osgEarthUtil/Draggers>
00022 
00023 using namespace osgEarth::Util;
00024 using namespace osgEarth::Symbology;
00025 using namespace osgEarth::Features;
00026 
00027 /****************************************************************/
00028 AddPointHandler::AddPointHandler(Feature* feature, FeatureListSource* source, const osgEarth::SpatialReference* mapSRS):
00029 _feature(feature),
00030 _source( source ),
00031 _mapSRS( mapSRS ),
00032 _mouseDown( false ),
00033 _firstMove( false ),
00034 _mouseButton( osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON ),
00035 _intersectionMask( 0xffffffff )
00036 {
00037 }
00038 
00039 void
00040 AddPointHandler::setMouseButton( osgGA::GUIEventAdapter::MouseButtonMask mouseButton)
00041 {
00042     _mouseButton = mouseButton;
00043 }
00044 
00045 osgGA::GUIEventAdapter::MouseButtonMask
00046 AddPointHandler::getMouseButton() const
00047 {
00048     return _mouseButton;
00049 }
00050 
00051 bool
00052 AddPointHandler::addPoint( float x, float y, osgViewer::View* view )
00053 {
00054     osgUtil::LineSegmentIntersector::Intersections results;
00055     if ( view->computeIntersections( x, y, results, _intersectionMask ) )
00056     {
00057         // find the first hit under the mouse:
00058         osgUtil::LineSegmentIntersector::Intersection first = *(results.begin());
00059         osg::Vec3d point = first.getWorldIntersectPoint();
00060 
00061         // transform it to map coordinates:
00062         double lat_rad, lon_rad, dummy;
00063         _mapSRS->getEllipsoid()->convertXYZToLatLongHeight( point.x(), point.y(), point.z(), lat_rad, lon_rad, dummy );
00064 
00065         double lat_deg = osg::RadiansToDegrees( lat_rad );
00066         double lon_deg = osg::RadiansToDegrees( lon_rad );
00067 
00068         if (_feature.valid())            
00069         {
00070             _feature->getGeometry()->push_back( osg::Vec3d(lon_deg, lat_deg, 0) );
00071             _source->dirty();
00072         }
00073         return true;
00074     }
00075     return false;
00076 }
00077 
00078 bool
00079 AddPointHandler::handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa )
00080 {
00081     osgViewer::View* view = static_cast<osgViewer::View*>(aa.asView());
00082     if ( ea.getEventType() == osgGA::GUIEventAdapter::PUSH )
00083     {
00084         if (ea.getButton() == _mouseButton)
00085         {
00086             _mouseDown = true;
00087             _firstMove = true;
00088             return addPoint( ea.getX(), ea.getY(), view );
00089         }
00090     }
00091     else if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE)
00092     {
00093         if (ea.getButton() == _mouseButton)
00094         {
00095             _mouseDown = false;
00096         }
00097     }
00098     else if (ea.getEventType() == osgGA::GUIEventAdapter::MOVE || ea.getEventType() == osgGA::GUIEventAdapter::DRAG)
00099     {
00100         if (_mouseDown)
00101         {
00102             if (!_firstMove)
00103             {
00104                 return addPoint( ea.getX(), ea.getY(), view );
00105             }
00106             _firstMove = false;
00107         }
00108         return true;
00109     }
00110 
00111     return false;
00112 }
00113 
00114 /****************************************************************/
00115 
00116 class MoveFeatureDraggerCallback : public osgManipulator::DraggerCallback
00117 {
00118 public:
00119     MoveFeatureDraggerCallback(Feature* feature, FeatureSource* source, const Map* map, int point):
00120       _feature(feature),
00121       _source(source),
00122       _map(map),
00123       _point(point)
00124       {}
00125 
00126       osg::Vec2d getLocation(const osg::Matrixd& matrix)
00127       {
00128           osg::Vec3d trans = matrix.getTrans();
00129           double lat, lon, height;
00130           _map->getProfile()->getSRS()->getEllipsoid()->convertXYZToLatLongHeight(trans.x(), trans.y(), trans.z(), lat, lon, height);
00131           return osg::Vec2d(osg::RadiansToDegrees(lon), osg::RadiansToDegrees(lat));
00132       }
00133 
00134 
00135       virtual bool receive(const osgManipulator::MotionCommand& command)
00136       {
00137           switch (command.getStage())
00138           {
00139           case osgManipulator::MotionCommand::START:
00140               {
00141                   // Save the current matrix                  
00142                   osg::Vec3d startLocation = (*_feature->getGeometry())[_point];
00143                   double x, y, z;
00144                   _map->getProfile()->getSRS()->getEllipsoid()->convertLatLongHeightToXYZ(osg::DegreesToRadians(startLocation.y()), osg::DegreesToRadians(startLocation.x()), 0, x, y, z);
00145                   _startMotionMatrix = osg::Matrixd::translate(x, y, z);
00146 
00147                   // Get the LocalToWorld and WorldToLocal matrix for this node.
00148                   osg::NodePath nodePathToRoot;
00149                   _localToWorld = osg::Matrixd::identity();
00150                   _worldToLocal = osg::Matrixd::identity();
00151 
00152                   return true;
00153               }
00154           case osgManipulator::MotionCommand::MOVE:
00155               {
00156                   // Transform the command's motion matrix into local motion matrix.
00157                   osg::Matrix localMotionMatrix = _localToWorld * command.getWorldToLocal()
00158                       * command.getMotionMatrix()
00159                       * command.getLocalToWorld() * _worldToLocal;
00160 
00161                   osg::Matrixd newMatrix = localMotionMatrix * _startMotionMatrix;
00162                   osg::Vec2d location = getLocation( newMatrix );
00163                   (*_feature->getGeometry())[_point] = osg::Vec3d(location.x(), location.y(), 0);
00164                   _source->dirty();
00165 
00166                   return true;
00167               }
00168           case osgManipulator::MotionCommand::FINISH:
00169               {
00170                   return true;
00171               }
00172           case osgManipulator::MotionCommand::NONE:
00173           default:
00174               return false;
00175           }
00176       }
00177 
00178 
00179       osg::ref_ptr<const Map>            _map;      
00180       osg::ref_ptr< Feature > _feature;
00181       osg::ref_ptr< FeatureSource > _source;
00182 
00183       osg::Matrix _startMotionMatrix;
00184       int _point;
00185 
00186       osg::Matrix _localToWorld;
00187       osg::Matrix _worldToLocal;
00188 };
00189 
00190 /****************************************************************/
00191 FeatureEditor::FeatureEditor( Feature* feature, FeatureSource* source, MapNode* mapNode ):
00192 _feature( feature ),
00193 _source( source ),
00194 _mapNode( mapNode ),
00195 _color(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f)),
00196 _pickColor(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f)),
00197 _size( 5.0f )
00198 {
00199     init();
00200 }
00201 
00202 
00203 const osg::Vec4f&
00204 FeatureEditor::getPickColor() const
00205 {
00206     return _pickColor;
00207 }
00208 
00209 void
00210 FeatureEditor::setPickColor( const osg::Vec4f& pickColor )
00211 {
00212     if (_pickColor != pickColor)
00213     {
00214         _pickColor = pickColor;
00215         init();
00216     }
00217 }
00218 
00219 const osg::Vec4f&
00220 FeatureEditor::getColor() const
00221 {
00222     return _color;
00223 }
00224 
00225 void
00226 FeatureEditor::setColor( const osg::Vec4f& color )
00227 {
00228     if (_color != color)
00229     {
00230         _color = color;
00231         init();
00232     }
00233 }        
00234 
00235 float
00236 FeatureEditor::getSize() const
00237 {
00238     return _size;
00239 }
00240 
00241 void
00242 FeatureEditor::setSize( float size )
00243 {
00244     if (_size != size)
00245     {
00246         _size = size;
00247         init();
00248     }
00249 }
00250 
00251 void
00252 FeatureEditor::init()
00253 {
00254     removeChildren( 0, this->getNumChildren() );
00255     //Create a dragger for each point
00256     for (unsigned int i = 0; i < _feature->getGeometry()->size(); i++)
00257     {
00258         osg::Matrixd matrix;
00259         double lat = (*_feature->getGeometry())[i].y();
00260         double lon = (*_feature->getGeometry())[i].x();
00261         _mapNode->getMap()->getProfile()->getSRS()->getEllipsoid()->computeLocalToWorldTransformFromLatLongHeight(osg::DegreesToRadians(lat), osg::DegreesToRadians(lon), 0, matrix);    
00262 
00263         IntersectingDragger* dragger = new IntersectingDragger;
00264         dragger->setColor( _color );
00265         dragger->setPickColor( _pickColor );
00266         dragger->setSize( _size );
00267         dragger->setNode( _mapNode->getTerrainEngine() );
00268         dragger->setupDefaultGeometry();
00269         dragger->setMatrix(matrix);
00270         dragger->setHandleEvents( true );        
00271         dragger->addDraggerCallback(new MoveFeatureDraggerCallback(_feature.get(), _source.get(), _mapNode->getMap(), i) );
00272 
00273         addChild(dragger);        
00274     }
00275 }        
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines