Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix failing feature source conformance tests for QgsVectorLayerSelect…
…edFeatureSource

Fixes #19324

(cherry-picked from eb53e3b)
  • Loading branch information
nyalldawson committed Jul 10, 2018
1 parent 16f1504 commit c7e78ed
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
Expand Up @@ -191,6 +191,8 @@ the QgsVectorLayerSelectedFeatureSource will not be reflected.

};



/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
52 changes: 50 additions & 2 deletions src/core/qgsvectorlayerfeatureiterator.cpp
Expand Up @@ -1090,7 +1090,13 @@ QgsFeatureIterator QgsVectorLayerSelectedFeatureSource::getFeatures( const QgsFe
{
QgsFeatureRequest req( request );

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

return mSource.getFeatures( req );
return QgsFeatureIterator( new QgsVectorLayerSelectedFeatureIterator( mSelectedFeatureIds, req, mSource ) );
}

QgsCoordinateReferenceSystem QgsVectorLayerSelectedFeatureSource::sourceCrs() const
Expand Down Expand Up @@ -1136,3 +1142,45 @@ QgsExpressionContextScope *QgsVectorLayerSelectedFeatureSource::createExpression
else
return nullptr;
}

//
// QgsVectorLayerSelectedFeatureIterator
//

///@cond PRIVATE
QgsVectorLayerSelectedFeatureIterator::QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds, const QgsFeatureRequest &request, QgsVectorLayerFeatureSource &source )
: QgsAbstractFeatureIterator( request )
, mSelectedFeatureIds( selectedFeatureIds )
{
QgsFeatureRequest sourceRequest = request;
if ( sourceRequest.filterType() == QgsFeatureRequest::FilterExpression && sourceRequest.limit() > 0 )
{
// we can't pass the request limit to the provider here - otherwise the provider will
// limit the number of returned features and may only return a bunch of matching features
// which AREN'T in the selected feature set
sourceRequest.setLimit( -1 );
}
mIterator = source.getFeatures( sourceRequest );
}

bool QgsVectorLayerSelectedFeatureIterator::rewind()
{
return mIterator.rewind();
}

bool QgsVectorLayerSelectedFeatureIterator::close()
{
return mIterator.close();
}

bool QgsVectorLayerSelectedFeatureIterator::fetchFeature( QgsFeature &f )
{
while ( mIterator.nextFeature( f ) )
{
if ( mSelectedFeatureIds.contains( f.id() ) )
return true;
}
return false;
}

///@endcond
27 changes: 27 additions & 0 deletions src/core/qgsvectorlayerfeatureiterator.h
Expand Up @@ -318,4 +318,31 @@ class CORE_EXPORT QgsVectorLayerSelectedFeatureSource : public QgsFeatureSource,

};

///@cond PRIVATE

#ifndef SIP_RUN
class QgsVectorLayerSelectedFeatureIterator : public QgsAbstractFeatureIterator
{
public:

QgsVectorLayerSelectedFeatureIterator( const QgsFeatureIds &selectedFeatureIds,
const QgsFeatureRequest &request,
QgsVectorLayerFeatureSource &source );

bool rewind() override;
bool close() override;

protected:
bool fetchFeature( QgsFeature &f ) override;

private:
QgsFeatureIds mSelectedFeatureIds;
QgsFeatureIterator mIterator;

};

///@endcond

#endif

#endif // QGSVECTORLAYERFEATUREITERATOR_H

0 comments on commit c7e78ed

Please sign in to comment.