Skip to content

Commit 6fb7856

Browse files
committedFeb 12, 2019
[memory] Fix inefficient memory feature iteration when using a FilterFids request
The request was not being handled correctly by the provider, resulting in the provider iterating through every feature in the layer at every attempt to retrieve a particular feature from a list of IDs. Greatly speeds up numerous Processing algorithms when working with temporary outputs
1 parent 916805c commit 6fb7856

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed
 

‎src/core/providers/memory/qgsmemoryfeatureiterator.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource *sour
7171
if ( it != mSource->mFeatures.constEnd() )
7272
mFeatureIdList.append( mRequest.filterFid() );
7373
}
74+
else if ( mRequest.filterType() == QgsFeatureRequest::FilterFids )
75+
{
76+
mUsingFeatureIdList = true;
77+
mFeatureIdList = mRequest.filterFids().toList();
78+
}
7479
else
7580
{
7681
mUsingFeatureIdList = false;
@@ -105,11 +110,25 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature &feature )
105110
// option 1: we have a list of features to traverse
106111
while ( mFeatureIdListIterator != mFeatureIdList.constEnd() )
107112
{
108-
if ( !mFilterRect.isNull() && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
113+
if ( !mFilterRect.isNull() )
109114
{
110-
// do exact check in case we're doing intersection
111-
if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSelectRectEngine->intersects( mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().constGet() ) )
115+
if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
116+
{
117+
// do exact check in case we're doing intersection
118+
if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSelectRectEngine->intersects( mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().constGet() ) )
119+
hasFeature = true;
120+
}
121+
else if ( mSource->mSpatialIndex )
122+
{
123+
// using a spatial index - so we already know that the bounding box intersects correctly
112124
hasFeature = true;
125+
}
126+
else
127+
{
128+
// do bounding box check if we aren't using a spatial index
129+
if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().boundingBoxIntersects( mFilterRect ) )
130+
hasFeature = true;
131+
}
113132
}
114133
else
115134
hasFeature = true;

0 commit comments

Comments
 (0)
Please sign in to comment.