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