osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthFeatures/FeatureSource.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/FeatureSource>
00020 #include <osgEarthFeatures/ResampleFilter>
00021 #include <osgEarthFeatures/BufferFilter>
00022 #include <osgEarthFeatures/ConvertTypeFilter>
00023 #include <osg/Notify>
00024 #include <osgDB/ReadFile>
00025 #include <OpenThreads/ScopedLock>
00026 
00027 #define LC "[FeatureSource] "
00028 
00029 using namespace osgEarth::Features;
00030 using namespace osgEarth::Symbology;
00031 using namespace OpenThreads;
00032 
00033 FeatureSourceOptions::FeatureSourceOptions( const ConfigOptions& options ) :
00034 DriverConfigOptions( options )
00035 {
00036     fromConfig( _conf );
00037 }
00038 
00039 void
00040 FeatureSourceOptions::fromConfig( const Config& conf )
00041 {
00042     unsigned numResamples = 0;
00043 
00044     conf.getIfSet   ( "open_write", _openWrite );
00045     conf.getIfSet   ( "name",       _name );
00046     conf.getObjIfSet( "profile",    _profile );
00047 
00048     const ConfigSet& children = conf.children();
00049     for( ConfigSet::const_iterator i = children.begin(); i != children.end(); ++i )
00050     {
00051         const Config& child = *i;
00052 
00053         if ( child.key() == "buffer" && !child.empty() )
00054         {
00055             BufferFilter* buffer = new BufferFilter();
00056             child.getIfSet( "distance", buffer->distance() );
00057             _filters.push_back( buffer );
00058 
00059             if ( numResamples > 0 )
00060             {
00061                 OE_WARN << LC 
00062                     << "Warning: Resampling should be applied before buffering, as buffering"
00063                     << " will remove colinear segments created by the buffer operation."
00064                     << std::endl;
00065             }
00066 
00067             OE_DEBUG << LC << "Added buffer filter" << std::endl;
00068         }
00069 
00070         else if ( child.key() == "resample" && !child.empty() )
00071         {
00072             ResampleFilter* resample = new ResampleFilter();
00073             child.getIfSet( "min_length", resample->minLength() );
00074             child.getIfSet( "max_length", resample->maxLength() );
00075             _filters.push_back( resample );
00076             numResamples++;
00077 
00078             OE_DEBUG << LC << "Added resample filter" << std::endl;
00079         }
00080 
00081         else if ( child.key() == "convert" && !child.empty() )
00082         {
00083             ConvertTypeFilter* convert = new ConvertTypeFilter();
00084             optional<Geometry::Type> type = Geometry::TYPE_POINTSET;
00085             child.getIfSet( "type", "point",   type, Geometry::TYPE_POINTSET );
00086             child.getIfSet( "type", "line",    type, Geometry::TYPE_LINESTRING );
00087             child.getIfSet( "type", "polygon", type, Geometry::TYPE_POLYGON );
00088             convert->toType() = *type;
00089             _filters.push_back( convert );
00090 
00091             OE_DEBUG << LC << "Added convert filter" << std::endl;
00092         }
00093     }
00094 }
00095 
00096 Config
00097 FeatureSourceOptions::getConfig() const
00098 {
00099     Config conf = DriverConfigOptions::getConfig();
00100 
00101     conf.updateIfSet   ( "open_write", _openWrite );
00102     conf.updateIfSet   ( "name",       _name );
00103     conf.updateObjIfSet( "profile",    _profile );
00104 
00105     //TODO: make each of these filters Configurable.
00106     for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i )
00107     {
00108         BufferFilter* buffer = dynamic_cast<BufferFilter*>( i->get() );
00109         if ( buffer ) {
00110             Config bufferConf( "buffer" );
00111             bufferConf.addIfSet( "distance", buffer->distance() );
00112             conf.update( bufferConf );
00113         }
00114 
00115         ResampleFilter* resample = dynamic_cast<ResampleFilter*>( i->get() );
00116         if ( resample ) { 
00117             Config resampleConf( "resample" );
00118             resampleConf.addIfSet( "min_length", resample->minLength() );
00119             resampleConf.addIfSet( "max_length", resample->maxLength() );
00120             conf.update( resampleConf );
00121         }
00122 
00123         ConvertTypeFilter* convert = dynamic_cast<ConvertTypeFilter*>( i->get() );
00124         if ( convert ) {
00125             Config convertConf( "convert" );
00126             optional<Geometry::Type> type( convert->toType(), convert->toType() ); // weird optional ctor :)
00127             convertConf.addIfSet( "type", "point",   type, Geometry::TYPE_POINTSET );
00128             convertConf.addIfSet( "type", "line",    type, Geometry::TYPE_LINESTRING );
00129             convertConf.addIfSet( "type", "polygon", type, Geometry::TYPE_POLYGON );
00130             conf.update( convertConf );
00131         }
00132     }
00133 
00134     return conf;
00135 }
00136 
00137 //------------------------------------------------------------------------
00138 
00139 FeatureSource::FeatureSource( const ConfigOptions& options ) :
00140 _options( options )
00141 {    
00142     //nop
00143 }
00144 
00145 const FeatureProfile*
00146 FeatureSource::getFeatureProfile() const
00147 {
00148     if ( !_featureProfile.valid() )
00149     {
00150         FeatureSource* nonConstThis = const_cast<FeatureSource*>(this);
00151 
00152         ScopedLock<Mutex> doubleCheckLock( nonConstThis->_createMutex );
00153         {
00154             if ( !_featureProfile.valid() )
00155             {
00156                 // caching pattern                
00157                 nonConstThis->_featureProfile = nonConstThis->createFeatureProfile();
00158             }
00159         }
00160     }
00161     return _featureProfile.get();
00162 }
00163 
00164 const FeatureFilterList&
00165 FeatureSource::getFilters() const
00166 {
00167     return _options.filters();
00168 }
00169 
00170 const FeatureSchema&
00171 FeatureSource::getSchema() const
00172 {
00173     static FeatureSchema s_emptySchema;
00174     return s_emptySchema;
00175 }
00176 
00177 //------------------------------------------------------------------------
00178 
00179 #undef  LC
00180 #define LC "[FeatureSourceFactory] "
00181 #define FEATURE_SOURCE_OPTIONS_TAG "__osgEarth::FeatureSourceOptions"
00182 
00183 FeatureSource*
00184 FeatureSourceFactory::create( const FeatureSourceOptions& options )
00185 {
00186     FeatureSource* featureSource = 0L;
00187 
00188     if ( !options.getDriver().empty() )
00189     {
00190         std::string driverExt = std::string(".osgearth_feature_") + options.getDriver();
00191 
00192         osg::ref_ptr<osgDB::ReaderWriter::Options> rwopts = new osgDB::ReaderWriter::Options();
00193         rwopts->setPluginData( FEATURE_SOURCE_OPTIONS_TAG, (void*)&options );
00194 
00195         featureSource = dynamic_cast<FeatureSource*>( osgDB::readObjectFile( driverExt, rwopts.get() ) );
00196         if ( featureSource )
00197         {
00198             if ( options.name().isSet() )
00199                 featureSource->setName( *options.name() );
00200             else
00201                 featureSource->setName( options.getDriver() );
00202         }
00203         else
00204         {
00205             OE_WARN << LC << "FAILED to load feature driver \"" << options.getDriver() << "\"" << std::endl;
00206         }
00207     }
00208     else
00209     {
00210         OE_WARN << LC << "ILLEGAL null feature driver name" << std::endl;
00211     }
00212 
00213     return featureSource;
00214 }
00215 
00216 //------------------------------------------------------------------------
00217 
00218 const FeatureSourceOptions&
00219 FeatureSourceDriver::getFeatureSourceOptions( const osgDB::ReaderWriter::Options* rwopt ) const
00220 {
00221     return *static_cast<const FeatureSourceOptions*>( rwopt->getPluginData( FEATURE_SOURCE_OPTIONS_TAG ) );
00222 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines