1 /***************************************************************************
2     qgsvectorlayerfeaturecounter.h
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 #ifndef QGSVECTORLAYERFEATURECOUNTER_H
16 #define QGSVECTORLAYERFEATURECOUNTER_H
17 
18 #include "qgsvectorlayerfeatureiterator.h"
19 #include "qgsrenderer.h"
20 #include "qgstaskmanager.h"
21 #include "qgsfeatureid.h"
22 
23 /**
24  * \ingroup core
25  *
26  * \brief Counts the features in a QgsVectorLayer in task.
27  * You should most likely not use this directly and instead call
28  * QgsVectorLayer::countSymbolFeatures() and connect to the signal
29  * QgsVectorLayer::symbolFeatureCountMapChanged().
30  *
31  * \since QGIS 3.0
32  */
33 class CORE_EXPORT QgsVectorLayerFeatureCounter : public QgsTask
34 {
35     Q_OBJECT
36 
37   public:
38 
39     /**
40      * Create a new feature counter for \a layer.
41      * \param layer Target QgsVectorLayer to perform counting on.
42      * \param context Specific QgsExpressionContext to use during the rendering step.
43      * \param storeSymbolFids If TRUE will store the feature ids (fids), otherwise will only count the number of features per symbol. Default FALSE.
44      */
45     QgsVectorLayerFeatureCounter( QgsVectorLayer *layer, const QgsExpressionContext &context = QgsExpressionContext(), bool storeSymbolFids = false );
46     ~QgsVectorLayerFeatureCounter() override;
47 
48     /**
49      * Calculates the feature count and Ids per symbol
50      */
51     bool run() override;
52 
53     void cancel() override;
54 
55     /**
56      * Returns the count for each symbol. Only valid after the symbolsCounted()
57      * signal has been emitted.
58      *
59      * \note Not available in Python bindings.
60      */
61     QHash<QString, long long> symbolFeatureCountMap() const SIP_SKIP;
62 
63     /**
64      * Returns the feature count for a particular \a legendKey.
65      * If the key has not been found, -1 will be returned.
66      */
67     long long featureCount( const QString &legendKey ) const;
68 
69     /**
70      * Returns the QgsFeatureIds for each symbol. Only valid after the symbolsCounted()
71      * signal has been emitted.
72      *
73      * \see symbolFeatureCountMap
74      * \note Not available in Python bindings.
75      * \since QGIS 3.10
76      */
77     QHash<QString, QgsFeatureIds> symbolFeatureIdMap() const SIP_SKIP;
78 
79     /**
80      * Returns the feature Ids for a particular \a legendKey.
81      * If the key has not been found an empty QSet will be returned.
82      *
83      * \since QGIS 3.10
84      */
85     QgsFeatureIds featureIds( const QString &symbolkey ) const;
86 
87   signals:
88 
89     /**
90      * Emitted when the symbols have been counted.
91      */
92     void symbolsCounted();
93 
94   private:
95     std::unique_ptr<QgsVectorLayerFeatureSource> mSource;
96     std::unique_ptr<QgsFeatureRenderer> mRenderer;
97     QgsExpressionContext mExpressionContext;
98     QHash<QString, long long> mSymbolFeatureCountMap;
99     QHash<QString, QgsFeatureIds> mSymbolFeatureIdMap;
100     std::unique_ptr< QgsFeedback > mFeedback;
101     bool mWithFids = false;
102     long mFeatureCount = 0;
103 
104 };
105 
106 #endif // QGSVECTORLAYERFEATURECOUNTER_H
107