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