osgEarth 2.1.1

/home/cube/sources/osgearth/src/applications/osgearth_labels/osgearth_labels.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/GUIEventHandler>
00022 #include <osgViewer/Viewer>
00023 #include <osgGA/StateSetManipulator>
00024 #include <osgViewer/ViewerEventHandlers>
00025 #include <osgEarthUtil/EarthManipulator>
00026 #include <osgEarthUtil/Controls>
00027 #include <osgEarthDrivers/feature_ogr/OGRFeatureOptions>
00028 #include <osgEarthFeatures/FeatureSource>
00029 #include <osgEarth/Utils>
00030 
00031 #define LC "[osgearth_labels] "
00032 
00033 using namespace osgEarth::Util::Controls;
00034 using namespace osgEarth::Drivers;
00035 using namespace osgEarth::Features;
00036 using namespace osgEarth::Symbology;
00037 
00038 osg::Group* createLabels( Map* );
00039 
00040 std::string g_featureFile, g_labelAttr, g_priorityAttr;
00041 bool g_removeDupes = true;
00042 
00047 int main(int argc, char** argv)
00048 {
00049     osg::ArgumentParser arguments(&argc,argv);
00050 
00051     if ( arguments.read( "--help" ) || argc < 2 )
00052     {
00053         OE_NOTICE << LC << std::endl << std::endl
00054 
00055             << "osgearth_labels <earthfile>" << std::endl
00056             << "    --features <filename>            : name of shapefile containing feature labels" << std::endl
00057             << "    --label-attr <attribute>         : attribute containing label text" << std::endl
00058             << "    --priority-attr <attribute>      : attribute containing priority value" << std::endl
00059             << "    --show-duplicates                : draws duplicate labels (usually won't)" << std::endl;
00060         
00061         return 0;
00062     }
00063 
00064     if ( !arguments.read( "--features", g_featureFile ) )
00065         g_featureFile = "../data/world.shp";
00066     
00067     if ( !arguments.read( "--label-attr", g_labelAttr ) )
00068         g_labelAttr = "cntry_name";
00069 
00070     if ( !arguments.read( "--priority-attr", g_priorityAttr ) )
00071         g_priorityAttr = "cntry_pop";
00072 
00073     if ( arguments.read( "--show-duplicates" ) )
00074         g_removeDupes = false;
00075 
00076     osgViewer::Viewer viewer(arguments);
00077 
00078     osg::Group* root = new osg::Group();
00079     osg::Node* node = osgDB::readNodeFiles( arguments );
00080     if ( node )
00081         root->addChild( node );
00082 
00083     MapNode* mapNode = MapNode::findMapNode(node);
00084     if ( mapNode )
00085     {
00086         viewer.setSceneData( root );
00087         viewer.setCameraManipulator( new osgEarth::Util::EarthManipulator );
00088 
00089         //root->addChild( new ControlCanvas( &viewer ) );
00090 
00091         // load up some labels.
00092         root->addChild( createLabels(mapNode->getMap()) );
00093     }
00094 
00095     // add some stock OSG handlers:
00096     viewer.addEventHandler(new osgViewer::StatsHandler());
00097     viewer.addEventHandler(new osgViewer::WindowSizeHandler());
00098     viewer.addEventHandler(new osgViewer::ThreadingHandler());
00099     viewer.addEventHandler(new osgViewer::LODScaleHandler());
00100     viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
00101     viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
00102 
00103     return viewer.run();
00104 }
00105 
00106 osg::Group*
00107 createLabels( Map* map )
00108 {
00109     osg::ref_ptr<osg::Group> labels = new osg::Group();
00110 
00111     // first, open up the source shapefile
00112     OGRFeatureOptions fo;
00113     fo.url() = g_featureFile;
00114 
00115     osg::ref_ptr<FeatureSource> features = FeatureSourceFactory::create( fo );
00116     if ( !features.valid() )
00117     {
00118         OE_WARN << LC << "Unable to load features!" << std::endl;
00119         return 0L;
00120     }
00121 
00122     features->initialize( "" );
00123     const FeatureProfile* featureProfile = features->getFeatureProfile();
00124     if ( !featureProfile || !featureProfile->getSRS() )
00125     {
00126         OE_WARN << LC << "Feature data has no spatial reference!" << std::endl;
00127         return 0L;
00128     }
00129 
00130     osg::ref_ptr<FeatureCursor> cursor = features->createFeatureCursor();
00131     if ( !cursor.valid() )
00132     {
00133         OE_WARN << LC << "Failed to query the feature source!" << std::endl;
00134         return 0L;
00135     }
00136 
00137     //SceneControlBin* priorityBin = canvas->getSceneControls();
00138 
00139     unsigned count = 0;
00140 
00141     std::set<std::string> antiDupeSet;
00142 
00143     while( cursor->hasMore() )
00144     {
00145         Feature* feature = cursor->nextFeature();
00146         Geometry* geom = feature->getGeometry();
00147 
00148         if ( !geom )
00149             continue;
00150 
00151         // we will display the country name:
00152         std::string text = feature->getString( g_labelAttr );
00153         if ( text.empty() )
00154             continue;
00155 
00156         // and use the population to prioritize labels:
00157         float population = feature->getDouble(g_priorityAttr, 0.0);
00158 
00159         // remove duplicate labels:
00160         if ( g_removeDupes )
00161         {
00162             if ( antiDupeSet.find(text) != antiDupeSet.end() )
00163                 continue;
00164             antiDupeSet.insert(text);
00165         }
00166 
00167         // calculate the world location of the label:
00168         osg::Vec3d centerPoint = geom->getBounds().center();
00169 
00170         osg::Vec3d mapPoint;
00171         if ( !map->toMapPoint( centerPoint, featureProfile->getSRS(), mapPoint ) )
00172             continue;
00173 
00174         osg::Vec3d worldPoint;
00175         if ( !map->mapPointToWorldPoint( mapPoint, worldPoint ) )
00176             continue;
00177 
00178         // create the label and place it:
00179         osg::MatrixTransform* xform = new osg::MatrixTransform( osg::Matrix::translate(worldPoint) );
00180         xform->setCullCallback( new CullNodeByNormal(worldPoint) );
00181         xform->addChild( new ControlNode(new LabelControl(text)) );
00182         labels->addChild( xform );
00183 
00184         ++count;
00185 
00186         //OE_NOTICE << LC << "Added: " << text << std::endl;
00187     }
00188 
00189     OE_NOTICE << LC << "Found " << count << " features. " << std::endl;
00190 
00191     return labels.release();
00192 }
00193 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines