@@ -1090,7 +1090,13 @@ QgsFeatureIterator QgsVectorLayerSelectedFeatureSource::getFeatures( const QgsFe
1090
1090
{
1091
1091
QgsFeatureRequest req ( request );
1092
1092
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 )
1094
1100
{
1095
1101
req.setFilterFids ( mSelectedFeatureIds );
1096
1102
}
@@ -1101,7 +1107,7 @@ QgsFeatureIterator QgsVectorLayerSelectedFeatureSource::getFeatures( const QgsFe
1101
1107
req.setFilterFids ( reqIds );
1102
1108
}
1103
1109
1104
- return mSource . getFeatures ( req );
1110
+ return QgsFeatureIterator ( new QgsVectorLayerSelectedFeatureIterator ( mSelectedFeatureIds , req, mSource ) );
1105
1111
}
1106
1112
1107
1113
QgsCoordinateReferenceSystem QgsVectorLayerSelectedFeatureSource::sourceCrs () const
@@ -1136,3 +1142,45 @@ QgsExpressionContextScope *QgsVectorLayerSelectedFeatureSource::createExpression
1136
1142
else
1137
1143
return nullptr ;
1138
1144
}
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
0 commit comments