QGIS API Documentation  3.25.0-Master (10b47c2603)
qgsrulebasedlabeling.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrulebasedlabeling.cpp
3  ---------------------
4  begin : September 2015
5  copyright : (C) 2015 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 #include "qgsrulebasedlabeling.h"
16 #include "qgssymbollayerutils.h"
17 #include "qgsstyleentityvisitor.h"
18 
20  : QgsVectorLayerLabelProvider( layer, QString(), withFeatureLoop, nullptr )
21 {
22  mRules.reset( rules.clone() );
23  mRules->rootRule()->createSubProviders( layer, mSubProviders, this );
24 }
25 
26 QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings )
27 {
28  return new QgsVectorLayerLabelProvider( layer, providerId, withFeatureLoop, settings );
29 }
30 
31 bool QgsRuleBasedLabelProvider::prepare( QgsRenderContext &context, QSet<QString> &attributeNames )
32 {
33  for ( QgsVectorLayerLabelProvider *provider : std::as_const( mSubProviders ) )
34  provider->setEngine( mEngine );
35 
36  // populate sub-providers
37  mRules->rootRule()->prepare( context, attributeNames, mSubProviders );
38  return true;
39 }
40 
41 QList<QgsLabelFeature *> QgsRuleBasedLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry, const QgsSymbol *symbol )
42 {
43  // will register the feature to relevant sub-providers
44  return std::get< 1 >( mRules->rootRule()->registerFeature( feature, context, mSubProviders, obstacleGeometry, symbol ) );
45 }
46 
47 QList<QgsAbstractLabelProvider *> QgsRuleBasedLabelProvider::subProviders()
48 {
49  QList<QgsAbstractLabelProvider *> lst;
50  for ( QgsVectorLayerLabelProvider *subprovider : std::as_const( mSubProviders ) )
51  lst << subprovider;
52  return lst;
53 }
54 
55 
57 
58 QgsRuleBasedLabeling::Rule::Rule( QgsPalLayerSettings *settings, double scaleMinDenom, double scaleMaxDenom, const QString &filterExp, const QString &description, bool elseRule )
59  : mSettings( settings )
60  , mMaximumScale( scaleMinDenom )
61  , mMinimumScale( scaleMaxDenom )
62  , mFilterExp( filterExp )
63  , mDescription( description )
64  , mElseRule( elseRule )
65 {
66  if ( mElseRule )
67  mFilterExp = QStringLiteral( "ELSE" );
68 
69  initFilter();
70 }
71 
73 {
74  qDeleteAll( mChildren );
75  // do NOT delete parent
76 }
77 
79 {
80  if ( mSettings.get() == settings )
81  return;
82 
83  mSettings.reset( settings );
84 }
85 
87 {
88  RuleList l;
89  for ( Rule *c : mChildren )
90  {
91  l += c;
92  l += c->descendants();
93  }
94  return l;
95 }
96 
97 void QgsRuleBasedLabeling::Rule::initFilter()
98 {
99  if ( mFilterExp.trimmed().compare( QLatin1String( "ELSE" ), Qt::CaseInsensitive ) == 0 )
100  {
101  mElseRule = true;
102  mFilter.reset( );
103  }
104  else if ( mFilterExp.trimmed().isEmpty() )
105  {
106  mElseRule = false;
107  mFilter.reset();
108  }
109  else
110  {
111  mElseRule = false;
112  mFilter = std::make_unique< QgsExpression >( mFilterExp );
113  }
114 }
115 
116 void QgsRuleBasedLabeling::Rule::updateElseRules()
117 {
118  mElseRules.clear();
119  for ( Rule *rule : std::as_const( mChildren ) )
120  {
121  if ( rule->isElse() )
122  mElseRules << rule;
123  }
124 }
125 
127 {
128  if ( mSettings && mSettings->format().containsAdvancedEffects() )
129  return true;
130 
131  for ( Rule *rule : std::as_const( mChildren ) )
132  {
133  if ( rule->requiresAdvancedEffects() )
134  return true;
135  }
136 
137  return false;
138 }
139 
141 {
142  // NOTE: if visitEnter returns false it means "don't visit the rule", not "abort all further visitations"
143  if ( mParent && !visitor->visitEnter( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::SymbolRule, mRuleKey, mDescription ) ) )
144  return true;
145 
146  if ( mSettings )
147  {
148  QgsStyleLabelSettingsEntity entity( *mSettings );
149  if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) ) )
150  return false;
151  }
152 
153  if ( !mChildren.empty() )
154  {
155  for ( const Rule *rule : mChildren )
156  {
157  if ( !rule->accept( visitor ) )
158  return false;
159  }
160  }
161 
162  if ( mParent && !visitor->visitExit( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::SymbolRule, mRuleKey, mDescription ) ) )
163  return false;
164 
165  return true;
166 }
167 
168 void QgsRuleBasedLabeling::Rule::subProviderIds( QStringList &list ) const
169 {
170  for ( const Rule *rule : std::as_const( mChildren ) )
171  {
172  if ( rule->settings() )
173  list << rule->ruleKey();
174 
175  rule->subProviderIds( list );
176  }
177 }
178 
179 
181 {
182  mChildren.append( rule );
183  rule->mParent = this;
184  updateElseRules();
185 }
186 
188 {
189  mChildren.insert( i, rule );
190  rule->mParent = this;
191  updateElseRules();
192 }
193 
195 {
196  delete mChildren.at( i );
197  mChildren.removeAt( i );
198  updateElseRules();
199 }
200 
202 {
203  // we could use a hash / map for search if this will be slow...
204 
205  if ( key == mRuleKey )
206  return this;
207 
208  for ( Rule *rule : mChildren )
209  {
210  const Rule *r = rule->findRuleByKey( key );
211  if ( r )
212  return r;
213  }
214  return nullptr;
215 }
216 
218 {
219  if ( key == mRuleKey )
220  return this;
221 
222  for ( Rule *rule : std::as_const( mChildren ) )
223  {
224  Rule *r = rule->findRuleByKey( key );
225  if ( r )
226  return r;
227  }
228  return nullptr;
229 }
230 
232 {
233  QgsPalLayerSettings *s = mSettings.get() ? new QgsPalLayerSettings( *mSettings ) : nullptr;
234  Rule *newrule = new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
235  newrule->setActive( mIsActive );
236  // clone children
237  for ( Rule *rule : mChildren )
238  newrule->appendChild( rule->clone() );
239  return newrule;
240 }
241 
243 {
244  QgsPalLayerSettings *settings = nullptr;
245  QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral( "settings" ) );
246  if ( !settingsElem.isNull() )
247  {
249  settings->readXml( settingsElem, context );
250  }
251 
252  QString filterExp = ruleElem.attribute( QStringLiteral( "filter" ) );
253  QString description = ruleElem.attribute( QStringLiteral( "description" ) );
254  int scaleMinDenom = ruleElem.attribute( QStringLiteral( "scalemindenom" ), QStringLiteral( "0" ) ).toInt();
255  int scaleMaxDenom = ruleElem.attribute( QStringLiteral( "scalemaxdenom" ), QStringLiteral( "0" ) ).toInt();
256  QString ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
257  Rule *rule = new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );
258 
259  if ( !ruleKey.isEmpty() )
260  rule->mRuleKey = ruleKey;
261 
262  rule->setActive( ruleElem.attribute( QStringLiteral( "active" ), QStringLiteral( "1" ) ).toInt() );
263 
264  QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( "rule" ) );
265  while ( !childRuleElem.isNull() )
266  {
267  Rule *childRule = create( childRuleElem, context );
268  if ( childRule )
269  {
270  rule->appendChild( childRule );
271  }
272  else
273  {
274  //QgsDebugMsg( QStringLiteral( "failed to init a child rule!" ) );
275  }
276  childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( "rule" ) );
277  }
278 
279  return rule;
280 }
281 
282 QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
283 {
284  QDomElement ruleElem = doc.createElement( QStringLiteral( "rule" ) );
285 
286  if ( mSettings )
287  {
288  ruleElem.appendChild( mSettings->writeXml( doc, context ) );
289  }
290  if ( !mFilterExp.isEmpty() )
291  ruleElem.setAttribute( QStringLiteral( "filter" ), mFilterExp );
292  if ( !qgsDoubleNear( mMaximumScale, 0 ) )
293  ruleElem.setAttribute( QStringLiteral( "scalemindenom" ), mMaximumScale );
294  if ( !qgsDoubleNear( mMinimumScale, 0 ) )
295  ruleElem.setAttribute( QStringLiteral( "scalemaxdenom" ), mMinimumScale );
296  if ( !mDescription.isEmpty() )
297  ruleElem.setAttribute( QStringLiteral( "description" ), mDescription );
298  if ( !mIsActive )
299  ruleElem.setAttribute( QStringLiteral( "active" ), 0 );
300  ruleElem.setAttribute( QStringLiteral( "key" ), mRuleKey );
301 
302  for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
303  {
304  Rule *rule = *it;
305  ruleElem.appendChild( rule->save( doc, context ) );
306  }
307  return ruleElem;
308 }
309 
311 {
312  if ( mSettings )
313  {
314  // add provider!
315  QgsVectorLayerLabelProvider *p = provider->createProvider( layer, mRuleKey, false, mSettings.get() );
316  delete subProviders.value( this, nullptr );
317  subProviders[this] = p;
318  }
319 
320  // call recursively
321  for ( Rule *rule : std::as_const( mChildren ) )
322  {
323  rule->createSubProviders( layer, subProviders, provider );
324  }
325 }
326 
328 {
329  if ( mSettings )
330  {
332  if ( !p->prepare( context, attributeNames ) )
333  {
334  subProviders.remove( this );
335  delete p;
336  }
337  }
338 
339  if ( mFilter )
340  {
341  attributeNames.unite( mFilter->referencedColumns() );
342  mFilter->prepare( &context.expressionContext() );
343  }
344 
345  // call recursively
346  for ( Rule *rule : std::as_const( mChildren ) )
347  {
348  rule->prepare( context, attributeNames, subProviders );
349  }
350 }
351 
352 std::tuple< QgsRuleBasedLabeling::Rule::RegisterResult, QList< QgsLabelFeature * > > QgsRuleBasedLabeling::Rule::registerFeature( const QgsFeature &feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry, const QgsSymbol *symbol )
353 {
354  QList< QgsLabelFeature * > labels;
355  if ( !isFilterOK( feature, context )
356  || !isScaleOK( context.rendererScale() ) )
357  {
358  return { Filtered, labels };
359  }
360 
361  bool registered = false;
362 
363  // do we have active subprovider for the rule?
364  if ( subProviders.contains( this ) && mIsActive )
365  {
366  labels.append( subProviders[this]->registerFeature( feature, context, obstacleGeometry, symbol ) );
367  registered = true;
368  }
369 
370  bool matchedAChild = false;
371 
372  // call recursively
373  for ( Rule *rule : std::as_const( mChildren ) )
374  {
375  // Don't process else rules yet
376  if ( !rule->isElse() )
377  {
378  RegisterResult res;
379  QList< QgsLabelFeature * > added;
380  std::tie( res, added ) = rule->registerFeature( feature, context, subProviders, obstacleGeometry );
381  labels.append( added );
382  // consider inactive items as "matched" so the else rule will ignore them
383  matchedAChild |= ( res == Registered || res == Inactive );
384  registered |= matchedAChild;
385  }
386  }
387 
388  // If none of the rules passed then we jump into the else rules and process them.
389  if ( !matchedAChild )
390  {
391  for ( Rule *rule : std::as_const( mElseRules ) )
392  {
393  RegisterResult res;
394  QList< QgsLabelFeature * > added;
395  std::tie( res, added ) = rule->registerFeature( feature, context, subProviders, obstacleGeometry, symbol ) ;
396  matchedAChild |= ( res == Registered || res == Inactive );
397  registered |= res != Filtered;
398  labels.append( added );
399  }
400  }
401 
402  if ( !mIsActive || ( matchedAChild && !registered ) )
403  return { Inactive, labels };
404  else if ( registered )
405  return { Registered, labels };
406  else
407  return { Filtered, labels };
408 }
409 
410 bool QgsRuleBasedLabeling::Rule::isFilterOK( const QgsFeature &f, QgsRenderContext &context ) const
411 {
412  if ( ! mFilter || mElseRule )
413  return true;
414 
415  context.expressionContext().setFeature( f );
416  QVariant res = mFilter->evaluate( &context.expressionContext() );
417  return res.toBool();
418 }
419 
420 bool QgsRuleBasedLabeling::Rule::isScaleOK( double scale ) const
421 {
422  if ( qgsDoubleNear( scale, 0.0 ) ) // so that we can count features in classes without scale context
423  return true;
424  if ( qgsDoubleNear( mMaximumScale, 0.0 ) && qgsDoubleNear( mMinimumScale, 0.0 ) )
425  return true;
426  if ( !qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
427  return false;
428  if ( !qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
429  return false;
430  return true;
431 }
432 
434 
436  : mRootRule( root )
437 {
438 }
439 
441 {
442  Rule *rootRule = mRootRule->clone();
443 
444  // normally with clone() the individual rules get new keys (UUID), but here we want to keep
445  // the tree of rules intact, so that other components that may use the rule keys work nicely (e.g. map themes)
446  rootRule->setRuleKey( mRootRule->ruleKey() );
447  RuleList origDescendants = mRootRule->descendants();
448  RuleList clonedDescendants = rootRule->descendants();
449  Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
450  for ( int i = 0; i < origDescendants.count(); ++i )
451  clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
452 
453  return new QgsRuleBasedLabeling( rootRule );
454 }
455 
457 {
458 }
459 
461 {
462  return mRootRule.get();
463 }
464 
466 {
467  return mRootRule.get();
468 }
469 
470 
471 QgsRuleBasedLabeling *QgsRuleBasedLabeling::create( const QDomElement &element, const QgsReadWriteContext &context )
472 {
473  QDomElement rulesElem = element.firstChildElement( QStringLiteral( "rules" ) );
474 
475  Rule *root = Rule::create( rulesElem, context );
476  if ( !root )
477  return nullptr;
478 
479  QgsRuleBasedLabeling *rl = new QgsRuleBasedLabeling( root );
480  return rl;
481 }
482 
484 {
485  return QStringLiteral( "rule-based" );
486 }
487 
488 QDomElement QgsRuleBasedLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
489 {
490  QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
491  elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "rule-based" ) );
492 
493  QDomElement rulesElem = mRootRule->save( doc, context );
494  rulesElem.setTagName( QStringLiteral( "rules" ) ); // instead of just "rule"
495  elem.appendChild( rulesElem );
496 
497  return elem;
498 }
499 
501 {
502  return new QgsRuleBasedLabelProvider( *this, layer, false );
503 }
504 
506 {
507  QStringList lst;
508  mRootRule->subProviderIds( lst );
509  return lst;
510 }
511 
512 QgsPalLayerSettings QgsRuleBasedLabeling::settings( const QString &providerId ) const
513 {
514  const Rule *rule = mRootRule->findRuleByKey( providerId );
515  if ( rule && rule->settings() )
516  return *rule->settings();
517 
518  return QgsPalLayerSettings();
519 }
520 
522 {
523  return mRootRule->accept( visitor );
524 }
525 
527 {
528  return mRootRule->requiresAdvancedEffects();
529 }
530 
531 void QgsRuleBasedLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
532 {
533  if ( settings )
534  {
535  Rule *rule = mRootRule->findRuleByKey( providerId );
536  if ( rule && rule->settings() )
537  rule->setSettings( settings );
538  }
539 }
540 
541 void QgsRuleBasedLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
542 {
543  if ( !mRootRule )
544  {
545  return;
546  }
547 
548  const QgsRuleBasedLabeling::RuleList rules = mRootRule->children();
549  for ( Rule *rule : rules )
550  {
551  QgsPalLayerSettings *settings = rule->settings();
552 
553  if ( settings && settings->drawLabels )
554  {
555  QDomDocument doc = parent.ownerDocument();
556 
557  QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
558  parent.appendChild( ruleElement );
559 
560  if ( !rule->filterExpression().isEmpty() )
561  {
562  QgsSymbolLayerUtils::createFunctionElement( doc, ruleElement, rule->filterExpression() );
563  }
564 
565  // scale dependencies, the actual behavior is that the PAL settings min/max and
566  // the rule min/max get intersected
567  QVariantMap localProps = QVariantMap( props );
568  QgsSymbolLayerUtils::mergeScaleDependencies( rule->maximumScale(), rule->minimumScale(), localProps );
569  if ( settings->scaleVisibility )
570  {
572  }
573  QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, localProps );
574 
576  }
577 
578  }
579 
580 }
QgsMapLayer * layer() const
Returns the associated layer, or nullptr if no layer is associated with the provider.
const QgsLabelingEngine * mEngine
Associated labeling engine.
QString providerId() const
Returns provider ID - useful in case there is more than one label provider within a layer (e....
virtual void writeTextSymbolizer(QDomNode &parent, QgsPalLayerSettings &settings, const QVariantMap &props) const
Writes a TextSymbolizer element contents based on the provided labeling settings.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:56
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:125
Contains settings for how a map layer will be labeled.
bool drawLabels
Whether to draw labels for this layer.
double minimumScale
The minimum map scale (i.e.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
double maximumScale
The maximum map scale (i.e.
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.
double rendererScale() const
Returns the renderer map scale.
QgsExpressionContext & expressionContext()
Gets the expression context.
Label provider for rule based labeling.
bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames) override
Prepare for registration of features.
std::unique_ptr< QgsRuleBasedLabeling > mRules
owned copy
QList< QgsLabelFeature * > registerFeature(const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr) override
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels.
QgsRuleBasedLabelProvider(const QgsRuleBasedLabeling &rules, QgsVectorLayer *layer, bool withFeatureLoop=true)
QgsRuleBasedLabeling::RuleToProviderMap mSubProviders
label providers are owned by labeling engine
virtual QgsVectorLayerLabelProvider * createProvider(QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings)
create a label provider
QList< QgsAbstractLabelProvider * > subProviders() override
Returns subproviders.
A child rule for QgsRuleBasedLabeling.
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based labeling)
QgsRuleBasedLabeling::Rule * clone() const
clone this rule, return new instance
void prepare(QgsRenderContext &context, QSet< QString > &attributeNames, RuleToProviderMap &subProviders)
call prepare() on sub-providers and populate attributeNames
QgsPalLayerSettings * settings() const
Returns the labeling settings.
std::tuple< RegisterResult, QList< QgsLabelFeature * > > registerFeature(const QgsFeature &feature, QgsRenderContext &context, RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Register individual features.
RegisterResult
The result of registering a rule.
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all child rules associated with the rule...
static QgsRuleBasedLabeling::Rule * create(const QDomElement &ruleElem, const QgsReadWriteContext &context)
Create a rule from an XML definition.
void subProviderIds(QStringList &list) const
append rule keys of descendants that contain valid settings (i.e.
bool requiresAdvancedEffects() const
Returns true if this rule or any of its children requires advanced composition effects to render.
void removeChildAt(int i)
delete child rule
void setActive(bool state)
Sets if this rule is active.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const
store labeling info to XML element
void setSettings(QgsPalLayerSettings *settings)
Sets new settings (or nullptr). Deletes old settings if any.
QgsRuleBasedLabeling::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
void createSubProviders(QgsVectorLayer *layer, RuleToProviderMap &subProviders, QgsRuleBasedLabelProvider *provider)
add providers
Rule(QgsPalLayerSettings *settings, double maximumScale=0, double minimumScale=0, const QString &filterExp=QString(), const QString &description=QString(), bool elseRule=false)
takes ownership of settings, settings may be nullptr
void insertChild(int i, QgsRuleBasedLabeling::Rule *rule)
add child rule, take ownership, sets this as parent
const QgsRuleBasedLabeling::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
void appendChild(QgsRuleBasedLabeling::Rule *rule)
add child rule, take ownership, sets this as parent
Rule based labeling for a vector layer.
QList< QgsRuleBasedLabeling::Rule * > RuleList
std::unique_ptr< Rule > mRootRule
void toSld(QDomNode &parent, const QVariantMap &props) const override
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
QStringList subProviders() const override
Gets list of sub-providers within the layer's labeling.
QgsRuleBasedLabeling(QgsRuleBasedLabeling::Rule *root)
Constructs the labeling from given tree of rules (takes ownership)
QgsVectorLayerLabelProvider * provider(QgsVectorLayer *layer) const override
static QgsRuleBasedLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString()) override
Set pal settings for a specific provider (takes ownership).
QgsPalLayerSettings settings(const QString &providerId=QString()) const override
Gets associated label settings.
QMap< QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider * > RuleToProviderMap
QString type() const override
Unique type string of the labeling configuration implementation.
QgsRuleBasedLabeling * clone() const override
Returns a new copy of the object.
QgsRuleBasedLabeling::Rule * rootRule()
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the labeling...
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Returns labeling configuration as XML element.
bool requiresAdvancedEffects() const override
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
An interface for classes which can visit style entity (e.g.
@ SymbolRule
Rule based symbology or label child rule.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A label settings entity for QgsStyle databases.
Definition: qgsstyle.h:1435
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QVariantMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
static void mergeScaleDependencies(double mScaleMinDenom, double mScaleMaxDenom, QVariantMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
QgsVectorLayerLabelProvider(QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings, const QString &layerName=QString())
Convenience constructor to initialize the provider from given vector layer.
const QgsPalLayerSettings & settings() const
Returns the layer's settings.
Represents a vector layer which manages a vector based data sets.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2062
Contains information relating to a node (i.e.
Contains information relating to the style entity currently being visited.