QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsvectorlayerfeaturecounter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayerfeaturecounter.cpp
3  ---------------------
4  begin : May 2017
5  copyright : (C) 2017 by Matthias Kuhn
6  email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 #include "qgsvectorlayer.h"
18 #include "qgsfeatureid.h"
19 
21  : QgsTask( tr( "Counting features in %1" ).arg( layer->name() ), QgsTask::CanCancel )
22  , mSource( new QgsVectorLayerFeatureSource( layer ) )
23  , mRenderer( layer->renderer()->clone() )
24  , mExpressionContext( context )
25  , mWithFids( storeSymbolFids )
26  , mFeatureCount( layer->featureCount() )
27 {
28  if ( !mExpressionContext.scopeCount() )
29  {
30  mExpressionContext = layer->createExpressionContext();
31  }
32 }
33 
35 {
36  mSymbolFeatureCountMap.clear();
37  mSymbolFeatureIdMap.clear();
38  QgsLegendSymbolList symbolList = mRenderer->legendSymbolItems();
39  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
40 
41  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
42  {
43  mSymbolFeatureCountMap.insert( symbolIt->label(), 0 );
44  if ( mWithFids )
45  mSymbolFeatureIdMap.insert( symbolIt->label(), QgsFeatureIds() );
46  }
47 
48  // If there are no features to be counted, we can spare us the trouble
49  if ( mFeatureCount > 0 )
50  {
51  int featuresCounted = 0;
52 
53  // Renderer (rule based) may depend on context scale, with scale is ignored if 0
54  QgsRenderContext renderContext;
55  renderContext.setRendererScale( 0 );
56  renderContext.setExpressionContext( mExpressionContext );
57 
58  QgsFeatureRequest request;
59  if ( !mRenderer->filterNeedsGeometry() )
61  request.setSubsetOfAttributes( mRenderer->usedAttributes( renderContext ), mSource->fields() );
62  QgsFeatureIterator fit = mSource->getFeatures( request );
63 
64  // TODO: replace QgsInterruptionChecker with QgsFeedback
65  // fit.setInterruptionChecker( mFeedback );
66 
67  mRenderer->startRender( renderContext, mSource->fields() );
68 
69  double progress = 0;
70  QgsFeature f;
71  while ( fit.nextFeature( f ) )
72  {
73  renderContext.expressionContext().setFeature( f );
74 
75  const QSet<QString> featureKeyList = mRenderer->legendKeysForFeature( f, renderContext );
76  for ( const QString &key : featureKeyList )
77  {
78  mSymbolFeatureCountMap[key] += 1;
79  if ( mWithFids )
80  mSymbolFeatureIdMap[key].insert( f.id() );
81  }
82  ++featuresCounted;
83 
84  double p = ( static_cast< double >( featuresCounted ) / mFeatureCount ) * 100;
85  if ( p - progress > 1 )
86  {
87  progress = p;
89  }
90 
91  if ( isCanceled() )
92  {
93  mRenderer->stopRender( renderContext );
94  return false;
95  }
96  }
97  mRenderer->stopRender( renderContext );
98  }
99  setProgress( 100 );
100  emit symbolsCounted();
101  return true;
102 }
103 
105 {
106  return mSymbolFeatureCountMap;
107 }
108 
109 long QgsVectorLayerFeatureCounter::featureCount( const QString &legendKey ) const
110 {
111  return mSymbolFeatureCountMap.value( legendKey, -1 );
112 }
113 
114 QHash<QString, QgsFeatureIds> QgsVectorLayerFeatureCounter::symbolFeatureIdMap() const
115 {
116  return mSymbolFeatureIdMap;
117 }
118 
120 {
121  return mSymbolFeatureIdMap.value( symbolkey, QgsFeatureIds() );
122 }
QgsFeatureRequest::NoGeometry
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
Definition: qgsfeaturerequest.h:81
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:370
QgsFeature::id
Q_GADGET QgsFeatureId id
Definition: qgsfeature.h:64
QgsRenderContext::expressionContext
QgsExpressionContext & expressionContext()
Gets the expression context.
Definition: qgsrendercontext.h:596
QgsVectorLayerFeatureCounter::symbolFeatureIdMap
QHash< QString, QgsFeatureIds > symbolFeatureIdMap() const
Returns the QgsFeatureIds for each symbol.
Definition: qgsvectorlayerfeaturecounter.cpp:114
QgsRenderContext
Contains information about the context of a rendering operation.
Definition: qgsrendercontext.h:58
qgsfeatureid.h
QgsFeatureRequest::setSubsetOfAttributes
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
Definition: qgsfeaturerequest.cpp:185
qgsvectorlayerfeaturecounter.h
QgsVectorLayerFeatureCounter::featureIds
QgsFeatureIds featureIds(const QString &symbolkey) const
Returns the feature Ids for a particular legendKey.
Definition: qgsvectorlayerfeaturecounter.cpp:119
QgsVectorLayerFeatureCounter::symbolFeatureCountMap
QHash< QString, long > symbolFeatureCountMap() const
Returns the count for each symbol.
Definition: qgsvectorlayerfeaturecounter.cpp:104
QgsExpressionContext::scopeCount
int scopeCount() const
Returns the number of scopes contained in the context.
Definition: qgsexpressioncontext.cpp:485
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:76
QgsTask::setProgress
void setProgress(double progress)
Sets the task's current progress.
Definition: qgstaskmanager.cpp:232
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsRenderContext::setRendererScale
void setRendererScale(double scale)
Sets the renderer map scale.
Definition: qgsrendercontext.h:483
qgsvectorlayer.h
QgsVectorLayerFeatureCounter::run
bool run() override
Calculates the feature count and Ids per symbol.
Definition: qgsvectorlayerfeaturecounter.cpp:34
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:374
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsVectorLayerFeatureSource
Partial snapshot of vector layer's state (only the members necessary for access to features)
Definition: qgsvectorlayerfeatureiterator.h:52
QgsVectorLayerFeatureCounter::QgsVectorLayerFeatureCounter
QgsVectorLayerFeatureCounter(QgsVectorLayer *layer, const QgsExpressionContext &context=QgsExpressionContext(), bool storeSymbolFids=false)
Create a new feature counter for layer.
Definition: qgsvectorlayerfeaturecounter.cpp:20
QgsVectorLayerFeatureCounter::symbolsCounted
void symbolsCounted()
Emitted when the symbols have been counted.
QgsRenderContext::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Definition: qgsrendercontext.h:588
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsVectorLayer::createExpressionContext
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgsvectorlayer.cpp:4952
QgsLegendSymbolList
QList< QgsLegendSymbolItem > QgsLegendSymbolList
Definition: qgslegendsymbolitem.h:144
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:265
QgsFeatureRequest::setFlags
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Definition: qgsfeaturerequest.cpp:179
QgsVectorLayerFeatureCounter::featureCount
long featureCount(const QString &legendKey) const
Returns the feature count for a particular legendKey.
Definition: qgsvectorlayerfeaturecounter.cpp:109
QgsTask::progress
double progress() const
Returns the task's progress (between 0.0 and 100.0)
Definition: qgstaskmanager.h:123
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:521
QgsTask::isCanceled
bool isCanceled() const
Will return true if task should terminate ASAP.
Definition: qgstaskmanager.cpp:118
QgsTask
Abstract base class for long running background tasks.
Definition: qgstaskmanager.h:53