QGIS API Documentation  3.21.0-Master (5b68dc587e)
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 #include "qgsrendercontext.h"
27 
28 class QgsExpression;
29 
32 
40 class CORE_EXPORT QgsRuleBasedRenderer : public QgsFeatureRenderer
41 {
42  public:
43  // TODO: use QVarLengthArray instead of QList
44 
46  {
47  FeatIsSelected = 1,
48  FeatDrawMarkers = 2
49  };
50 
56  {
57  FeatureToRender( const QgsFeature &_f, int _flags )
58  : feat( _f )
59  , flags( _flags )
60  {}
62  int flags; // selected and/or draw markers
63  };
64 
69  struct RenderJob
70  {
72  : ftr( _ftr )
73  , symbol( _s )
74  {}
75 
78 
80  QgsSymbol *symbol = nullptr;
81 
82  private:
83 #ifdef SIP_RUN
84  RenderJob &operator=( const RenderJob & );
85 #endif
86  };
87 
92  struct RenderLevel
93  {
94  explicit RenderLevel( int z )
95  : zIndex( z )
96  {}
97 
98  ~RenderLevel() { qDeleteAll( jobs ); }
99  int zIndex;
100 
102  QList<QgsRuleBasedRenderer::RenderJob *> jobs;
103 
105  {
106  zIndex = rh.zIndex;
107  qDeleteAll( jobs );
108  jobs.clear();
109  for ( auto it = rh.jobs.constBegin(); it != rh.jobs.constEnd(); ++it )
110  {
111  jobs << new RenderJob( *( *it ) );
112  }
113  return *this;
114  }
115 
117  : zIndex( other.zIndex ), jobs()
118  {
119  for ( auto it = other.jobs.constBegin(); it != other.jobs.constEnd(); ++it )
120  {
121  jobs << new RenderJob( * ( *it ) );
122  }
123  }
124 
125  };
126 
128  typedef QList<QgsRuleBasedRenderer::RenderLevel> RenderQueue;
129 
130  class Rule;
131  typedef QList<QgsRuleBasedRenderer::Rule *> RuleList;
132 
143  class CORE_EXPORT Rule
144  {
145  public:
148  {
149  Filtered = 0,
151  Rendered
152  };
153 
155  Rule( QgsSymbol *symbol SIP_TRANSFER, int maximumScale = 0, int minimumScale = 0, const QString &filterExp = QString(),
156  const QString &label = QString(), const QString &description = QString(), bool elseRule = false );
157  ~Rule();
158 
160  Rule( const Rule &rh ) = delete;
162  Rule &operator=( const Rule &rh ) = delete;
163 
169  QString dump( int indent = 0 ) const;
170 
175  QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
176 
180  bool needsGeometry() const;
181 
183  QgsSymbolList symbols( const QgsRenderContext &context = QgsRenderContext() ) const;
184 
186  QgsLegendSymbolList legendSymbolItems( int currentLevel = -1 ) const;
187 
195  bool isFilterOK( const QgsFeature &f, QgsRenderContext *context = nullptr ) const;
196 
204  bool isScaleOK( double scale ) const;
205 
206  QgsSymbol *symbol() { return mSymbol.get(); }
207  QString label() const { return mLabel; }
208  bool dependsOnScale() const { return mMaximumScale != 0 || mMinimumScale != 0; }
209 
218  double maximumScale() const { return mMaximumScale; }
219 
228  double minimumScale() const { return mMinimumScale; }
229 
234  QgsExpression *filter() const { return mFilter.get(); }
235 
240  QString filterExpression() const { return mFilterExp; }
241 
247  QString description() const { return mDescription; }
248 
254  bool active() const { return mIsActive; }
255 
260  QString ruleKey() const { return mRuleKey; }
261 
266  void setRuleKey( const QString &key ) { mRuleKey = key; }
267 
269  void setSymbol( QgsSymbol *sym SIP_TRANSFER );
270  void setLabel( const QString &label ) { mLabel = label; }
271 
279  void setMinimumScale( double scale ) { mMinimumScale = scale; }
280 
288  void setMaximumScale( double scale ) { mMaximumScale = scale; }
289 
295  void setFilterExpression( const QString &filterExp );
296 
302  void setDescription( const QString &description ) { mDescription = description; }
303 
308  void setActive( bool state ) { mIsActive = state; }
309 
312 
314  void toSld( QDomDocument &doc, QDomElement &element, QVariantMap props ) const;
315 
319  static QgsRuleBasedRenderer::Rule *createFromSld( QDomElement &element, QgsWkbTypes::GeometryType geomType ) SIP_FACTORY;
320 
321  QDomElement save( QDomDocument &doc, QgsSymbolMap &symbolMap ) const;
322 
324  bool startRender( QgsRenderContext &context, const QgsFields &fields, QString &filter );
325 
327  QSet<int> collectZLevels();
328 
333  void setNormZLevels( const QMap<int, int> &zLevelsToNormLevels ) SIP_SKIP;
334 
344  QgsRuleBasedRenderer::Rule::RenderResult renderFeature( QgsRuleBasedRenderer::FeatureToRender &featToRender, QgsRenderContext &context, QgsRuleBasedRenderer::RenderQueue &renderQueue );
345 
347  bool willRenderFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
348 
350  QgsSymbolList symbolsForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
351 
356  QSet< QString > legendKeysForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr );
357 
366  QgsRuleBasedRenderer::RuleList rulesForFeature( const QgsFeature &feature, QgsRenderContext *context = nullptr, bool onlyActive = true );
367 
373  void stopRender( QgsRenderContext &context );
374 
383  static QgsRuleBasedRenderer::Rule *create( QDomElement &ruleElem, QgsSymbolMap &symbolMap ) SIP_FACTORY;
384 
390  const QgsRuleBasedRenderer::RuleList &children() { return mChildren; }
391 
397  QgsRuleBasedRenderer::RuleList descendants() const;
398 
404  QgsRuleBasedRenderer::Rule *parent() { return mParent; }
405 
407  void appendChild( QgsRuleBasedRenderer::Rule *rule SIP_TRANSFER );
408 
410  void insertChild( int i, QgsRuleBasedRenderer::Rule *rule SIP_TRANSFER );
411 
413  void removeChild( QgsRuleBasedRenderer::Rule *rule );
414 
416  void removeChildAt( int i );
417 
420 
422  QgsRuleBasedRenderer::Rule *takeChildAt( int i ) SIP_TRANSFERBACK;
423 
428  QgsRuleBasedRenderer::Rule *findRuleByKey( const QString &key );
429 
435  void setIsElse( bool iselse );
436 
442  bool isElse() const { return mElseRule; }
443 
453  bool accept( QgsStyleEntityVisitorInterface *visitor ) const;
454 
455  protected:
456  void initFilter();
457 
458  private:
459 #ifdef SIP_RUN
460  Rule( const QgsRuleBasedRenderer::Rule &rh );
461 #endif
462 
463  Rule *mParent = nullptr; // parent rule (nullptr only for root rule)
464  std::unique_ptr< QgsSymbol > mSymbol;
465  double mMaximumScale = 0;
466  double mMinimumScale = 0;
467  QString mFilterExp, mLabel, mDescription;
468  bool mElseRule = false;
469  RuleList mChildren;
470  RuleList mElseRules;
471  bool mIsActive = true; // whether it is enabled or not
472 
473  QString mRuleKey; // string used for unique identification of rule within renderer
474 
475  // temporary
476  std::unique_ptr< QgsExpression > mFilter;
477  // temporary while rendering
478  QSet<int> mSymbolNormZLevels;
479  RuleList mActiveChildren;
480 
485  void updateElseRules();
486  };
487 
489 
491  static QgsFeatureRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
492 
496  QgsRuleBasedRenderer( QgsSymbol *defaultSymbol SIP_TRANSFER );
497 
498  ~QgsRuleBasedRenderer() override;
499 
501  QgsSymbol *symbolForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
502 
503  bool renderFeature( const QgsFeature &feature, QgsRenderContext &context, int layer = -1, bool selected = false, bool drawVertexMarker = false ) override SIP_THROW( QgsCsException );
504 
505  void startRender( QgsRenderContext &context, const QgsFields &fields ) override;
506 
507  void stopRender( QgsRenderContext &context ) override;
508 
509  QString filter( const QgsFields &fields = QgsFields() ) override;
510 
511  QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
512 
513  bool filterNeedsGeometry() const override;
514 
515  QgsRuleBasedRenderer *clone() const override SIP_FACTORY;
516 
517  void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props = QVariantMap() ) const override;
518 
519  static QgsFeatureRenderer *createFromSld( QDomElement &element, QgsWkbTypes::GeometryType geomType ) SIP_FACTORY;
520 
521  QgsSymbolList symbols( QgsRenderContext &context ) const override;
522 
523  QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) override;
524  bool legendSymbolItemsCheckable() const override;
525  bool legendSymbolItemChecked( const QString &key ) override;
526  void checkLegendSymbolItem( const QString &key, bool state = true ) override;
527 
528  void setLegendSymbolItem( const QString &key, QgsSymbol *symbol SIP_TRANSFER ) override;
529  QgsLegendSymbolList legendSymbolItems() const override;
530  QString dump() const override;
531  bool willRenderFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
532  QgsSymbolList symbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
533  QgsSymbolList originalSymbolsForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
534  QSet<QString> legendKeysForFeature( const QgsFeature &feature, QgsRenderContext &context ) const override;
535  QgsFeatureRenderer::Capabilities capabilities() override { return MoreSymbolsPerFeature | Filter | ScaleDependent; }
536  bool accept( QgsStyleEntityVisitorInterface *visitor ) const override;
537 
539 
540  QgsRuleBasedRenderer::Rule *rootRule() { return mRootRule; }
541 
543 
545  static void refineRuleCategories( QgsRuleBasedRenderer::Rule *initialRule, QgsCategorizedSymbolRenderer *r );
547  static void refineRuleRanges( QgsRuleBasedRenderer::Rule *initialRule, QgsGraduatedSymbolRenderer *r );
549  static void refineRuleScales( QgsRuleBasedRenderer::Rule *initialRule, QList<int> scales );
550 
559  static QgsRuleBasedRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer, QgsVectorLayer *layer = nullptr ) SIP_FACTORY;
560 
562  static void convertToDataDefinedSymbology( QgsSymbol *symbol, const QString &sizeScaleField, const QString &rotationField = QString() );
563 
564  protected:
566  Rule *mRootRule = nullptr;
567 
568  // temporary
569  RenderQueue mRenderQueue;
570  QList<FeatureToRender> mCurrentFeatures;
571 
572  QString mFilter;
573 
574  private:
575 #ifdef SIP_RUN
577  QgsRuleBasedRenderer &operator=( const QgsRuleBasedRenderer & );
578 #endif
579 };
580 
581 #endif // QGSRULEBASEDRENDERER_H
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:66
Class for parsing and evaluation of expressions (formerly called "search strings").
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
virtual QgsSymbolList symbols(QgsRenderContext &context) const
Returns list of symbols used by the renderer.
virtual QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const =0
To be overridden.
virtual QString dump() const
Returns debug information about this renderer.
@ ScaleDependent
Depends on scale if feature will be rendered (rule based )
Definition: qgsrenderer.h:266
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const =0
Returns a list of attributes required by this renderer.
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
virtual bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) SIP_THROW(QgsCsException)
Render a feature using this renderer in the given context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
Container of fields for a vector layer.
Definition: qgsfields.h:45
The class is used as a container of context for various read/write operations on other objects.
Contains information about the context of a rendering operation.
This class keeps data about a rules for rule-based renderer.
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
void setDescription(const QString &description)
Set a human readable description for this rule.
RenderResult
The result of rendering a rule.
@ Inactive
The rule is inactive.
double maximumScale() const
Returns the maximum map scale (i.e.
bool isElse() const
Check if this rule is an ELSE rule.
QgsRuleBasedRenderer::Rule * parent()
The parent rule.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
void setActive(bool state)
Sets if this rule is active.
Rule(const Rule &rh)=delete
Rules cannot be copied.
QgsExpression * filter() const
A filter that will check if this rule applies.
double minimumScale() const
Returns the minimum map scale (i.e.
QString description() const
A human readable description for this rule.
void setMinimumScale(double scale)
Sets the minimum map scale (i.e.
void setLabel(const QString &label)
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer)
QString filterExpression() const
A filter that will check if this rule applies.
bool active() const
Returns if this rule is active.
Rule & operator=(const Rule &rh)=delete
Rules cannot be copied.
Rule based renderer.
QList< QgsRuleBasedRenderer::RenderLevel > RenderQueue
Rendering queue: a list of rendering levels.
QgsRuleBasedRenderer::Rule * rootRule()
QList< QgsRuleBasedRenderer::Rule * > RuleList
An interface for classes which can visit style entity (e.g.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:38
Represents a vector layer which manages a vector based data sets.
Handles storage of information regarding WKB types and their properties.
Definition: qgswkbtypes.h:42
#define SIP_THROW(name)
Definition: qgis_sip.h:189
#define SIP_SKIP
Definition: qgis_sip.h:126
#define SIP_TRANSFER
Definition: qgis_sip.h:36
#define SIP_TRANSFERBACK
Definition: qgis_sip.h:48
#define SIP_FACTORY
Definition: qgis_sip.h:76
QList< QgsLegendSymbolItem > QgsLegendSymbolList
QMap< QString, QgsSymbol * > QgsSymbolMap
Definition: qgsrenderer.h:45
QList< QgsSymbol * > QgsSymbolList
Definition: qgsrenderer.h:44
Feature for rendering by a QgsRuleBasedRenderer.
FeatureToRender(const QgsFeature &_f, int _flags)
A QgsRuleBasedRenderer rendering job, consisting of a feature to be rendered with a particular symbol...
QgsRuleBasedRenderer::FeatureToRender & ftr
Feature to render.
RenderJob(QgsRuleBasedRenderer::FeatureToRender &_ftr, QgsSymbol *_s)
Render level: a list of jobs to be drawn at particular level for a QgsRuleBasedRenderer.
QList< QgsRuleBasedRenderer::RenderJob * > jobs
List of jobs to render, owned by this object.
RenderLevel(const QgsRuleBasedRenderer::RenderLevel &other)
QgsRuleBasedRenderer::RenderLevel & operator=(const QgsRuleBasedRenderer::RenderLevel &rh)