Skip to content
Permalink
Browse files
Support early abortion of vector layer feature counter
Refs #43572
  • Loading branch information
nyalldawson committed Jun 18, 2021
1 parent e7433f4 commit b16465bc319dd3f5d831fb2129d4e56ea0018f5d
@@ -32,14 +32,17 @@ Create a new feature counter for ``layer``.
:param context: Specific :py:class:`QgsExpressionContext` to use during the rendering step.
:param storeSymbolFids: If ``True`` will store the feature ids (fids), otherwise will only count the number of features per symbol. Default ``False``.
%End

~QgsVectorLayerFeatureCounter();

virtual bool run();

%Docstring
Calculates the feature count and Ids per symbol
%End

virtual void cancel();



long long featureCount( const QString &legendKey ) const;
%Docstring
@@ -16,6 +16,7 @@
#include "qgsvectorlayerfeaturecounter.h"
#include "qgsvectorlayer.h"
#include "qgsfeatureid.h"
#include "qgsfeedback.h"

QgsVectorLayerFeatureCounter::QgsVectorLayerFeatureCounter( QgsVectorLayer *layer, const QgsExpressionContext &context, bool storeSymbolFids )
: QgsTask( tr( "Counting features in %1" ).arg( layer->name() ), QgsTask::CanCancel )
@@ -31,6 +32,8 @@ QgsVectorLayerFeatureCounter::QgsVectorLayerFeatureCounter( QgsVectorLayer *laye
}
}

QgsVectorLayerFeatureCounter::~QgsVectorLayerFeatureCounter() = default;

bool QgsVectorLayerFeatureCounter::run()
{
mSymbolFeatureCountMap.clear();
@@ -48,6 +51,8 @@ bool QgsVectorLayerFeatureCounter::run()
// If there are no features to be counted, we can spare us the trouble
if ( mFeatureCount > 0 )
{
mFeedback = std::make_unique< QgsFeedback >();

int featuresCounted = 0;

// Renderer (rule based) may depend on context scale, with scale is ignored if 0
@@ -59,10 +64,11 @@ bool QgsVectorLayerFeatureCounter::run()
if ( !mRenderer->filterNeedsGeometry() )
request.setFlags( QgsFeatureRequest::NoGeometry );
request.setSubsetOfAttributes( mRenderer->usedAttributes( renderContext ), mSource->fields() );
QgsFeatureIterator fit = mSource->getFeatures( request );

// TODO: replace QgsInterruptionChecker with QgsFeedback
// fit.setInterruptionChecker( mFeedback );
request.setFeedback( mFeedback.get() );
mExpressionContext.setFeedback( mFeedback.get() );

QgsFeatureIterator fit = mSource->getFeatures( request );

mRenderer->startRender( renderContext, mSource->fields() );

@@ -91,17 +97,27 @@ bool QgsVectorLayerFeatureCounter::run()
if ( isCanceled() )
{
mRenderer->stopRender( renderContext );
mFeedback.reset();
return false;
}
}
mRenderer->stopRender( renderContext );
mExpressionContext.setFeedback( nullptr );
mFeedback.reset();
}
setProgress( 100 );
emit symbolsCounted();
return true;
}

QHash<QString, long long> QgsVectorLayerFeatureCounter::symbolFeatureCountMap() const
void QgsVectorLayerFeatureCounter::cancel()
{
if ( mFeedback )
mFeedback->cancel();
QgsTask::cancel();
}

QHash<QString, long> QgsVectorLayerFeatureCounter::symbolFeatureCountMap() const
{
return mSymbolFeatureCountMap;
}
@@ -43,13 +43,15 @@ class CORE_EXPORT QgsVectorLayerFeatureCounter : public QgsTask
* \param storeSymbolFids If TRUE will store the feature ids (fids), otherwise will only count the number of features per symbol. Default FALSE.
*/
QgsVectorLayerFeatureCounter( QgsVectorLayer *layer, const QgsExpressionContext &context = QgsExpressionContext(), bool storeSymbolFids = false );

~QgsVectorLayerFeatureCounter() override;

/**
* Calculates the feature count and Ids per symbol
*/
bool run() override;

void cancel() override;

/**
* Returns the count for each symbol. Only valid after the symbolsCounted()
* signal has been emitted.
@@ -95,8 +97,9 @@ class CORE_EXPORT QgsVectorLayerFeatureCounter : public QgsTask
QgsExpressionContext mExpressionContext;
QHash<QString, long long> mSymbolFeatureCountMap;
QHash<QString, QgsFeatureIds> mSymbolFeatureIdMap;
std::unique_ptr< QgsFeedback > mFeedback;
bool mWithFids = false;
int mFeatureCount;
long mFeatureCount = 0;

};

0 comments on commit b16465b

Please sign in to comment.