/
qgscategorizedsymbolrenderer.h
322 lines (265 loc) · 12.3 KB
/
qgscategorizedsymbolrenderer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/***************************************************************************
qgscategorizedsymbolrenderer.h
---------------------
begin : November 2009
copyright : (C) 2009 by Martin Dobias
email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCATEGORIZEDSYMBOLRENDERER_H
#define QGSCATEGORIZEDSYMBOLRENDERER_H
#include "qgis_core.h"
#include "qgis.h"
#include "qgssymbol.h"
#include "qgsrenderer.h"
#include "qgsexpression.h"
#include "qgscolorramp.h"
#include "qgsdatadefinedsizelegend.h"
#include <QHash>
class QgsVectorLayer;
class QgsStyle;
/**
* \ingroup core
* \brief categorized renderer
*/
class CORE_EXPORT QgsRendererCategory
{
public:
/**
* Constructor for QgsRendererCategory.
*/
QgsRendererCategory() = default;
//! takes ownership of symbol
QgsRendererCategory( const QVariant &value, QgsSymbol *symbol SIP_TRANSFER, const QString &label, bool render = true );
//! copy constructor
QgsRendererCategory( const QgsRendererCategory &cat );
QgsRendererCategory &operator=( QgsRendererCategory cat );
QVariant value() const;
QgsSymbol *symbol() const;
QString label() const;
void setValue( const QVariant &value );
void setSymbol( QgsSymbol *s SIP_TRANSFER );
void setLabel( const QString &label );
/**
* Returns true if the category is currently enabled and should be rendered.
* \see setRenderState()
* \since QGIS 2.5
*/
bool renderState() const;
/**
* Sets whether the category is currently enabled and should be rendered.
* \see renderState()
* \since QGIS 2.5
*/
void setRenderState( bool render );
// debugging
QString dump() const;
void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const;
protected:
QVariant mValue;
std::unique_ptr<QgsSymbol> mSymbol;
QString mLabel;
bool mRender = true;
void swap( QgsRendererCategory &other );
};
typedef QList<QgsRendererCategory> QgsCategoryList;
/**
* \ingroup core
* \class QgsCategorizedSymbolRenderer
*/
class CORE_EXPORT QgsCategorizedSymbolRenderer : public QgsFeatureRenderer
{
public:
QgsCategorizedSymbolRenderer( const QString &attrName = QString(), const QgsCategoryList &categories = QgsCategoryList() );
QgsSymbol *symbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
QgsSymbol *originalSymbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
void startRender( QgsRenderContext &context, const QgsFields &fields ) override;
void stopRender( QgsRenderContext &context ) override;
QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
bool filterNeedsGeometry() const override;
QString dump() const override;
QgsCategorizedSymbolRenderer *clone() const override SIP_FACTORY;
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props = QgsStringMap() ) const override;
QgsFeatureRenderer::Capabilities capabilities() override { return SymbolLevels | Filter; }
QString filter( const QgsFields &fields = QgsFields() ) override;
QgsSymbolList symbols( QgsRenderContext &context ) const override;
/**
* Update all the symbols but leave categories and colors. This method also sets the source
* symbol for the renderer.
* \param sym source symbol to use for categories. Ownership is not transferred.
* \see setSourceSymbol()
*/
void updateSymbols( QgsSymbol *sym );
const QgsCategoryList &categories() const { return mCategories; }
//! Returns index of category with specified value (-1 if not found)
int categoryIndexForValue( const QVariant &val );
/**
* Returns index of category with specified label (-1 if not found or not unique)
* \since QGIS 2.5
*/
int categoryIndexForLabel( const QString &val );
bool updateCategoryValue( int catIndex, const QVariant &value );
bool updateCategorySymbol( int catIndex, QgsSymbol *symbol SIP_TRANSFER );
bool updateCategoryLabel( int catIndex, const QString &label );
//! \since QGIS 2.5
bool updateCategoryRenderState( int catIndex, bool render );
void addCategory( const QgsRendererCategory &category );
bool deleteCategory( int catIndex );
void deleteAllCategories();
//! Moves the category at index position from to index position to.
void moveCategory( int from, int to );
void sortByValue( Qt::SortOrder order = Qt::AscendingOrder );
void sortByLabel( Qt::SortOrder order = Qt::AscendingOrder );
QString classAttribute() const { return mAttrName; }
void setClassAttribute( const QString &attr ) { mAttrName = attr; }
//! create renderer from XML element
static QgsFeatureRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) override;
QgsLegendSymbolList legendSymbolItems() const override;
QSet< QString > legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
/**
* Returns the renderer's source symbol, which is the base symbol used for the each categories' symbol before applying
* the categories' color.
* \see setSourceSymbol()
* \see sourceColorRamp()
*/
QgsSymbol *sourceSymbol();
/**
* Sets the source symbol for the renderer, which is the base symbol used for the each categories' symbol before applying
* the categories' color.
* \param sym source symbol, ownership is transferred to the renderer
* \see sourceSymbol()
* \see setSourceColorRamp()
*/
void setSourceSymbol( QgsSymbol *sym SIP_TRANSFER );
/**
* Returns the source color ramp, from which each categories' color is derived.
* \see setSourceColorRamp()
* \see sourceSymbol()
*/
QgsColorRamp *sourceColorRamp();
/**
* Sets the source color ramp.
* \param ramp color ramp. Ownership is transferred to the renderer
* \see sourceColorRamp()
* \see setSourceSymbol()
*/
void setSourceColorRamp( QgsColorRamp *ramp SIP_TRANSFER );
/**
* Update the color ramp used and all symbols colors.
* \param ramp color ramp. Ownership is transferred to the renderer
* \since QGIS 2.5
*/
void updateColorRamp( QgsColorRamp *ramp SIP_TRANSFER );
bool legendSymbolItemsCheckable() const override;
bool legendSymbolItemChecked( const QString &key ) override;
void setLegendSymbolItem( const QString &key, QgsSymbol *symbol SIP_TRANSFER ) override;
void checkLegendSymbolItem( const QString &key, bool state = true ) override;
QString legendClassificationAttribute() const override { return classAttribute(); }
/**
* creates a QgsCategorizedSymbolRenderer from an existing renderer.
* \returns a new renderer if the conversion was possible, otherwise 0.
* \since QGIS 2.5
*/
static QgsCategorizedSymbolRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer ) SIP_FACTORY;
/**
* Configures appearance of legend when renderer is configured to use data-defined size for marker symbols.
* This allows configuring for which values (symbol sizes) should be shown in the legend, whether to display
* different symbol sizes collapsed in one legend node or separated across multiple legend nodes etc.
*
* When renderer does not use data-defined size or does not use marker symbols, these settings will be ignored.
* Takes ownership of the passed settings objects. Null pointer is a valid input that disables data-defined
* size legend.
* \since QGIS 3.0
*/
void setDataDefinedSizeLegend( QgsDataDefinedSizeLegend *settings SIP_TRANSFER );
/**
* Returns configuration of appearance of legend when using data-defined size for marker symbols.
* Will return null if the functionality is disabled.
* \since QGIS 3.0
*/
QgsDataDefinedSizeLegend *dataDefinedSizeLegend() const;
/**
* Replaces category symbols with the symbols from a \a style that have a matching
* name and symbol \a type.
*
* The \a unmatchedCategories list will be filled with all existing categories which could not be matched
* to a symbol in \a style.
*
* The \a unmatchedSymbols list will be filled with all symbol names from \a style which were not matched
* to an existing category.
*
* If \a caseSensitive is false, then a case-insensitive match will be performed. If \a useTolerantMatch
* is true, then non-alphanumeric characters in style and category names will be ignored during the match.
*
* Returns the count of symbols matched.
*
* \since QGIS 3.4
*/
int matchToSymbols( QgsStyle *style, QgsSymbol::SymbolType type,
QVariantList &unmatchedCategories SIP_OUT, QStringList &unmatchedSymbols SIP_OUT, bool caseSensitive = true, bool useTolerantMatch = false );
/**
* Create categories for a list of \a values.
* The returned symbols in the category list will be a modification of \a symbol.
*
* If \a layer and \a fieldName are specified it will try to find nicer values
* to represent the description for the categories based on the respective field
* configuration.
*
* \since QGIS 3.6
*/
static QgsCategoryList createCategories( const QVariantList &values, const QgsSymbol *symbol, QgsVectorLayer *layer = nullptr, const QString &fieldName = QString() );
protected:
QString mAttrName;
QgsCategoryList mCategories;
std::unique_ptr<QgsSymbol> mSourceSymbol;
std::unique_ptr<QgsColorRamp> mSourceColorRamp;
std::unique_ptr<QgsExpression> mExpression;
std::unique_ptr<QgsDataDefinedSizeLegend> mDataDefinedSizeLegend;
//! attribute index (derived from attribute name in startRender)
int mAttrNum = -1;
//! hashtable for faster access to symbols
QHash<QString, QgsSymbol *> mSymbolHash;
bool mCounting = false;
void rebuildHash();
/**
* \deprecated No longer used, will be removed in QGIS 4.0
*/
Q_DECL_DEPRECATED QgsSymbol *skipRender() SIP_DEPRECATED;
/**
* Returns the matching symbol corresponding to an attribute \a value.
* \deprecated use variant which takes a second bool argument instead.
*/
Q_DECL_DEPRECATED QgsSymbol *symbolForValue( const QVariant &value ) const SIP_DEPRECATED;
// TODO QGIS 4.0 - rename Python method to symbolForValue
/**
* Returns the matching symbol corresponding to an attribute \a value.
*
* Will return nullptr if no matching symbol was found for \a value, or
* if the category corresponding to \a value is currently disabled (see QgsRendererCategory::renderState()).
*
* If \a foundMatchingSymbol is specified then it will be set to true if
* a matching category was found. This can be used to differentiate between
* a nullptr returned as a result of no matching category vs a nullptr as a result
* of disabled categories.
*
* \note available in Python bindings as symbolForValue2
*/
QgsSymbol *symbolForValue( const QVariant &value, bool &foundMatchingSymbol SIP_OUT ) const SIP_PYNAME( symbolForValue2 );
private:
#ifdef SIP_RUN
QgsCategorizedSymbolRenderer( const QgsCategorizedSymbolRenderer & );
QgsCategorizedSymbolRenderer &operator=( const QgsCategorizedSymbolRenderer & );
#endif
//! Returns calculated classification value for a feature
QVariant valueForFeature( const QgsFeature &feature, QgsRenderContext &context ) const;
//! Returns list of legend symbol items from individual categories
QgsLegendSymbolList baseLegendSymbolItems() const;
};
#endif // QGSCATEGORIZEDSYMBOLRENDERER_H