QGIS API Documentation 3.41.0-Master (88383c3d16f)
Loading...
Searching...
No Matches
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 ***************************************************************************/
16#include "qgsscaleutils.h"
17#include "qgssymbollayerutils.h"
19
21 : QgsVectorLayerLabelProvider( layer, QString(), withFeatureLoop, nullptr )
22{
23 mRules.reset( rules.clone() );
24 mRules->rootRule()->createSubProviders( layer, mSubProviders, this );
25}
26
27QgsVectorLayerLabelProvider *QgsRuleBasedLabelProvider::createProvider( QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings )
28{
29 return new QgsVectorLayerLabelProvider( layer, providerId, withFeatureLoop, settings );
30}
31
32bool QgsRuleBasedLabelProvider::prepare( QgsRenderContext &context, QSet<QString> &attributeNames )
33{
34 for ( const auto &subprovider : std::as_const( mSubProviders ) )
35 {
36 subprovider.second->setEngine( mEngine );
37 }
38
39 // populate sub-providers
40 mRules->rootRule()->prepare( context, attributeNames, mSubProviders );
41 return true;
42}
43
44QList<QgsLabelFeature *> QgsRuleBasedLabelProvider::registerFeature( const QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry, const QgsSymbol *symbol )
45{
46 // will register the feature to relevant sub-providers
47 return std::get< 1 >( mRules->rootRule()->registerFeature( feature, context, mSubProviders, obstacleGeometry, symbol ) );
48}
49
50QList<QgsAbstractLabelProvider *> QgsRuleBasedLabelProvider::subProviders()
51{
52 QList<QgsAbstractLabelProvider *> lst;
53 for ( const auto &subprovider : std::as_const( mSubProviders ) )
54 {
55 lst << subprovider.second;
56 }
57 return lst;
58}
59
60
62
63QgsRuleBasedLabeling::Rule::Rule( QgsPalLayerSettings *settings, double scaleMinDenom, double scaleMaxDenom, const QString &filterExp, const QString &description, bool elseRule )
64 : mSettings( settings )
65 , mMaximumScale( scaleMinDenom )
66 , mMinimumScale( scaleMaxDenom )
67 , mFilterExp( filterExp )
68 , mDescription( description )
69 , mElseRule( elseRule )
70{
71 if ( mElseRule )
72 mFilterExp = QStringLiteral( "ELSE" );
73
74 initFilter();
75}
76
78{
79 qDeleteAll( mChildren );
80 // do NOT delete parent
81}
82
84{
85 if ( mSettings.get() == settings )
86 return;
87
88 mSettings.reset( settings );
89}
90
92{
93 RuleList l;
94 for ( Rule *c : mChildren )
95 {
96 l += c;
97 l += c->descendants();
98 }
99 return l;
100}
101
102void QgsRuleBasedLabeling::Rule::initFilter()
103{
104 if ( mFilterExp.trimmed().compare( QLatin1String( "ELSE" ), Qt::CaseInsensitive ) == 0 )
105 {
106 mElseRule = true;
107 mFilter.reset( );
108 }
109 else if ( mFilterExp.trimmed().isEmpty() )
110 {
111 mElseRule = false;
112 mFilter.reset();
113 }
114 else
115 {
116 mElseRule = false;
117 mFilter = std::make_unique< QgsExpression >( mFilterExp );
118 }
119}
120
121void QgsRuleBasedLabeling::Rule::updateElseRules()
122{
123 mElseRules.clear();
124 for ( Rule *rule : std::as_const( mChildren ) )
125 {
126 if ( rule->isElse() )
127 mElseRules << rule;
128 }
129}
130
132{
133 if ( mSettings && mSettings->format().containsAdvancedEffects() )
134 return true;
135
136 for ( Rule *rule : std::as_const( mChildren ) )
137 {
138 if ( rule->requiresAdvancedEffects() )
139 return true;
140 }
141
142 return false;
143}
144
146{
147 // NOTE: if visitEnter returns false it means "don't visit the rule", not "abort all further visitations"
149 return true;
150
151 if ( mSettings )
152 {
153 QgsStyleLabelSettingsEntity entity( *mSettings );
154 if ( !visitor->visit( QgsStyleEntityVisitorInterface::StyleLeaf( &entity ) ) )
155 return false;
156 }
157
158 if ( !mChildren.empty() )
159 {
160 for ( const Rule *rule : mChildren )
161 {
162 if ( !rule->accept( visitor ) )
163 return false;
164 }
165 }
166
167 if ( mParent && !visitor->visitExit( QgsStyleEntityVisitorInterface::Node( QgsStyleEntityVisitorInterface::NodeType::SymbolRule, mRuleKey, mDescription ) ) )
168 return false;
169
170 return true;
171}
172
173void QgsRuleBasedLabeling::Rule::subProviderIds( QStringList &list ) const
174{
175 for ( const Rule *rule : std::as_const( mChildren ) )
176 {
177 if ( rule->settings() )
178 list << rule->ruleKey();
179
180 rule->subProviderIds( list );
181 }
182}
183
184
186{
187 mChildren.append( rule );
188 rule->mParent = this;
189 updateElseRules();
190}
191
193{
194 mChildren.insert( i, rule );
195 rule->mParent = this;
196 updateElseRules();
197}
198
200{
201 delete mChildren.at( i );
202 mChildren.removeAt( i );
203 updateElseRules();
204}
205
207{
208 // we could use a hash / map for search if this will be slow...
209
210 if ( key == mRuleKey )
211 return this;
212
213 for ( Rule *rule : mChildren )
214 {
215 const Rule *r = rule->findRuleByKey( key );
216 if ( r )
217 return r;
218 }
219 return nullptr;
220}
221
223{
224 if ( key == mRuleKey )
225 return this;
226
227 for ( Rule *rule : std::as_const( mChildren ) )
228 {
229 Rule *r = rule->findRuleByKey( key );
230 if ( r )
231 return r;
232 }
233 return nullptr;
234}
235
237{
238 QgsPalLayerSettings *s = mSettings.get() ? new QgsPalLayerSettings( *mSettings ) : nullptr;
239 Rule *newrule = new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
240 newrule->setActive( mIsActive );
241 if ( !resetRuleKey )
242 newrule->setRuleKey( ruleKey() );
243
244 // clone children
245 for ( Rule *rule : mChildren )
246 newrule->appendChild( rule->clone( resetRuleKey ) );
247
248 return newrule;
249}
250
251QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::create( const QDomElement &ruleElem, const QgsReadWriteContext &context, bool reuseId )
252{
253 QgsPalLayerSettings *settings = nullptr;
254 QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral( "settings" ) );
255 if ( !settingsElem.isNull() )
256 {
258 settings->readXml( settingsElem, context );
259 }
260
261 QString filterExp = ruleElem.attribute( QStringLiteral( "filter" ) );
262 QString description = ruleElem.attribute( QStringLiteral( "description" ) );
263 int scaleMinDenom = ruleElem.attribute( QStringLiteral( "scalemindenom" ), QStringLiteral( "0" ) ).toInt();
264 int scaleMaxDenom = ruleElem.attribute( QStringLiteral( "scalemaxdenom" ), QStringLiteral( "0" ) ).toInt();
265 QString ruleKey;
266 if ( reuseId )
267 ruleKey = ruleElem.attribute( QStringLiteral( "key" ) );
268 else
269 ruleKey = QUuid::createUuid().toString();
270 Rule *rule = new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );
271
272 if ( !ruleKey.isEmpty() )
273 rule->mRuleKey = ruleKey;
274
275 rule->setActive( ruleElem.attribute( QStringLiteral( "active" ), QStringLiteral( "1" ) ).toInt() );
276
277 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( "rule" ) );
278 while ( !childRuleElem.isNull() )
279 {
280 Rule *childRule = create( childRuleElem, context );
281 if ( childRule )
282 {
283 rule->appendChild( childRule );
284 }
285 else
286 {
287 //QgsDebugError( QStringLiteral( "failed to init a child rule!" ) );
288 }
289 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( "rule" ) );
290 }
291
292 return rule;
293}
294
295QDomElement QgsRuleBasedLabeling::Rule::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
296{
297 QDomElement ruleElem = doc.createElement( QStringLiteral( "rule" ) );
298
299 if ( mSettings )
300 {
301 ruleElem.appendChild( mSettings->writeXml( doc, context ) );
302 }
303 if ( !mFilterExp.isEmpty() )
304 ruleElem.setAttribute( QStringLiteral( "filter" ), mFilterExp );
305 if ( !qgsDoubleNear( mMaximumScale, 0 ) )
306 ruleElem.setAttribute( QStringLiteral( "scalemindenom" ), mMaximumScale );
307 if ( !qgsDoubleNear( mMinimumScale, 0 ) )
308 ruleElem.setAttribute( QStringLiteral( "scalemaxdenom" ), mMinimumScale );
309 if ( !mDescription.isEmpty() )
310 ruleElem.setAttribute( QStringLiteral( "description" ), mDescription );
311 if ( !mIsActive )
312 ruleElem.setAttribute( QStringLiteral( "active" ), 0 );
313 ruleElem.setAttribute( QStringLiteral( "key" ), mRuleKey );
314
315 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
316 {
317 Rule *rule = *it;
318 ruleElem.appendChild( rule->save( doc, context ) );
319 }
320 return ruleElem;
321}
322
324{
325 if ( mSettings )
326 {
327 // add provider!
328 QgsVectorLayerLabelProvider *p = provider->createProvider( layer, mRuleKey, false, mSettings.get() );
329 auto it = std::find_if( subProviders.begin(), subProviders.end(),
330 [this]( const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
331 {
332 return item.first == this;
333 } );
334
335 if ( it != subProviders.end() )
336 {
337 delete it->second;
338 subProviders.erase( it );
339 }
340
341 subProviders.push_back( {this, p} );
342 }
343
344 // call recursively
345 for ( Rule *rule : std::as_const( mChildren ) )
346 {
347 rule->createSubProviders( layer, subProviders, provider );
348 }
349}
350
351void QgsRuleBasedLabeling::Rule::prepare( QgsRenderContext &context, QSet<QString> &attributeNames, QgsRuleBasedLabeling::RuleToProviderVec &subProviders )
352{
353 if ( mSettings )
354 {
355 auto it = std::find_if( subProviders.begin(), subProviders.end(),
356 [this]( const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
357 {
358 return item.first == this;
359 } );
360
361 if ( it != subProviders.end() )
362 {
363 QgsVectorLayerLabelProvider *p = it->second;
364 if ( !p->prepare( context, attributeNames ) )
365 {
366 subProviders.erase( it );
367 delete p;
368 }
369 }
370 }
371
372 if ( mFilter )
373 {
374 attributeNames.unite( mFilter->referencedColumns() );
375 mFilter->prepare( &context.expressionContext() );
376 }
377
378 // call recursively
379 for ( Rule *rule : std::as_const( mChildren ) )
380 {
381 rule->prepare( context, attributeNames, subProviders );
382 }
383}
384
385std::tuple< QgsRuleBasedLabeling::Rule::RegisterResult, QList< QgsLabelFeature * > > QgsRuleBasedLabeling::Rule::registerFeature( const QgsFeature &feature, QgsRenderContext &context, QgsRuleBasedLabeling::RuleToProviderVec &subProviders, const QgsGeometry &obstacleGeometry, const QgsSymbol *symbol )
386{
387 QList< QgsLabelFeature * > labels;
388 if ( !isFilterOK( feature, context )
389 || !isScaleOK( context.rendererScale() ) )
390 {
391 return { Filtered, labels };
392 }
393
394 bool registered = false;
395
396 // do we have active subprovider for the rule?
397 auto it = std::find_if( subProviders.begin(), subProviders.end(),
398 [this]( const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
399 {
400 return item.first == this;
401 } );
402
403 if ( it != subProviders.end() && mIsActive )
404 {
405 labels.append( it->second->registerFeature( feature, context, obstacleGeometry, symbol ) );
406 registered = true;
407 }
408
409 bool matchedAChild = false;
410
411 // call recursively
412 for ( Rule *rule : std::as_const( mChildren ) )
413 {
414 // Don't process else rules yet
415 if ( !rule->isElse() )
416 {
417 RegisterResult res;
418 QList< QgsLabelFeature * > added;
419 std::tie( res, added ) = rule->registerFeature( feature, context, subProviders, obstacleGeometry );
420 labels.append( added );
421 // consider inactive items as "matched" so the else rule will ignore them
422 matchedAChild |= ( res == Registered || res == Inactive );
423 registered |= matchedAChild;
424 }
425 }
426
427 // If none of the rules passed then we jump into the else rules and process them.
428 if ( !matchedAChild )
429 {
430 for ( Rule *rule : std::as_const( mElseRules ) )
431 {
432 RegisterResult res;
433 QList< QgsLabelFeature * > added;
434 std::tie( res, added ) = rule->registerFeature( feature, context, subProviders, obstacleGeometry, symbol ) ;
435 matchedAChild |= ( res == Registered || res == Inactive );
436 registered |= res != Filtered;
437 labels.append( added );
438 }
439 }
440
441 if ( !mIsActive || ( matchedAChild && !registered ) )
442 return { Inactive, labels };
443 else if ( registered )
444 return { Registered, labels };
445 else
446 return { Filtered, labels };
447}
448
449bool QgsRuleBasedLabeling::Rule::isFilterOK( const QgsFeature &f, QgsRenderContext &context ) const
450{
451 if ( ! mFilter || mElseRule )
452 return true;
453
454 context.expressionContext().setFeature( f );
455 QVariant res = mFilter->evaluate( &context.expressionContext() );
456 return res.toBool();
457}
458
459bool QgsRuleBasedLabeling::Rule::isScaleOK( double scale ) const
460{
461 if ( qgsDoubleNear( scale, 0.0 ) ) // so that we can count features in classes without scale context
462 return true;
463 if ( qgsDoubleNear( mMaximumScale, 0.0 ) && qgsDoubleNear( mMinimumScale, 0.0 ) )
464 return true;
465
466 // maxScale is inclusive ( < --> no label )
467 if ( !qgsDoubleNear( mMaximumScale, 0.0 ) && QgsScaleUtils::lessThanMaximumScale( scale, mMaximumScale ) )
468 return false;
469
470 // minScale is exclusive ( >= --> no label )
471 if ( !qgsDoubleNear( mMinimumScale, 0.0 ) && QgsScaleUtils::equalToOrGreaterThanMinimumScale( scale, mMinimumScale ) )
472 return false;
473 return true;
474}
475
477
482
484{
486
487 // normally with clone() the individual rules get new keys (UUID), but here we want to keep
488 // the tree of rules intact, so that other components that may use the rule keys work nicely (e.g. map themes)
489 rootRule->setRuleKey( mRootRule->ruleKey() );
490 RuleList origDescendants = mRootRule->descendants();
491 RuleList clonedDescendants = rootRule->descendants();
492 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
493 for ( int i = 0; i < origDescendants.count(); ++i )
494 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
495
496 return new QgsRuleBasedLabeling( rootRule );
497}
498
502
507
509{
510 return mRootRule.get();
511}
512
513
514QgsRuleBasedLabeling *QgsRuleBasedLabeling::create( const QDomElement &element, const QgsReadWriteContext &context ) // cppcheck-suppress duplInheritedMember
515{
516 QDomElement rulesElem = element.firstChildElement( QStringLiteral( "rules" ) );
517
518 Rule *root = Rule::create( rulesElem, context );
519 if ( !root )
520 return nullptr;
521
523 return rl;
524}
525
527{
528 return QStringLiteral( "rule-based" );
529}
530
531QDomElement QgsRuleBasedLabeling::save( QDomDocument &doc, const QgsReadWriteContext &context ) const
532{
533 QDomElement elem = doc.createElement( QStringLiteral( "labeling" ) );
534 elem.setAttribute( QStringLiteral( "type" ), QStringLiteral( "rule-based" ) );
535
536 QDomElement rulesElem = mRootRule->save( doc, context );
537 rulesElem.setTagName( QStringLiteral( "rules" ) ); // instead of just "rule"
538 elem.appendChild( rulesElem );
539
540 return elem;
541}
542
544{
545 return new QgsRuleBasedLabelProvider( *this, layer, false );
546}
547
549{
550 QStringList lst;
551 mRootRule->subProviderIds( lst );
552 return lst;
553}
554
555QgsPalLayerSettings QgsRuleBasedLabeling::settings( const QString &providerId ) const
556{
557 const Rule *rule = mRootRule->findRuleByKey( providerId );
558 if ( rule && rule->settings() )
559 return *rule->settings();
560
561 return QgsPalLayerSettings();
562}
563
565{
566 return mRootRule->accept( visitor );
567}
568
570{
571 return mRootRule->requiresAdvancedEffects();
572}
573
574void QgsRuleBasedLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
575{
576 if ( settings )
577 {
578 Rule *rule = mRootRule->findRuleByKey( providerId );
579 if ( rule && rule->settings() )
580 rule->setSettings( settings );
581 }
582}
583
584void QgsRuleBasedLabeling::toSld( QDomNode &parent, const QVariantMap &props ) const
585{
586 if ( !mRootRule )
587 {
588 return;
589 }
590
591 const QgsRuleBasedLabeling::RuleList rules = mRootRule->children();
592 for ( Rule *rule : rules )
593 {
594 QgsPalLayerSettings *settings = rule->settings();
595
596 if ( settings && settings->drawLabels )
597 {
598 QDomDocument doc = parent.ownerDocument();
599
600 QDomElement ruleElement = doc.createElement( QStringLiteral( "se:Rule" ) );
601 parent.appendChild( ruleElement );
602
603 if ( !rule->filterExpression().isEmpty() )
604 {
605 QgsSymbolLayerUtils::createFunctionElement( doc, ruleElement, rule->filterExpression() );
606 }
607
608 // scale dependencies, the actual behavior is that the PAL settings min/max and
609 // the rule min/max get intersected
610 QVariantMap localProps = QVariantMap( props );
611 QgsSymbolLayerUtils::mergeScaleDependencies( rule->maximumScale(), rule->minimumScale(), localProps );
613 {
615 }
616 QgsSymbolLayerUtils::applyScaleDependency( doc, ruleElement, localProps );
617
619 }
620
621 }
622
623}
624
625void QgsRuleBasedLabeling::multiplyOpacity( double opacityFactor )
626{
627 if ( !mRootRule )
628 {
629 return;
630 }
631
632 const QgsRuleBasedLabeling::RuleList rules = mRootRule->children();
633 for ( Rule *rule : rules )
634 {
635 QgsPalLayerSettings *settings = rule->settings();
636
637 if ( settings && settings->drawLabels )
638 {
639 QgsTextFormat format { settings->format() };
640 format.multiplyOpacity( opacityFactor );
641 settings->setFormat( format );
642 }
643
644 }
645}
const QgsLabelingEngine * mEngine
Associated labeling engine.
QgsMapLayer * layer() const
Returns the associated layer, or nullptr if no layer is associated with the provider.
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:58
A geometry is the spatial representation of a feature.
Contains settings for how a map layer will be labeled.
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
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.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
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)
std::vector< std::pair< QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider * > > 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)
void createSubProviders(QgsVectorLayer *layer, RuleToProviderVec &subProviders, QgsRuleBasedLabelProvider *provider)
add providers
std::tuple< RegisterResult, QList< QgsLabelFeature * > > registerFeature(const QgsFeature &feature, QgsRenderContext &context, RuleToProviderVec &subProviders, const QgsGeometry &obstacleGeometry=QgsGeometry(), const QgsSymbol *symbol=nullptr)
Register individual features.
void prepare(QgsRenderContext &context, QSet< QString > &attributeNames, RuleToProviderVec &subProviders)
call prepare() on sub-providers and populate attributeNames
QgsPalLayerSettings * settings() const
Returns the labeling settings.
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...
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.
static QgsRuleBasedLabeling::Rule * create(const QDomElement &ruleElem, const QgsReadWriteContext &context, bool reuseId=true)
Create a rule from an XML definition.
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... you get it.
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
QgsRuleBasedLabeling::Rule * clone(bool resetRuleKey=true) const
clone this rule
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.
QString type() const override
Unique type string of the labeling configuration implementation.
QgsRuleBasedLabeling * clone() const override
Returns a new copy of the object.
void multiplyOpacity(double opacityFactor) override
Multiply opacity by opacityFactor.
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 ...
static bool equalToOrGreaterThanMinimumScale(const double scale, const double minScale)
Returns whether the scale is equal to or greater than the minScale, taking non-round numbers into acc...
static bool lessThanMaximumScale(const double scale, const double maxScale)
Returns whether the scale is less than the maxScale, taking non-round numbers into account.
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:1489
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:231
Container for all settings relating to text rendering.
void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
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:6125
Contains information relating to a node (i.e.
Contains information relating to the style entity currently being visited.