osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_featureeditor/osgearth_featureeditor.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 <osgGA/StateSetManipulator>
00022 #include <osgViewer/Viewer>
00023 #include <osgViewer/ViewerEventHandlers>
00024 #include <osgGA/GUIEventHandler>
00025 #include <osgEarth/Map>
00026 #include <osgEarth/MapNode>
00027 #include <osgEarthUtil/EarthManipulator>
00028 #include <osgEarthUtil/AutoClipPlaneHandler>
00029 #include <osgEarth/Utils>
00030 
00031 #include <osgEarthSymbology/Style>
00032 #include <osgEarthFeatures/FeatureModelGraph>
00033 #include <osgEarthFeatures/FeatureListSource>
00034 #include <osgEarthFeatures/GeometryCompiler>
00035 
00036 #include <osgEarthDrivers/gdal/GDALOptions>
00037 #include <osgEarthDrivers/feature_ogr/OGRFeatureOptions>
00038 #include <osgEarthDrivers/agglite/AGGLiteOptions>
00039 #include <osgEarthDrivers/model_feature_geom/FeatureGeomModelOptions>
00040 #include <osgEarthDrivers/model_feature_stencil/FeatureStencilModelOptions>
00041 
00042 #include <osgEarthUtil/Controls>
00043 
00044 #include <osgEarthUtil/FeatureEditing>
00045 
00046 using namespace osgEarth;
00047 using namespace osgEarth::Features;
00048 using namespace osgEarth::Drivers;
00049 using namespace osgEarth::Symbology;
00050 using namespace osgEarth::Util;
00051 using namespace osgEarth::Util::Controls;
00052 
00053 osg::Vec4
00054 randomColor()
00055 {
00056     float r = (float)rand() / (float)RAND_MAX;
00057     float g = (float)rand() / (float)RAND_MAX;
00058     float b = (float)rand() / (float)RAND_MAX;
00059     return osg::Vec4(r,g,b,1.0f);
00060 }
00061 
00062 
00063 static int s_fid = 0;
00064 
00065 static osg::ref_ptr< AddPointHandler > s_addPointHandler;
00066 static osg::ref_ptr< osg::Node > s_editor;
00067 static osg::ref_ptr< Feature > s_activeFeature;
00068 static osgViewer::Viewer* s_viewer;
00069 static osg::ref_ptr< osg::Group > s_root;
00070 static osg::ref_ptr< FeatureListSource > s_source;
00071 static osg::ref_ptr< MapNode > s_mapNode;
00072 
00073 Grid* createToolBar()
00074 {    
00075     Grid* toolbar = new Grid();
00076     toolbar->setBackColor(0,0,0,0.5);
00077     toolbar->setMargin( 10 );
00078     toolbar->setPadding( 10 );
00079     toolbar->setChildSpacing( 10 );
00080     toolbar->setChildVertAlign( Control::ALIGN_CENTER );
00081     toolbar->setAbsorbEvents( true );
00082     toolbar->setVertAlign( Control::ALIGN_TOP );    
00083     return toolbar;    
00084 }
00085 
00086 struct AddVertsModeHandler : public ControlEventHandler
00087 {
00088     AddVertsModeHandler( FeatureModelGraph* featureGraph)
00089         : _featureGraph( featureGraph )
00090     {
00091     }
00092 
00093     void onClick( Control* control, int mouseButtonMask ) {
00094 
00095         //remove the editor if it's valid
00096         if (s_editor.valid())
00097         {
00098             s_root->removeChild( s_editor.get() );
00099             s_editor = NULL;
00100 
00101             Style* style = _featureGraph->getStyles()->getDefaultStyle();
00102             if ( style )
00103             {            
00104                 style->get<LineSymbol>()->stroke()->stipple().unset();
00105                 _featureGraph->dirty();
00106             }
00107         }
00108 
00109         //Add the new add point handler
00110         if (!s_addPointHandler.valid() && s_activeFeature.valid())
00111         {
00112             s_addPointHandler = new AddPointHandler(s_activeFeature.get(), s_source.get(), s_mapNode->getMap()->getProfile()->getSRS());
00113             s_addPointHandler->setIntersectionMask( 0x1 );
00114             s_viewer->addEventHandler( s_addPointHandler.get() );
00115         }        
00116     }
00117 
00118     osg::ref_ptr< FeatureModelGraph > _featureGraph;
00119 };
00120 
00121 struct EditModeHandler : public ControlEventHandler
00122 {
00123     EditModeHandler( FeatureModelGraph* featureGraph)
00124         : _featureGraph( featureGraph )
00125     { 
00126     }
00127 
00128     void onClick( Control* control, int mouseButtonMask ) {
00129         
00130         //Remove the add point handler if it's valid
00131         if (s_addPointHandler.valid())
00132         {            
00133             osgEarth::removeEventHandler( s_viewer, s_addPointHandler.get() );
00134             s_addPointHandler = NULL;
00135         }        
00136 
00137         if (!s_editor.valid() && s_activeFeature.valid())
00138         {
00139             Style* style = _featureGraph->getStyles()->getDefaultStyle();
00140             if ( style )
00141             {
00142                 style->get<LineSymbol>()->stroke()->stipple() = 0x00FF;
00143                 _featureGraph->dirty();
00144             }
00145             s_editor = new FeatureEditor(s_activeFeature.get(), s_source.get(), s_mapNode.get());
00146             s_root->addChild( s_editor.get() );
00147         }
00148     }
00149 
00150     osg::ref_ptr< FeatureModelGraph > _featureGraph;
00151 };
00152 
00153 struct ChangeStyleHandler : public ControlEventHandler
00154 {
00155     ChangeStyleHandler( FeatureModelGraph* features, StyleSheet* styleSheet) 
00156         : _features( features), _styleSheet(styleSheet)
00157     {
00158         //nop
00159     }
00160 
00161     void onClick( Control* control, int mouseButtonMask ) {
00162         _features->setStyles( _styleSheet.get() );
00163     }
00164 
00165     osg::ref_ptr< FeatureModelGraph > _features;
00166     osg::ref_ptr< StyleSheet >        _styleSheet;
00167 };
00168 
00169 StyleSheet* buildStyleSheet( const osg::Vec4 &color, float width )
00170 {
00171     // Define a style for the feature data. Since we are going to render the
00172     // vectors as lines, configure the line symbolizer:
00173     Style style;
00174 
00175     LineSymbol* ls = style.getOrCreateSymbol<LineSymbol>();
00176     ls->stroke()->color() = color;
00177     ls->stroke()->width() = width;
00178 
00179     //AltitudeSymbol* as = style.getOrCreate<AltitudeSymbol>();
00180     //as->clamping() = AltitudeSymbol::CLAMP_TO_TERRAIN;
00181 
00182     StyleSheet* styleSheet = new StyleSheet();
00183     styleSheet->addStyle( style );
00184     return styleSheet;
00185 }
00186 
00187 
00188 //
00189 // NOTE: run this sample from the repo/tests directory.
00190 //
00191 int main(int argc, char** argv)
00192 {
00193     osg::ArgumentParser arguments(&argc,argv);
00194 
00195     osgViewer::Viewer viewer(arguments);
00196     s_viewer = &viewer;
00197 
00198     // Start by creating the map:
00199     s_mapNode = MapNode::load(arguments);
00200     if ( !s_mapNode )
00201     {
00202         Map* map = new Map();
00203 
00204         // Start with a basemap imagery layer; we'll be using the GDAL driver
00205         // to load a local GeoTIFF file:
00206         GDALOptions basemapOpt;
00207         basemapOpt.url() = "../data/world.tif";
00208         map->addImageLayer( new ImageLayer( ImageLayerOptions("basemap", basemapOpt) ) );
00209 
00210         // That's it, the map is ready; now create a MapNode to render the Map:
00211         MapNodeOptions mapNodeOptions;
00212         mapNodeOptions.enableLighting() = false;
00213 
00214         s_mapNode = new MapNode( map, mapNodeOptions );
00215     }
00216     s_mapNode->setNodeMask( 0x01 );
00217 
00218         
00219     // Define a style for the feature data. Since we are going to render the
00220     // vectors as lines, configure the line symbolizer:
00221     StyleSheet* styleSheet = buildStyleSheet( Color::Yellow, 2.0f );
00222 
00223     s_source = new FeatureListSource();
00224 
00225     LineString* line = new LineString();
00226     line->push_back( osg::Vec3d(-60, 20, 0) );
00227     line->push_back( osg::Vec3d(-120, 20, 0) );
00228     line->push_back( osg::Vec3d(-120, 60, 0) );
00229     line->push_back( osg::Vec3d(-60, 60, 0) );
00230     Feature *feature = new Feature(s_fid++);
00231     feature->setGeometry( line );
00232     s_source->insertFeature( feature );
00233     s_activeFeature = feature;
00234   
00235     s_root = new osg::Group;
00236     s_root->addChild( s_mapNode.get() );
00237 
00238     Session* session = new Session(s_mapNode->getMap(), styleSheet);
00239 
00240     FeatureModelGraph* graph = new FeatureModelGraph( 
00241         s_source.get(), 
00242         FeatureModelSourceOptions(), 
00243         new GeomFeatureNodeFactory(),
00244         session );
00245 
00246     graph->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
00247     graph->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
00248 
00249     s_root->addChild( graph );
00250 
00251     //Setup the controls
00252     ControlCanvas* canvas = ControlCanvas::get( &viewer );
00253     s_root->addChild( canvas );
00254     Grid *toolbar = createToolBar( );
00255     canvas->addControl( toolbar );
00256     canvas->setNodeMask( 0x1 << 1 );
00257 
00258 
00259 
00260     int col = 0;
00261     LabelControl* addVerts = new LabelControl("Add Verts");
00262     toolbar->setControl(col++, 0, addVerts );    
00263     addVerts->addEventHandler( new AddVertsModeHandler( graph ));
00264     
00265     LabelControl* edit = new LabelControl("Edit");
00266     toolbar->setControl(col++, 0, edit );    
00267     edit->addEventHandler(new EditModeHandler( graph ));
00268 
00269     unsigned int row = 0;
00270     Grid *styleBar = createToolBar( );
00271     styleBar->setPosition(0, 50);
00272     canvas->addControl( styleBar );
00273     
00274     //Make a list of styles
00275     styleBar->setControl(0, row++, new LabelControl("Styles") );    
00276 
00277     unsigned int numStyles = 8;
00278     for (unsigned int i = 0; i < numStyles; ++i)
00279     {
00280         float w = 50;
00281         osg::Vec4 color = randomColor();
00282 
00283         float widths[3] = {2, 4, 8};
00284 
00285         unsigned int r = row++;
00286         for (unsigned int j = 0; j < 3; j++) 
00287         {
00288             Control* l = new Control();            
00289             l->setBackColor( color );
00290             l->addEventHandler(new ChangeStyleHandler(graph, buildStyleSheet( color, widths[j] ) ));
00291             l->setSize(w,5 * widths[j]);
00292             styleBar->setControl(j, r, l);
00293         }
00294     }
00295    
00296     
00297     viewer.setSceneData( s_root.get() );
00298     viewer.setCameraManipulator( new EarthManipulator() );
00299     viewer.addEventHandler( new osgEarth::Util::AutoClipPlaneHandler );
00300 
00301     // add some stock OSG handlers:
00302     viewer.addEventHandler(new osgViewer::StatsHandler());
00303     viewer.addEventHandler(new osgViewer::WindowSizeHandler());
00304     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
00305 
00306     return viewer.run();
00307 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines