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);
		}
	}

}
// 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;
}
Exemple #5
0
// 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;
    }