QGIS API Documentation  3.4.15-Madeira (e83d02e274)
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 QGSRULEBASEDRENDERERV2_H
17 #define QGSRULEBASEDRENDERERV2_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 (NULL 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 // QGSRULEBASEDRENDERERV2_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.
bool active() const
Returns if this rule is active.
const QgsRuleBasedRenderer::RuleList & children()
Returns all children rules of this rule.
This class keeps data about a rules for rule-based 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.
QgsExpression * filter() const
A filter that will check if this rule applies.
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)
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
QMap< QString, QString > QgsStringMap
Definition: qgis.h:577
double maximumScale() const
Returns the maximum map scale (i.e.
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
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.
#define SIP_FACTORY
Definition: qgis_sip.h:69
Render level: a list of jobs to be drawn at particular level for a QgsRuleBasedRenderer.
QString filterExpression() const
A filter that will check if this rule applies.
void setMaximumScale(double scale)
Sets the maximum map scale (i.e.
double minimumScale() const
Returns the minimum map scale (i.e.
bool isElse() const
Check if this rule is an ELSE rule.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:138
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
QString description() const
A human readable description for this rule.
#define SIP_THROW(name)
Definition: qgis_sip.h:177
RenderJob(QgsRuleBasedRenderer::FeatureToRender &_ftr, QgsSymbol *_s)
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
Feature for rendering by a QgsRuleBasedRenderer.
QgsRuleBasedRenderer::Rule * parent()
The parent rule.