Config FeatureSourceOptions::toConfig() const { Config conf = DriverOptions::toConfig(); //TODO: make each of these filters Configurable. for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { BufferFilter* buffer = dynamic_cast<BufferFilter*>( i->get() ); if ( buffer ) { Config bufferConf( "buffer" ); bufferConf.addIfSet( "distance", buffer->distance() ); conf.update( bufferConf ); } ResampleFilter* resample = dynamic_cast<ResampleFilter*>( i->get() ); if ( resample ) { Config resampleConf( "resample" ); resampleConf.addIfSet( "min_length", resample->minLength() ); resampleConf.addIfSet( "max_length", resample->maxLength() ); conf.update( resampleConf ); } } return conf; }
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 FeatureSource::applyFilters(FeatureList& features, const GeoExtent& extent) const { // apply filters before returning. if ( !getFilters().empty() ) { FilterContext cx; cx.setProfile( getFeatureProfile() ); cx.extent() = extent; for(FeatureFilterList::const_iterator filter = getFilters().begin(); filter != getFilters().end(); ++filter) { cx = filter->get()->push( features, cx ); } } }
Config FeatureSourceOptions::getConfig() const { Config conf = DriverConfigOptions::getConfig(); conf.updateIfSet ( "open_write", _openWrite ); conf.updateIfSet ( "name", _name ); conf.updateObjIfSet( "profile", _profile ); conf.updateObjIfSet( "cache_policy", _cachePolicy ); for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { conf.update( i->get()->getConfig() ); } return conf; }
Feature* GeometryFeatureCursor::nextFeature() { if ( hasMore() ) { _lastFeature = new Feature( _geom.get(), _featureProfile.valid() ? _featureProfile->getSRS() : 0L ); FilterContext cx; cx.profile() = _featureProfile.get(); FeatureList list; list.push_back( _lastFeature.get() ); for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { cx = i->get()->push( list, cx ); } _geom = 0L; } return _lastFeature.get(); }
Config FeatureSourceOptions::getConfig() const { Config conf = DriverConfigOptions::getConfig(); conf.updateIfSet ( "open_write", _openWrite ); conf.updateIfSet ( "name", _name ); conf.updateObjIfSet( "profile", _profile ); conf.updateObjIfSet( "cache_policy", _cachePolicy ); conf.updateIfSet ( "geo_interpolation", "great_circle", _geoInterp, GEOINTERP_GREAT_CIRCLE ); conf.updateIfSet ( "geo_interpolation", "rhumb_line", _geoInterp, GEOINTERP_RHUMB_LINE ); for( FeatureFilterList::const_iterator i = _filters.begin(); i != _filters.end(); ++i ) { conf.update( i->get()->getConfig() ); } return conf; }
// 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) { FeatureCursor* result = 0L; std::string url = createURL( query ); if (url.empty()) return 0; // 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( _readOptions.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 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().empty()) { // preprocess the features using the filter list: if ( features.size() > 0 ) { FilterContext cx; cx.setProfile( getFeatureProfile() ); cx.extent() = query.tileKey()->getExtent(); for( FeatureFilterList::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); result = dataOK ? new FeatureListCursor( features ) : 0L; if ( !result ) Registry::instance()->blacklist( url ); return result; }