osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_imageoverlay/osgearth_imageoverlay.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 <osgGA/GUIEventHandler>
00023 #include <osgViewer/Viewer>
00024 #include <osgViewer/ViewerEventHandlers>
00025 #include <osgEarth/MapNode>
00026 #include <osgEarthUtil/EarthManipulator>
00027 #include <osgEarthUtil/AutoClipPlaneHandler>
00028 #include <osgEarthUtil/Controls>
00029 #include <osgEarth/Utils>
00030 
00031 #include <osg/ImageStream>
00032 #include <osgDB/FileNameUtils>
00033 #include <osg/Version>
00034 #include <osgEarth/Version>
00035 
00036 #include <osgEarthUtil/ImageOverlay>
00037 #if OSG_MIN_VERSION_REQUIRED(2,9,6)
00038 #include <osgEarthUtil/ImageOverlayEditor>
00039 #endif
00040 
00041 using namespace osgEarth;
00042 using namespace osgEarth::Util;
00043 using namespace osgEarth::Util::Controls;
00044 
00045 static Grid* s_layerBox = NULL;
00046 
00047 osg::Node*
00048 createControlPanel( osgViewer::View* view )
00049 {
00050     ControlCanvas* canvas = ControlCanvas::get( view );
00051 
00052     // the outer container:
00053     s_layerBox = new Grid();
00054     s_layerBox->setBackColor(0,0,0,0.5);
00055     s_layerBox->setMargin( 10 );
00056     s_layerBox->setPadding( 10 );
00057     s_layerBox->setChildSpacing( 10 );
00058     s_layerBox->setChildVertAlign( Control::ALIGN_CENTER );
00059     s_layerBox->setAbsorbEvents( true );
00060     s_layerBox->setVertAlign( Control::ALIGN_BOTTOM );
00061 
00062 
00063 
00064     canvas->addControl( s_layerBox );    
00065     return canvas;
00066 }
00067 
00068 int
00069 usage( const std::string& msg )
00070 {
00071     OE_NOTICE << msg << std::endl;
00072     OE_NOTICE << "USAGE: osgearth_imageoverlay file.earth" << std::endl;
00073     OE_NOTICE << "   --image <file> xmin ymin xmax ymax : An image to overlay and it's bounds" << std::endl;        
00074     OE_NOTICE << "   --vert                             : Move individual verts when editing" << std::endl;
00075 
00076         
00077     return -1;
00078 }
00079 
00080 struct OpacityHandler : public ControlEventHandler
00081 {
00082     OpacityHandler( ImageOverlay* overlay ) : _overlay(overlay) { }
00083     void onValueChanged( Control* control, float value ) {
00084         _overlay->setAlpha( value );
00085     }
00086     ImageOverlay* _overlay;
00087 };
00088 
00089 struct EnabledHandler : public ControlEventHandler
00090 {
00091     EnabledHandler( ImageOverlay* overlay ) :  _overlay(overlay) { }
00092     void onValueChanged( Control* control, bool value ) {
00093         _overlay->setNodeMask( value ? ~0 : 0 );
00094     }
00095     ImageOverlay* _overlay;
00096 };
00097 
00098 
00099 
00100 struct EditHandler : public ControlEventHandler
00101 {
00102     EditHandler( ImageOverlay* overlay, osgViewer::Viewer* viewer, osg::Node* editor) :
00103       _overlay(overlay),
00104       _viewer(viewer),
00105       _editor(editor){ }
00106 
00107     void onClick( Control* control, int mouseButtonMask ) {        
00108 #if OSG_MIN_VERSION_REQUIRED(2,9,6)
00109         if (_editor->getNodeMask() != ~0)
00110         {
00111             static_cast<LabelControl*>(control)->setText( "Finish" );
00112             _editor->setNodeMask(~0);
00113         }
00114         else
00115         {
00116             static_cast<LabelControl*>(control)->setText( "Edit" );
00117             _editor->setNodeMask(0);
00118         }
00119 
00120 #else
00121         OE_NOTICE << "Use OSG 2.9.6 or greater to use editing" << std::endl;
00122 #endif
00123     }
00124     ImageOverlay* _overlay;
00125     osgViewer::Viewer* _viewer;
00126     osg::Node* _editor;
00127 };
00128 
00129 struct ChangeImageHandler : public ControlEventHandler
00130 {
00131     ChangeImageHandler( osg::Image* image, ImageOverlay* overlay, ImageControl* preview) :
00132       _image(image),
00133       _overlay(overlay),
00134       _preview(preview){ }
00135 
00136     void onClick( Control* control, int mouseButtonMask ) {
00137         _overlay->setImage( _image.get() );
00138         _preview->setImage( _image.get() );
00139     }
00140     ImageOverlay* _overlay;
00141     osg::ref_ptr< osg::Image > _image;
00142     osg::ref_ptr< ImageControl> _preview;
00143 };
00144 
00145 struct UpdateLabelCallback : public ImageOverlay::ImageOverlayCallback
00146 {
00147     UpdateLabelCallback(LabelControl* label, ImageOverlay* overlay, ImageOverlay::ControlPoint controlPoint):
00148       _label(label),
00149       _overlay(overlay),
00150       _controlPoint(controlPoint)
00151     {
00152 
00153     }
00154 
00155     virtual void onOverlayChanged()
00156     {
00157         osg::Vec2d location = _overlay->getControlPoint( _controlPoint );
00158         std::stringstream ss;
00159         ss << location.y() << ", " << location.x();
00160         _label->setText( ss.str() );
00161     }
00162     
00163 
00164     osg::ref_ptr< LabelControl > _label;
00165     osg::ref_ptr< ImageOverlay > _overlay;
00166     ImageOverlay::ControlPoint _controlPoint;
00167 };
00168 
00169 
00170 
00171 int
00172 main(int argc, char** argv)
00173 {
00174     osg::ArgumentParser arguments(&argc,argv);
00175     osg::DisplaySettings::instance()->setMinimumNumStencilBits( 8 );
00176 
00177 
00178     std::vector< std::string > imageFiles;
00179     std::vector< Bounds > imageBounds;
00180 
00181     //Read in the image files
00182     std::string filename;
00183     Bounds bounds;
00184     while (arguments.read("--image", filename, bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax()))
00185     {
00186         imageFiles.push_back( filename );
00187         imageBounds.push_back( bounds );
00188     }
00189 
00190     if (imageFiles.empty())
00191     {
00192       imageFiles.push_back("../data/osgearth.gif");
00193       imageBounds.push_back( Bounds(-100, 30, -90, 40) );
00194     }
00195  
00196 
00197     bool moveVert = arguments.read("--vert");
00198 
00199     // load the .earth file from the command line.
00200     osg::Node* earthNode = osgDB::readNodeFiles( arguments );
00201     if (!earthNode)
00202         return usage( "Unable to load earth model." );
00203 
00204     osgViewer::Viewer viewer(arguments);
00205     
00206     EarthManipulator* manip = new EarthManipulator();
00207     viewer.setCameraManipulator( manip );
00208 
00209     osg::Group* root = new osg::Group();
00210     root->addChild( earthNode );
00211 
00212     //Create the control panel
00213     root->addChild( createControlPanel(&viewer) );
00214 
00215     viewer.setSceneData( root );
00216     
00217     osgEarth::MapNode* mapNode = osgEarth::MapNode::findMapNode( earthNode );
00218     if ( mapNode )
00219     {
00220 
00221         for (unsigned int i = 0; i < imageFiles.size(); i++)
00222         {
00223             std::string imageFile = imageFiles[i];
00224             //Read the image file and play it if it's a movie
00225             osg::Image* image = osgDB::readImageFile(imageFile);
00226             if (image)
00227             {
00228                 osg::ImageStream* is = dynamic_cast<osg::ImageStream*>(image);
00229                 if (is)
00230                 {
00231                     is->play();
00232                 }
00233             }
00234 
00235             //Create a new ImageOverlay and set it's bounds
00236             //ImageOverlay* overlay = new ImageOverlay(mapNode->getMap()->getProfile()->getSRS()->getEllipsoid(), image);        
00237             ImageOverlay* overlay = new ImageOverlay(mapNode);
00238             overlay->setImage( image );
00239             overlay->setBounds(imageBounds[i]);
00240 
00241             root->addChild( overlay );
00242 
00243 
00244             //Create a new ImageOverlayEditor and set it's node mask to 0 to hide it initially
00245 #if OSG_MIN_VERSION_REQUIRED(2,9,6)
00246             osg::Node* editor = new ImageOverlayEditor( overlay, mapNode->getMap()->getProfile()->getSRS()->getEllipsoid(), mapNode );
00247 #else
00248             //Just make an empty group for pre-2.9.6
00249             osg::Node* editor = new osg::Group;
00250 #endif
00251             editor->setNodeMask( 0 );
00252             root->addChild( editor );      
00253             
00254             // Add an image preview
00255             ImageControl* imageCon = new ImageControl( image );
00256             imageCon->setSize( 64, 64 );
00257             imageCon->setVertAlign( Control::ALIGN_CENTER );
00258             s_layerBox->setControl( 0, i, imageCon );            
00259 
00260 
00261             //Add some controls        
00262             CheckBoxControl* enabled = new CheckBoxControl( true );
00263             enabled->addEventHandler( new EnabledHandler(overlay) );
00264             enabled->setVertAlign( Control::ALIGN_CENTER );
00265             s_layerBox->setControl( 1, i, enabled );
00266 
00267             //The overlay name
00268             LabelControl* name = new LabelControl( osgDB::getSimpleFileName( imageFile) );      
00269             name->setVertAlign( Control::ALIGN_CENTER );
00270             s_layerBox->setControl( 2, i, name );
00271 
00272             // an opacity slider
00273             HSliderControl* opacity = new HSliderControl( 0.0f, 1.0f, overlay->getAlpha() );
00274             opacity->setWidth( 125 );
00275             opacity->setHeight( 12 );
00276             opacity->setVertAlign( Control::ALIGN_CENTER );
00277             opacity->addEventHandler( new OpacityHandler(overlay) );
00278             s_layerBox->setControl( 3, i, opacity );
00279 
00280             // Add a text label:
00281             LabelControl* edit = new LabelControl( "Edit" );        
00282             edit->setVertAlign( Control::ALIGN_CENTER );
00283             edit->addEventHandler(new EditHandler(overlay, &viewer, editor));
00284             s_layerBox->setControl(4, i, edit );
00285         }        
00286     }
00287 
00288     // osgEarth benefits from pre-compilation of GL objects in the pager. In newer versions of
00289     // OSG, this activates OSG's IncrementalCompileOpeartion in order to avoid frame breaks.
00290     viewer.getDatabasePager()->setDoPreCompile( true );
00291 
00292     // add some stock OSG handlers:
00293     viewer.addEventHandler(new osgViewer::StatsHandler());
00294     viewer.addEventHandler(new osgViewer::WindowSizeHandler());    
00295     viewer.addEventHandler(new osgViewer::LODScaleHandler());
00296     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
00297     viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
00298 
00299     return viewer.run();
00300 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines