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 = qgis::make_unique< QgsExpression >( mSource->mSubsetString );
50 mSubsetExpression->prepare( &mSource->mExpressionContext );
57 mSelectRectEngine->prepareGeometry();
62 if ( !mFilterRect.isNull() && mSource->mSpatialIndex )
64 mUsingFeatureIdList =
true;
65 mFeatureIdList = mSource->mSpatialIndex->intersects( mFilterRect );
66 QgsDebugMsg(
"Features returned by spatial index: " + QString::number( mFeatureIdList.count() ) );
70 mUsingFeatureIdList =
true;
71 QgsFeatureMap::const_iterator it = mSource->mFeatures.constFind( mRequest.filterFid() );
72 if ( it != mSource->mFeatures.constEnd() )
73 mFeatureIdList.append( mRequest.filterFid() );
77 mUsingFeatureIdList =
true;
78 mFeatureIdList = qgis::setToList( mRequest.filterFids() );
82 mUsingFeatureIdList =
false;
88 QgsMemoryFeatureIterator::~QgsMemoryFeatureIterator()
93 bool QgsMemoryFeatureIterator::fetchFeature(
QgsFeature &feature )
100 if ( mUsingFeatureIdList )
101 return nextFeatureUsingList( feature );
103 return nextFeatureTraverseAll( feature );
107 bool QgsMemoryFeatureIterator::nextFeatureUsingList(
QgsFeature &feature )
109 bool hasFeature =
false;
113 while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
115 candidate = mSource->mFeatures.value( *mFeatureIdListIterator );
116 if ( !mFilterRect.isNull() )
124 else if ( mSource->mSpatialIndex )
139 if ( hasFeature && mSubsetExpression )
141 mSource->mExpressionContext.setFeature( candidate );
142 if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
149 ++mFeatureIdListIterator;
156 ++mFeatureIdListIterator;
164 geometryToDestinationCrs( feature, mTransform );
171 bool QgsMemoryFeatureIterator::nextFeatureTraverseAll(
QgsFeature &feature )
173 bool hasFeature =
false;
176 while ( mSelectIterator != mSource->mFeatures.constEnd() )
178 if ( mFilterRect.isNull() )
188 if ( mSelectIterator->hasGeometry() && mSelectRectEngine->intersects( mSelectIterator->geometry().constGet() ) )
194 if ( mSelectIterator->hasGeometry() && mSelectIterator->geometry().boundingBox().intersects( mFilterRect ) )
199 if ( mSubsetExpression )
201 mSource->mExpressionContext.setFeature( *mSelectIterator );
202 if ( !mSubsetExpression->evaluate( &mSource->mExpressionContext ).toBool() )
215 feature = mSelectIterator.value();
219 geometryToDestinationCrs( feature, mTransform );
227 bool QgsMemoryFeatureIterator::rewind()
232 if ( mUsingFeatureIdList )
233 mFeatureIdListIterator = mFeatureIdList.constBegin();
235 mSelectIterator = mSource->mFeatures.constBegin();
240 bool QgsMemoryFeatureIterator::close()
253 QgsMemoryFeatureSource::QgsMemoryFeatureSource(
const QgsMemoryProvider *p )
254 : mFields( p->mFields )
255 , mFeatures( p->mFeatures )
256 , mSpatialIndex( p->mSpatialIndex ? qgis::make_unique<
QgsSpatialIndex >( *p->mSpatialIndex ) : nullptr )
257 , mSubsetString( p->mSubsetString )
262 mExpressionContext.setFields( mFields );