osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthDrivers/label_overlay/OverlayLabelSource.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 #include <osgEarthFeatures/LabelSource>
00020 #include <osgEarthSymbology/Expression>
00021 #include <osgEarthUtil/Controls>
00022 #include <osgEarth/Utils>
00023 #include <osgEarth/ECEF>
00024 #include <osg/ClusterCullingCallback>
00025 #include <osg/MatrixTransform>
00026 #include <osgDB/FileNameUtils>
00027 #include <set>
00028 
00029 using namespace osgEarth;
00030 using namespace osgEarth::Features;
00031 using namespace osgEarth::Symbology;
00032 using namespace osgEarth::Util;
00033 
00034 class OverlayLabelSource : public LabelSource
00035 {
00036 public:
00037     OverlayLabelSource( const LabelSourceOptions& options ) :
00038       LabelSource( options )
00039     {
00040         //nop
00041     }
00042 
00043     osg::Node* createNode(
00044         const FeatureList&   input,
00045         const TextSymbol*    text,
00046         const FilterContext& context )
00047     {
00048         osg::Group* group = 0L;
00049         std::set<std::string> used; // to prevent dupes
00050         bool skipDupes = (text->removeDuplicateLabels() == true);
00051 
00052         StringExpression  contentExpr ( *text->content() );
00053         NumericExpression priorityExpr( *text->priority() );
00054 
00055         const MapInfo& mi = context.getSession()->getMapInfo();
00056         bool makeECEF = mi.isGeocentric();
00057 
00058         for( FeatureList::const_iterator i = input.begin(); i != input.end(); ++i )
00059         {
00060             const Feature* feature = i->get();
00061             if ( !feature )
00062                 continue;
00063 
00064             const Geometry* geom = feature->getGeometry();
00065             if ( !geom )
00066                 continue;
00067 
00068             osg::Vec3d centroid  = geom->getBounds().center();
00069             //osg::Vec3d centroidWorld = context.toWorld(centroid);
00070 
00071             if ( makeECEF )
00072             {
00073                 context.profile()->getSRS()->transformToECEF( centroid, centroid );
00074             }
00075 
00076 #if 0
00077             if ( context.isGeocentric() && geom->getComponentType() != Geometry::TYPE_POINTSET )
00078             {
00079                 // "clamp" the centroid to the ellipsoid
00080                 osg::Vec3d centroidMap;
00081                 mi.worldPointToMapPoint(centroidWorld, centroidMap);
00082                 centroidMap.z() = 0.0;
00083                 mi.mapPointToWorldPoint(centroidMap, centroidWorld);
00084                 centroid = context.toLocal(centroidWorld);
00085             }
00086 #endif
00087 
00088             const std::string& value = feature->eval( contentExpr );
00089 
00090             if ( !value.empty() && (!skipDupes || used.find(value) == used.end()) )
00091             {
00092                 if ( !group )
00093                 {
00094                     group = new osg::Group();
00095                 }
00096 
00097                 double priority = feature->eval( priorityExpr );
00098 
00099                 Controls::LabelControl* label = new Controls::LabelControl( value );
00100                 if ( text->fill().isSet() )
00101                     label->setForeColor( text->fill()->color() );
00102                 if ( text->halo().isSet() )
00103                     label->setHaloColor( text->halo()->color() );
00104                 if ( text->size().isSet() )
00105                     label->setFontSize( *text->size() );
00106                 if ( text->font().isSet() )
00107                     label->setFont( osgText::readFontFile(*text->font()) );
00108 
00109                 Controls::ControlNode* node = new Controls::ControlNode( label, priority );
00110 
00111                 osg::MatrixTransform* xform = new osg::MatrixTransform( osg::Matrixd::translate(centroid) );
00112                 xform->addChild( node );
00113 
00114                 // for a geocentric map, do a simple dot product cull.
00115                 if ( makeECEF )
00116                 {
00117                     xform->setCullCallback( new CullNodeByHorizon(centroid, mi.getProfile()->getSRS()->getEllipsoid()) );
00118                     group->addChild( xform );
00119                 }
00120                 else
00121                 {
00122                     group->addChild( xform );
00123                 }
00124 
00125                 if ( skipDupes )
00126                     used.insert( value );
00127             }
00128         }
00129 
00130         return group;
00131     }
00132 };
00133 
00134 //------------------------------------------------------------------------
00135 
00136 class OverlayLabelSourceDriver : public LabelSourceDriver
00137 {
00138 public:
00139     OverlayLabelSourceDriver()
00140     {
00141         supportsExtension( "osgearth_label_overlay", "osgEarth overlay label plugin" );
00142     }
00143 
00144     virtual const char* className()
00145     {
00146         return "osgEarth Overlay Label Plugin";
00147     }
00148 
00149     virtual ReadResult readObject(const std::string& file_name, const Options* options) const
00150     {
00151         if ( !acceptsExtension(osgDB::getLowerCaseFileExtension( file_name )))
00152             return ReadResult::FILE_NOT_HANDLED;
00153 
00154         return new OverlayLabelSource( getLabelSourceOptions(options) );
00155     }
00156 };
00157 
00158 REGISTER_OSGPLUGIN(osgearth_label_overlay, OverlayLabelSourceDriver)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines