FeatureCursor* createFeatureCursor( const Symbology::Query& query ) { FeatureCursor* result = 0L; std::string url = createURL( query ); // check the blacklist: if ( Registry::instance()->isBlacklisted(url) ) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url); // read the data: ReadResult r = uri.readString( _dbOptions.get() ); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible const std::string& mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); dataOK = getFeatures( buffer, mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //If we have any filters, process them here before the cursor is created if (!_options.filters().empty()) { // preprocess the features using the filter list: if ( features.size() > 0 ) { FilterContext cx; cx.setProfile( getFeatureProfile() ); for( FeatureFilterList::const_iterator i = _options.filters().begin(); i != _options.filters().end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( features, cx ); } } } //result = new FeatureListCursor(features); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }
// reads a chunk of features into a memory cache; do this for performance // and to avoid needing the OGR Mutex every time void FeatureCursorOGR::readChunk() { if ( !_resultSetHandle ) return; OGR_SCOPED_LOCK; while( _queue.size() < _chunkSize && !_resultSetEndReached ) { FeatureList filterList; while( filterList.size() < _chunkSize && !_resultSetEndReached ) { OGRFeatureH handle = OGR_L_GetNextFeature( _resultSetHandle ); if ( handle ) { osg::ref_ptr<Feature> feature = OgrUtils::createFeature( handle, _profile.get() ); if (feature.valid() && !_source->isBlacklisted( feature->getFID() ) && validateGeometry( feature->getGeometry() )) { filterList.push_back( feature.release() ); } OGR_F_Destroy( handle ); } else { _resultSetEndReached = true; } } // preprocess the features using the filter list: if ( !_filters.empty() ) { FilterContext cx; cx.setProfile( _profile.get() ); if (_query.bounds().isSet()) { cx.extent() = GeoExtent(_profile->getSRS(), _query.bounds().get()); } else { cx.extent() = _profile->getExtent(); } for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( filterList, cx ); } } for(FeatureList::const_iterator i = filterList.begin(); i != filterList.end(); ++i) { _queue.push( i->get() ); } } }
void FeatureCursorCDBV::Read_Data_Directly(void) { FeatureList preProcessList; OGR_SCOPED_LOCK; OGR_L_ResetReading(_layerHandle); OGRFeatureH feat_handle; OGRLayer * thislayer = (OGRLayer *)_layerHandle; int totalCount = thislayer->GetFeatureCount(); int fcount = -1; while ((feat_handle = OGR_L_GetNextFeature(_layerHandle)) != NULL) { ++fcount; if (feat_handle) { osg::ref_ptr<Feature> f = OgrUtils::createFeature(feat_handle, _profile.get()); if (f.valid() && !_source->isBlacklisted(f->getFID())) { if (isGeometryValid(f->getGeometry())) { _queue.push(f); if (_filters.size() > 0) { preProcessList.push_back(f.release()); } } else { OE_DEBUG << LC << "Skipping feature with invalid geometry: " << f->getGeoJSON() << std::endl; } } OGR_F_Destroy(feat_handle); } } // preprocess the features using the filter list: if (preProcessList.size() > 0) { FilterContext cx; cx.setProfile(_profile.get()); for (FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i) { FeatureFilter* filter = i->get(); cx = filter->push(preProcessList, cx); } } }
void FeatureSourceOptions::fromConfig( const Config& conf ) { unsigned numResamples = 0; conf.getIfSet ( "open_write", _openWrite ); conf.getIfSet ( "name", _name ); conf.getObjIfSet( "profile", _profile ); conf.getObjIfSet( "cache_policy", _cachePolicy ); conf.getIfSet ( "geo_interpolation", "great_circle", _geoInterp, GEOINTERP_GREAT_CIRCLE ); conf.getIfSet ( "geo_interpolation", "rhumb_line", _geoInterp, GEOINTERP_RHUMB_LINE ); const ConfigSet& children = conf.children(); for( ConfigSet::const_iterator i = children.begin(); i != children.end(); ++i ) { const Config& child = *i; if (!child.empty()) { FeatureFilter* filter = FeatureFilterRegistry::instance()->create( child ); if (filter) { //Do some checks to make sure resample filters are applied before buffering. ResampleFilter* resample = dynamic_cast< ResampleFilter*>( filter ); BufferFilter* buffer = dynamic_cast< BufferFilter*>(filter ); if (resample) { numResamples++; } else if (buffer) { if ( numResamples > 0 ) { OE_WARN << LC << "Warning: Resampling should be applied after buffering, as buffering" << " will remove colinear segments created by the resample operation." << std::endl; } } OE_DEBUG << "Added FeatureFilter " << filter->getConfig().toJSON(true) << std::endl; _filters.push_back( filter ); } } } }
const Status& FeatureSource::open(const osgDB::Options* readOptions) { if ( readOptions ) _readOptions = readOptions; // Create and initialize the filters. for(unsigned i=0; i<_options.filters().size(); ++i) { const ConfigOptions& conf = _options.filters().at(i); FeatureFilter* filter = FeatureFilterRegistry::instance()->create( conf.getConfig(), 0L ); if ( filter ) { _filters.push_back( filter ); filter->initialize( readOptions ); } } _status = initialize(readOptions); return _status; }
const Status& FeatureSource::open() { // Create and initialize the filters. for(unsigned i=0; i<_options.filters().size(); ++i) { const ConfigOptions& conf = _options.filters()[i]; FeatureFilter* filter = FeatureFilterRegistry::instance()->create( conf.getConfig(), 0L ); if ( filter ) { if (_filters.valid() == false) _filters = new FeatureFilterChain(); _filters->push_back( filter ); filter->initialize(_readOptions.get()); } } _status = initialize(_readOptions.get()); return _status; }
// reads a chunk of features into a memory cache; do this for performance // and to avoid needing the OGR Mutex every time void FeatureCursorCDBV::readChunk() { if ( !_resultSetHandle ) return; FeatureList preProcessList; OGR_SCOPED_LOCK; if ( _nextHandleToQueue ) { osg::ref_ptr<Feature> f = OgrUtils::createFeature( _nextHandleToQueue, _profile.get() ); if ( f.valid() && !_source->isBlacklisted(f->getFID()) ) { f->setFID(_s_CDBV_FeatureID); ++_s_CDBV_FeatureID; if ( isGeometryValid( f->getGeometry() ) ) { _queue.push( f ); if ( _filters.size() > 0 ) { preProcessList.push_back( f.release() ); } } else { OE_DEBUG << LC << "Skipping feature with invalid geometry: " << f->getGeoJSON() << std::endl; } } OGR_F_Destroy( _nextHandleToQueue ); _nextHandleToQueue = 0L; } unsigned handlesToQueue = _chunkSize - _queue.size(); bool resultSetEndReached = false; for( unsigned i=0; i<handlesToQueue; i++ ) { OGRFeatureH handle = OGR_L_GetNextFeature( _resultSetHandle ); if ( handle ) { osg::ref_ptr<Feature> f = OgrUtils::createFeature( handle, _profile.get() ); if ( f.valid() && !_source->isBlacklisted(f->getFID()) ) { f->setFID(_s_CDBV_FeatureID); ++_s_CDBV_FeatureID; if (isGeometryValid( f->getGeometry() ) ) { _queue.push( f ); if ( _filters.size() > 0 ) { preProcessList.push_back( f.release() ); } } else { OE_DEBUG << LC << "Skipping feature with invalid geometry: " << f->getGeoJSON() << std::endl; } } OGR_F_Destroy( handle ); } else { resultSetEndReached = true; break; } } // preprocess the features using the filter list: if ( preProcessList.size() > 0 ) { FilterContext cx; cx.setProfile( _profile.get() ); for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( preProcessList, cx ); } } // read one more for "more" detection: if (!resultSetEndReached) _nextHandleToQueue = OGR_L_GetNextFeature( _resultSetHandle ); else _nextHandleToQueue = 0L; //OE_NOTICE << "read " << _queue.size() << " features ... " << std::endl; }
// reads a chunk of features into a memory cache; do this for performance // and to avoid needing the OGR Mutex every time void FeatureCursorOGR::readChunk() { if ( !_resultSetHandle ) return; FeatureList preProcessList; OGR_SCOPED_LOCK; if ( _nextHandleToQueue ) { Feature* f = createFeature( _nextHandleToQueue ); if ( f ) { _queue.push( f ); if ( _filters.size() > 0 ) preProcessList.push_back( f ); } OGR_F_Destroy( _nextHandleToQueue ); _nextHandleToQueue = 0L; } int handlesToQueue = _chunkSize - _queue.size(); for( int i=0; i<handlesToQueue; i++ ) { OGRFeatureH handle = OGR_L_GetNextFeature( _resultSetHandle ); if ( handle ) { Feature* f = createFeature( handle ); if ( f ) { _queue.push( f ); if ( _filters.size() > 0 ) preProcessList.push_back( f ); } OGR_F_Destroy( handle ); } else break; } // preprocess the features using the filter list: if ( preProcessList.size() > 0 ) { FilterContext cx; cx.profile() = _profile.get(); for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { FeatureFilter* filter = i->get(); cx = filter->push( preProcessList, cx ); } } // read one more for "more" detection: _nextHandleToQueue = OGR_L_GetNextFeature( _resultSetHandle ); //OE_NOTICE << "read " << _queue.size() << " features ... " << std::endl; }
FeatureCursor* createFeatureCursor(const Symbology::Query& query, ProgressCallback* progress) { FeatureCursor* result = 0L; std::string url = createURL( query ); // the URL wil lbe empty if it was invalid or outside the level bounds of the layer. if (url.empty()) return 0L; OE_DEBUG << LC << url << std::endl; URI uri(url, _options.url()->context()); // read the data: ReadResult r = uri.readString(_readOptions.get(), progress); const std::string& buffer = r.getString(); const Config& meta = r.metadata(); bool dataOK = false; FeatureList features; if ( !buffer.empty() ) { // Get the mime-type from the metadata record if possible std::string mimeType = r.metadata().value( IOMetadata::CONTENT_TYPE ); //If the mimetype is empty then try to set it from the format specification if (mimeType.empty()) { if (_options.format().value() == "json") mimeType = "json"; else if (_options.format().value().compare("gml") == 0) mimeType = "text/xml"; else if (_options.format().value().compare("pbf") == 0) mimeType = "application/x-protobuf"; } dataOK = getFeatures( buffer, *query.tileKey(), mimeType, features ); } if ( dataOK ) { OE_DEBUG << LC << "Read " << features.size() << " features" << std::endl; } //If we have any filters, process them here before the cursor is created if (getFilters() && !getFilters()->empty() && !features.empty()) { FilterContext cx; cx.setProfile(getFeatureProfile()); cx.extent() = query.tileKey()->getExtent(); for (FeatureFilterChain::const_iterator i = getFilters()->begin(); i != getFilters()->end(); ++i) { FeatureFilter* filter = i->get(); cx = filter->push(features, cx); } } // If we have any features and we have an fid attribute, override the fid of the features if (_options.fidAttribute().isSet()) { for (FeatureList::iterator itr = features.begin(); itr != features.end(); ++itr) { std::string attr = itr->get()->getString(_options.fidAttribute().get()); FeatureID fid = as<long>(attr, 0); itr->get()->setFID( fid ); } } result = new FeatureListCursor(features); return result; }