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