Skip to content

Commit eb53e3b

Browse files
committedJul 5, 2018
Fix failing feature source conformance tests for QgsVectorLayerSelectedFeatureSource
Fixes #19324
1 parent 565980f commit eb53e3b

File tree

3 files changed

+79
-2
lines changed

3 files changed

+79
-2
lines changed
 

‎python/core/auto_generated/qgsvectorlayerfeatureiterator.sip.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ the QgsVectorLayerSelectedFeatureSource will not be reflected.
191191

192192
};
193193

194+
195+
194196
/************************************************************************
195197
* This file has been generated automatically from *
196198
* *

‎src/core/qgsvectorlayerfeatureiterator.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,7 +1090,13 @@ QgsFeatureIterator QgsVectorLayerSelectedFeatureSource::getFeatures( const QgsFe
10901090
{
10911091
QgsFeatureRequest req( request );
10921092

1093-
if ( req.filterFids().isEmpty() && req.filterType() != QgsFeatureRequest::FilterFid )
1093+
// while QgsVectorLayerSelectedFeatureIterator will reject any features not in mSelectedFeatureIds,
1094+
// we still tweak the feature request to only request selected feature ids wherever we can -- this
1095+
// allows providers to optimise the request and avoid requesting features we don't need
1096+
// note that we can't do this for some request types - e.g. expression based requests, so
1097+
// in that case we just pass the request on to the provider and let QgsVectorLayerSelectedFeatureIterator
1098+
// do ALL the filtering
1099+
if ( req.filterFids().isEmpty() && req.filterType() == QgsFeatureRequest::FilterNone )
10941100
{
10951101
req.setFilterFids( mSelectedFeatureIds );
10961102
}
@@ -1101,7 +1107,7 @@ QgsFeatureIterator QgsVectorLayerSelectedFeatureSource::getFeatures( const QgsFe
11011107
req.setFilterFids( reqIds );
11021108
}
11031109

1104-
return mSource.getFeatures( req );
1110+
return QgsFeatureIterator( new QgsVectorLayerSelectedFeatureIterator( mSelectedFeatureIds, req, mSource ) );
11051111
}
11061112

11071113
QgsCoordinateReferenceSystem QgsVectorLayerSelectedFeatureSource::sourceCrs() const
@@ -1136,3 +1142,45 @@ QgsExpressionContextScope *QgsVectorLayerSelectedFeatureSource::createExpression
11361142
else
11371143
return nullptr;
11381144
}
1145+
1146+
//
1147+
// QgsVectorLayerSelectedFeatureIterator
1148+
//
1149+
1150+
///@cond PRIVATE
1151+
QgsVectorLayerSelectedFeatureIterator::QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds, const QgsFeatureRequest &request, QgsVectorLayerFeatureSource &source )
1152+
: QgsAbstractFeatureIterator( request )
1153+
, mSelectedFeatureIds( selectedFeatureIds )
1154+
{
1155+
QgsFeatureRequest sourceRequest = request;
1156+
if ( sourceRequest.filterType() == QgsFeatureRequest::FilterExpression && sourceRequest.limit() > 0 )
1157+
{
1158+
// we can't pass the request limit to the provider here - otherwise the provider will
1159+
// limit the number of returned features and may only return a bunch of matching features
1160+
// which AREN'T in the selected feature set
1161+
sourceRequest.setLimit( -1 );
1162+
}
1163+
mIterator = source.getFeatures( sourceRequest );
1164+
}
1165+
1166+
bool QgsVectorLayerSelectedFeatureIterator::rewind()
1167+
{
1168+
return mIterator.rewind();
1169+
}
1170+
1171+
bool QgsVectorLayerSelectedFeatureIterator::close()
1172+
{
1173+
return mIterator.close();
1174+
}
1175+
1176+
bool QgsVectorLayerSelectedFeatureIterator::fetchFeature( QgsFeature &f )
1177+
{
1178+
while ( mIterator.nextFeature( f ) )
1179+
{
1180+
if ( mSelectedFeatureIds.contains( f.id() ) )
1181+
return true;
1182+
}
1183+
return false;
1184+
}
1185+
1186+
///@endcond

‎src/core/qgsvectorlayerfeatureiterator.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,4 +318,31 @@ class CORE_EXPORT QgsVectorLayerSelectedFeatureSource : public QgsFeatureSource,
318318

319319
};
320320

321+
///@cond PRIVATE
322+
323+
#ifndef SIP_RUN
324+
class QgsVectorLayerSelectedFeatureIterator : public QgsAbstractFeatureIterator
325+
{
326+
public:
327+
328+
QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds,
329+
const QgsFeatureRequest &request,
330+
QgsVectorLayerFeatureSource &source );
331+
332+
bool rewind() override;
333+
bool close() override;
334+
335+
protected:
336+
bool fetchFeature( QgsFeature &f ) override;
337+
338+
private:
339+
QgsFeatureIds mSelectedFeatureIds;
340+
QgsFeatureIterator mIterator;
341+
342+
};
343+
344+
///@endcond
345+
346+
#endif
347+
321348
#endif // QGSVECTORLAYERFEATUREITERATOR_H

0 commit comments

Comments
 (0)
Please sign in to comment.