29 QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource *source,
bool ownSource,
const QgsFeatureRequest &request )
32 if ( mRequest.destinationCrs().isValid() && mRequest.destinationCrs() != mSource->mCrs )
34 mTransform =
QgsCoordinateTransform( mSource->mCrs, mRequest.destinationCrs(), mRequest.transformContext() );
38 mFilterRect = filterRectToSourceCrs( mTransform );
47 if ( !mSource->mSubsetString.isEmpty() )
49 mSubsetExpression = std::make_unique< QgsExpression >( mSource->mSubsetString );
50 mSubsetExpression->prepare( mSource->expressionContext() );
54 switch ( mRequest.spatialFilterType() )
64 mSelectRectEngine->prepareGeometry();
69 if ( !mRequest.referenceGeometry().isEmpty() )
71 mDistanceWithinGeom = mRequest.referenceGeometry();
73 mDistanceWithinEngine->prepareGeometry();
80 if ( !mFilterRect.isNull() && mSource->mSpatialIndex )
82 mUsingFeatureIdList =
true;
83 mFeatureIdList = mSource->mSpatialIndex->intersects( mFilterRect );
84 QgsDebugMsgLevel(
"Features returned by spatial index: " + QString::number( mFeatureIdList.count() ), 2 );
88 mUsingFeatureIdList =
true;
89 const QgsFeatureMap::const_iterator it = mSource->mFeatures.constFind( mRequest.filterFid() );
90 if ( it != mSource->mFeatures.constEnd() )
91 mFeatureIdList.append( mRequest.filterFid() );
95 mUsingFeatureIdList =
true;
96 mFeatureIdList = qgis::setToList( mRequest.filterFids() );
100 mUsingFeatureIdList =
false;
106 QgsMemoryFeatureIterator::~QgsMemoryFeatureIterator()
111 bool QgsMemoryFeatureIterator::fetchFeature(
QgsFeature &feature )
118 if ( mUsingFeatureIdList )
119 return nextFeatureUsingList( feature );
121 return nextFeatureTraverseAll( feature );
125 bool QgsMemoryFeatureIterator::nextFeatureUsingList(
QgsFeature &feature )
127 bool hasFeature =
false;
130 while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
132 feature = mSource->mFeatures.value( *mFeatureIdListIterator );
133 if ( !mFilterRect.isNull() )
141 else if ( mSource->mSpatialIndex )
159 if ( hasFeature && mSubsetExpression )
161 mSource->expressionContext()->setFeature( feature );
162 if ( !mSubsetExpression->evaluate( mSource->expressionContext() ).toBool() )
169 geometryToDestinationCrs( feature, mTransform );
174 hasFeature = mDistanceWithinEngine->distance( feature.
geometry().
constGet() ) <= mRequest.distanceWithin();
177 ++mFeatureIdListIterator;
192 bool QgsMemoryFeatureIterator::nextFeatureTraverseAll(
QgsFeature &feature )
194 bool hasFeature =
false;
197 while ( mSelectIterator != mSource->mFeatures.constEnd() )
200 feature = *mSelectIterator;
201 if ( mFilterRect.isNull() )
222 if ( hasFeature && mSubsetExpression )
224 mSource->expressionContext()->setFeature( feature );
225 if ( !mSubsetExpression->evaluate( mSource->expressionContext() ).toBool() )
232 geometryToDestinationCrs( feature, mTransform );
237 hasFeature = mDistanceWithinEngine->distance( feature.
geometry().
constGet() ) <= mRequest.distanceWithin();
260 bool QgsMemoryFeatureIterator::rewind()
265 if ( mUsingFeatureIdList )
266 mFeatureIdListIterator = mFeatureIdList.constBegin();
268 mSelectIterator = mSource->mFeatures.constBegin();
273 bool QgsMemoryFeatureIterator::close()
286 QgsMemoryFeatureSource::QgsMemoryFeatureSource(
const QgsMemoryProvider *p )
287 : mFields( p->mFields )
288 , mFeatures( p->mFeatures )
289 , mSpatialIndex( p->mSpatialIndex ? std::make_unique<
QgsSpatialIndex >( *p->mSpatialIndex ) : nullptr )
290 , mSubsetString( p->mSubsetString )
304 if ( !mExpressionContext )
306 mExpressionContext = std::make_unique< QgsExpressionContext >(
307 QList<QgsExpressionContextScope *>()
310 mExpressionContext->setFields( mFields );
312 return mExpressionContext.get();