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