28 QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource *source,
bool ownSource,
const QgsFeatureRequest &request )
31 if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mSource->mCrs )
33 mTransform =
QgsCoordinateTransform( mSource->mCrs, mRequest.destinationCrs(), mRequest.transformContext() );
37 mFilterRect = filterRectToSourceCrs( mTransform );
46 if ( !mSource->mSubsetString.isEmpty() )
48 mSubsetExpression = qgis::make_unique< QgsExpression >( mSource->mSubsetString );
49 mSubsetExpression->prepare( &mSource->mExpressionContext );
56 mSelectRectEngine->prepareGeometry();
61 if ( !mFilterRect.isNull() && mSource->mSpatialIndex )
63 mUsingFeatureIdList =
true;
64 mFeatureIdList = mSource->mSpatialIndex->intersects( mFilterRect );
65 QgsDebugMsg(
"Features returned by spatial index: " + QString::number( mFeatureIdList.count() ) );
69 mUsingFeatureIdList =
true;
70 QgsFeatureMap::const_iterator it = mSource->mFeatures.constFind( mRequest.filterFid() );
71 if ( it != mSource->mFeatures.constEnd() )
72 mFeatureIdList.append( mRequest.filterFid() );
76 mUsingFeatureIdList =
false;
82 QgsMemoryFeatureIterator::~QgsMemoryFeatureIterator()
87 bool QgsMemoryFeatureIterator::fetchFeature(
QgsFeature &feature )
94 if ( mUsingFeatureIdList )
95 return nextFeatureUsingList( feature );
97 return nextFeatureTraverseAll( feature );
101 bool QgsMemoryFeatureIterator::nextFeatureUsingList(
QgsFeature &feature )
103 bool hasFeature =
false;
106 while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
111 if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSelectRectEngine->intersects( mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().constGet() ) )
117 if ( mSubsetExpression )
119 mSource->mExpressionContext.setFeature( mSource->mFeatures.value( *mFeatureIdListIterator ) );
120 if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
127 ++mFeatureIdListIterator;
133 feature = mSource->mFeatures.value( *mFeatureIdListIterator );
134 ++mFeatureIdListIterator;
142 geometryToDestinationCrs( feature, mTransform );
149 bool QgsMemoryFeatureIterator::nextFeatureTraverseAll(
QgsFeature &feature )
151 bool hasFeature =
false;
154 while ( mSelectIterator != mSource->mFeatures.constEnd() )
156 if ( mFilterRect.isNull() )
166 if ( mSelectIterator->hasGeometry() && mSelectRectEngine->intersects( mSelectIterator->geometry().constGet() ) )
172 if ( mSelectIterator->hasGeometry() && mSelectIterator->geometry().boundingBox().intersects( mFilterRect ) )
177 if ( mSubsetExpression )
179 mSource->mExpressionContext.setFeature( *mSelectIterator );
180 if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
193 feature = mSelectIterator.value();
197 geometryToDestinationCrs( feature, mTransform );
205 bool QgsMemoryFeatureIterator::rewind()
210 if ( mUsingFeatureIdList )
211 mFeatureIdListIterator = mFeatureIdList.constBegin();
213 mSelectIterator = mSource->mFeatures.constBegin();
218 bool QgsMemoryFeatureIterator::close()
231 QgsMemoryFeatureSource::QgsMemoryFeatureSource(
const QgsMemoryProvider *p )
232 : mFields( p->mFields )
233 , mFeatures( p->mFeatures )
234 , mSpatialIndex( p->mSpatialIndex ? qgis::make_unique<
QgsSpatialIndex >( *p->mSpatialIndex ) : nullptr )
235 , mSubsetString( p->mSubsetString )
240 mExpressionContext.setFields( mFields );
Wrapper for iterator of features from vector data provider or vector layer.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
Use exact geometry intersection (slower) instead of bounding boxes.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static QgsGeometry fromRect(const QgsRectangle &rect)
Creates a new geometry from a QgsRectangle.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
This class wraps a request for features to a vector layer (or directly its vector data provider)...
static QgsGeometryEngine * createGeometryEngine(const QgsAbstractGeometry *geometry)
Creates and returns a new geometry engine.
void setValid(bool validity)
Sets the validity of the feature.
A spatial index for QgsFeature objects.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Custom exception class for Coordinate Reference System related exceptions.
Helper template that cares of two things: 1.