QGIS API Documentation  3.8.0-Zanzibar (11aff65)
qgsrulebasedrenderer.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrulebasedrenderer.h - Rule-based renderer (symbology)
3  ---------------------
4  begin : May 2010
5  copyright : (C) 2010 by Martin Dobias
6  email : wonder dot sk at gmail dot com
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 
16 #ifndef QGSRULEBASEDRENDERER_H
17 #define QGSRULEBASEDRENDERER_H
18 
19 #include "qgis_core.h"
20 #include "qgis_sip.h"
21 #include "qgsfields.h"
22 #include "qgsfeature.h"
23 #include "qgis.h"
24 
25 #include "qgsrenderer.h"
26 
27 class QgsExpression;
28 
31 
37 class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer
38 {
39  public:
40  // TODO: use QVarLengthArray instead of QList
41 
43  {
44  FeatIsSelected = 1,
45  FeatDrawMarkers = 2
46  };
47 
53  {
54  FeatureToRender( const QgsFeature &_f, int _flags )
55  : feat( _f )
56  , flags( _flags )
57  {}
59  int flags; // selected and/or draw markers
60  };
61 
66  struct RenderJob
67  {
69  : ftr( _ftr )
70  , symbol( _s )
71  {}
72 
75 
77  QgsSymbol *symbol = nullptr;
78  };
79 
84  struct RenderLevel
85  {
86  explicit RenderLevel( int z ): zIndex( z ) {}
87  ~RenderLevel() { qDeleteAll( jobs ); }
88  int zIndex;
89 
91  QList<QgsRuleBasedRenderer::RenderJob *> jobs;
92 
94  {
95  zIndex = rh.zIndex;
96  qDeleteAll( jobs );
97  jobs.clear();
98  for ( RenderJob *job : qgis::as_const( rh.jobs ) )
99  {
100  jobs << new RenderJob( *job );
101  }
102  return *this;
103  }
104 
106  : zIndex( other.zIndex )
107  {
108  for ( RenderJob *job : qgis::as_const( other.jobs ) )
109  {
110  jobs << new RenderJob( *job );
111  }
112  }
113 
114  };
115 
117  typedef QList<QgsRuleBasedRenderer::RenderLevel> RenderQueue;
118 
119  class Rule;
120  typedef QList<QgsRuleBasedRenderer::Rule *> RuleList;
121 
131  class CORE_EXPORT Rule
132  {
133  public:
136  {
137  Filtered = 0,
139  Rendered
140  };
141 
143  Rule( QgsSymbol *symbol SIP_TRANSFER, int maximumScale = 0, int minimumScale = 0, const QString &filterExp = QString(),
144  const QString &label = QString(), const QString &description = QString(), bool elseRule = false );
145  ~Rule();
146 
148  Rule( const Rule &rh ) = delete;
150  Rule &operator=( const Rule &rh ) = delete;
151 
157  QString dump( int indent = 0 ) const;
158 
163  QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
164 
168  bool needsGeometry() const;
169 
171  QgsSymbolList symbols( const QgsRenderContext &context = QgsRenderContext() ) const;
172 
174  QgsLegendSymbolList legendSymbolItems( int currentLevel = -1 ) const;
175 
183  bool isFilterOK( const QgsFeature &f, QgsRenderContext *context = nullptr ) const;
184 
192  bool isScaleOK( double scale ) const;
193 
194  QgsSymbol *symbol() { return mSymbol.get(); }
195  QString label() const { return mLabel; }
196  bool dependsOnScale() const { return mMaximumScale != 0 || mMinimumScale != 0; }
197 
206  double maximumScale() const { return mMaximumScale; }
207 
216  double minimumScale() const { return mMinimumScale; }
217 
222  QgsExpression *filter() const { return mFilter.get(); }
223 
228  QString filterExpression() const { return mFilterExp; }
229 
235  QString description() const { return mDescription; }
236 
242  bool active() const { return mIsActive; }
243 
248  QString ruleKey() const { return mRuleKey; }
249 
254  void setRuleKey( const QString &key ) { mRuleKey = key; }
255 
257  void setSymbol( QgsSymbol *sym SIP_TRANSFER );
258  void setLabel( const QString &label ) { mLabel = label; }
259 
267  void setMinimumScale( double scale ) { mMinimumScale = scale; }
268 
276  void setMaximumScale( double scale ) { mMaximumScale = scale; }
277 
283  void setFilterExpression( const QString &filterExp );
284 
290  void setDescription( const QString &description ) { mDescription = description; }
291 
296  void setActive( bool state ) { mIsActive = state; }
297 
300 
301  void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props ) const;
302 
306  static QgsRuleBasedRenderer::Rule *createFromSld( QDomElement &element, QgsWkbTypes::GeometryType geomType ) SIP_FACTORY;
307 
308  QDomElement save( QDomDocument &doc, QgsSymbolMap &symbolMap ) const;
309 
311  bool startRender( QgsRenderContext &context, const QgsFields &fields, QString &filter );
312 
314  QSet<int> collectZLevels();
315 
320  void setNormZLevels( const QMap<int, int> &zLevelsToNormLevels ) SIP_SKIP;
321 
332 
334  bool willRenderFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
335 
337  QgsSymbolList symbolsForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
338 
343  QSet< QString > legendKeysForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
344 
353  QgsRuleBasedRenderer::RuleList rulesForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr, bool onlyActive = true );
354 
360  void stopRender( QgsRenderContext &context );
361 
370  static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap ) SIP_FACTORY;
371 
377  const QgsRuleBasedRenderer::RuleList &children() { return mChildren; }
378 
384  QgsRuleBasedRenderer::RuleList descendants() const;
385 
391  QgsRuleBasedRenderer::Rule *parent() { return mParent; }
392 
394  void appendChild( QgsRuleBasedRenderer::Rule *rule SIP_TRANSFER );
395 
397  void insertChild( int i, QgsRuleBasedRenderer::Rule *rule SIP_TRANSFER );
398 
400  void removeChild( QgsRuleBasedRenderer::Rule *rule );
401 
403  void removeChildAt( int i );
404 
407 
409  QgsRuleBasedRenderer::Rule *takeChildAt( int i ) SIP_TRANSFERBACK;
410 
415  QgsRuleBasedRenderer::Rule *findRuleByKey( const QString &key );
416 
422  void setIsElse( bool iselse );
423 
429  bool isElse() const { return mElseRule; }
430 
431  protected:
432  void initFilter();
433 
434  private:
435 #ifdef SIP_RUN
436  Rule( const QgsRuleBasedRenderer::Rule &rh );
437 #endif
438 
439  Rule *mParent = nullptr; // parent rule (nullptr only for root rule)
440  std::unique_ptr< QgsSymbol > mSymbol;
441  double mMaximumScale = 0;
442  double mMinimumScale = 0;
443  QString mFilterExp, mLabel, mDescription;
444  bool mElseRule = false;
445  RuleList mChildren;
446  RuleList mElseRules;
447  bool mIsActive = true; // whether it is enabled or not
448 
449  QString mRuleKey; // string used for unique identification of rule within renderer
450 
451  // temporary
452  std::unique_ptr< QgsExpression > mFilter;
453  // temporary while rendering
454  QSet<int> mSymbolNormZLevels;
455  RuleList mActiveChildren;
456 
461  void updateElseRules();
462  };
463 
465 
467  static QgsFeatureRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
468 
470  QgsRuleBasedRenderer( QgsRuleBasedRenderer::Rule *root SIP_TRANSFER );
472  QgsRuleBasedRenderer( QgsSymbol *defaultSymbol SIP_TRANSFER );
473 
474  ~QgsRuleBasedRenderer() override;
475 
477  QgsSymbol *symbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
478 
479  bool renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false ) override SIP_THROW( QgsCsException );
480 
481  void startRender( QgsRenderContext &context, const QgsFields &fields ) override;
482 
483  void stopRender( QgsRenderContext &context ) override;
484 
485  QString filter( const QgsFields &fields = QgsFields() ) override;
486 
487  QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
488 
489  bool filterNeedsGeometry() const override;
490 
491  QgsRuleBasedRenderer *clone() const override SIP_FACTORY;
492 
493  void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props = QgsStringMap() ) const override;
494 
495  static QgsFeatureRenderer *createFromSld( QDomElement &element, QgsWkbTypes::GeometryType geomType ) SIP_FACTORY;
496 
497  QgsSymbolList symbols( QgsRenderContext &context ) const override;
498 
499  QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) override;
500  bool legendSymbolItemsCheckable() const override;
501  bool legendSymbolItemChecked( const QString &key ) override;
502  void checkLegendSymbolItem( const QString &key, bool state = true ) override;
503 
504  void setLegendSymbolItem( const QString &key, QgsSymbol *symbol SIP_TRANSFER ) override;
505  QgsLegendSymbolList legendSymbolItems() const override;
506  QString dump() const override;
507  bool willRenderFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
508  QgsSymbolList symbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
509  QgsSymbolList originalSymbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
510  QSet<QString> legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
511  QgsFeatureRenderer::Capabilities capabilities() override { return MoreSymbolsPerFeature | Filter | ScaleDependent; }
512 
514 
515  QgsRuleBasedRenderer::Rule *rootRule() { return mRootRule; }
516 
518 
520  static void refineRuleCategories( QgsRuleBasedRenderer::Rule *initialRule, QgsCategorizedSymbolRenderer *r );
522  static void refineRuleRanges( QgsRuleBasedRenderer::Rule *initialRule, QgsGraduatedSymbolRenderer *r );
524  static void refineRuleScales( QgsRuleBasedRenderer::Rule *initialRule, QList<int> scales );
525 
531  static QgsRuleBasedRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer ) SIP_FACTORY;
532 
534  static void convertToDataDefinedSymbology( QgsSymbol *symbol, const QString &sizeScaleField, const QString &rotationField = QString() );
535 
536  protected:
538  Rule *mRootRule = nullptr;
539 
540  // temporary
541  RenderQueue mRenderQueue;
542  QList<FeatureToRender> mCurrentFeatures;
543 
544  QString mFilter;
545 
546  private:
547 #ifdef SIP_RUN
549  QgsRuleBasedRenderer &operator=( const QgsRuleBasedRenderer & );
550 #endif
551 };
552 
553 #endif // QGSRULEBASEDRENDERER_H
Class for parsing and evaluation of expressions (formerly called "search strings").
The class is used as a container of context for various read/write operations on other objects...
RenderLevel(const QgsRuleBasedRenderer::RenderLevel &other)
void setDescription(const QString &description)
Set a human readable description for this rule.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:61
QList< QgsRuleBasedRenderer::RenderLevel > RenderQueue
Rendering queue: a list of rendering levels.
const QgsRuleBasedRenderer::RuleList & children()
Returns all children rules of this rule.
This class keeps data about a rules for rule-based renderer.
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer) ...
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
QgsRuleBasedRenderer::FeatureToRender & ftr
Feature to render.
Container of fields for a vector layer.
Definition: qgsfields.h:42
QList< FeatureToRender > mCurrentFeatures
QgsRuleBasedRenderer::RenderLevel & operator=(const QgsRuleBasedRenderer::RenderLevel &rh)
double maximumScale() const
Returns the maximum map scale (i.e.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:55
#define SIP_TRANSFERBACK
Definition: qgis_sip.h:41
QString description() const
A human readable description for this rule.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:587
bool isElse() const
Check if this rule is an ELSE rule.
bool active() const
Returns if this rule is active.
QList< QgsRuleBasedRenderer::Rule * > RuleList
RenderResult
The result of rendering a rule.
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:43
#define SIP_SKIP
Definition: qgis_sip.h:119
A QgsRuleBasedRenderer rendering job, consisting of a feature to be rendered with a particular symbol...
#define SIP_TRANSFER
Definition: qgis_sip.h:36
QgsExpression * filter() const
A filter that will check if this rule applies.
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
QgsRuleBasedRenderer::Rule * rootRule()
QList< QgsRuleBasedRenderer::RenderJob * > jobs
List of jobs to render, owned by this object.
FeatureToRender(const QgsFeature &_f, int _flags)
QgsFeatureRenderer::Capabilities capabilities() override
Returns details about internals of this renderer.
double minimumScale() const
Returns the minimum map scale (i.e.
#define SIP_FACTORY
Definition: qgis_sip.h:69
Render level: a list of jobs to be drawn at particular level for a QgsRuleBasedRenderer.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
void setActive(bool state)
Sets if this rule is active.
Contains information about the context of a rendering operation.
void setLabel(const QString &label)
QMap< QString, QgsSymbol *> QgsSymbolMap
Definition: qgsrenderer.h:44
#define SIP_THROW(name)
Definition: qgis_sip.h:177
RenderJob(QgsRuleBasedRenderer::FeatureToRender &_ftr, QgsSymbol *_s)
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Feature for rendering by a QgsRuleBasedRenderer.
QString filterExpression() const
A filter that will check if this rule applies.
QgsRuleBasedRenderer::Rule * parent()
The parent rule.