osgEarth 2.1.1
|
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 }