osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthFeatures/VirtualFeatureSource.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/VirtualFeatureSource>
00020 
00021 #define LC "[VirtualFeatureSource] "
00022 
00023 using namespace osgEarth;
00024 using namespace osgEarth::Util;
00025 using namespace osgEarth::Features;
00026 
00027 //------------------------------------------------------------------------
00028 
00029 namespace
00030 {
00034     struct VirtualFeatureCursor : public FeatureCursor
00035     {
00036         VirtualFeatureCursor( const FeatureSourceMappingVector& sources, const Query& query ) :
00037           _sources(sources), _query(query)
00038         {
00039             _si = _sources.begin();
00040             advance();
00041         }
00042 
00043         bool hasMore() const
00044         {
00045             return _nextFeature.valid();
00046         }
00047 
00048         Feature* nextFeature()
00049         {
00050             _lastFeatureReturned = _nextFeature.get();
00051             _nextFeature = 0L;
00052             if ( _lastFeatureReturned.valid() )
00053                 advance();
00054             return _lastFeatureReturned.get();
00055         }
00056 
00057     private:
00058         // pulls the next feature (in advance) in preparation for the next
00059         // call to nextFeature.
00060         void advance()
00061         {
00062             _nextFeature = 0L;
00063 
00064             while ( !_nextFeature.valid() )
00065             {
00066                 // check to see if we are completely done:
00067                 if ( _si == _sources.end() )
00068                     return;
00069 
00070                 // if we're at the beginning, create the first cursor:
00071                 if ( _si == _sources.begin() && !_si_cursor.valid() )
00072                 {
00073                     _si_cursor = _si->_source->createFeatureCursor( _query );
00074                 }
00075 
00076                 while ( !_si_cursor.valid() || !_si_cursor->hasMore() )
00077                 {
00078                     // if the current cursor is done, advance to the next source.
00079                     // if there is no next source, we are done.
00080                     if ( ++_si == _sources.end() )
00081                         return;
00082 
00083                     // make a cursor for the next source
00084                     _si_cursor = _si->_source->createFeatureCursor( _query );
00085                 }
00086 
00087                 // here, we have a valid cursor with pending data:
00088                 Feature* f = _si_cursor->nextFeature();
00089 
00090                 // test against the predicate. (a NULL predicate always accepts the feature)
00091                 if ( !_si->_predicate.valid() || _si->_predicate->acceptFeature( f ) )
00092                     _nextFeature = f;
00093             }
00094         }
00095 
00096     private:
00097         FeatureSourceMappingVector           _sources;
00098         Query                                _query;
00099         FeatureSourceMappingVector::iterator _si;        // points to current source
00100         osg::ref_ptr<FeatureCursor>          _si_cursor; // cursor into current source
00101         osg::ref_ptr<Feature>                _nextFeature;
00102         osg::ref_ptr<Feature>                _lastFeatureReturned; // to manage references during iteration
00103     };
00104 }
00105 
00106 //------------------------------------------------------------------------
00107 
00108 void
00109 VirtualFeatureSource::add( FeatureSource* source, FeaturePredicate* predicate )
00110 {
00111     _sources.push_back( FeatureSourceMapping(source, predicate) );
00112     dirty();
00113 }
00114 
00115 FeatureCursor* 
00116 VirtualFeatureSource::createFeatureCursor( const Query& query )
00117 {
00118     return new VirtualFeatureCursor( _sources, query );
00119 }
00120 
00121 void 
00122 VirtualFeatureSource::initialize( const std::string& referenceURI )
00123 {
00124     for( FeatureSourceMappingVector::iterator i = _sources.begin(); i != _sources.end(); ++i )
00125     {
00126         i->_source->initialize( referenceURI );
00127     }
00128 }
00129 
00130 const FeatureProfile* 
00131 VirtualFeatureSource::createFeatureProfile()
00132 {
00133     if ( _sources.size() > 0 )
00134         return _sources.front()._source->getFeatureProfile();
00135     else
00136         return 0L;
00137 }
00138 
00139 const FeatureSchema&
00140 VirtualFeatureSource::getSchema() const
00141 {
00142   static FeatureSchema s_emptySchema;
00143 
00144   return _sources.size() > 0 ?_sources.front()._source->getSchema() : s_emptySchema;
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines