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