36 for (
const auto &subprovider : std::as_const(
mSubProviders ) )
38 subprovider.second->setEngine(
mEngine );
49 return std::get< 1 >(
mRules->rootRule()->registerFeature( feature, context,
mSubProviders, obstacleGeometry, symbol ) );
54 QList<QgsAbstractLabelProvider *> lst;
55 for (
const auto &subprovider : std::as_const(
mSubProviders ) )
57 lst << subprovider.second;
67 , mMaximumScale( scaleMinDenom )
68 , mMinimumScale( scaleMaxDenom )
69 , mFilterExp( filterExp )
71 , mElseRule( elseRule )
74 mFilterExp = QStringLiteral(
"ELSE" );
81 qDeleteAll( mChildren );
96 for (
Rule *
c : mChildren )
99 l +=
c->descendants();
104void QgsRuleBasedLabeling::Rule::initFilter()
106 if ( mFilterExp.trimmed().compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
111 else if ( mFilterExp.trimmed().isEmpty() )
119 mFilter = std::make_unique< QgsExpression >( mFilterExp );
123void QgsRuleBasedLabeling::Rule::updateElseRules()
126 for (
Rule *rule : std::as_const( mChildren ) )
128 if ( rule->isElse() )
135 if ( mSettings && mSettings->format().containsAdvancedEffects() )
138 for (
Rule *rule : std::as_const( mChildren ) )
140 if ( rule->requiresAdvancedEffects() )
154 || mSettings->format().hasNonDefaultCompositionMode() ) )
157 for (
Rule *rule : std::as_const( mChildren ) )
159 if ( rule->hasNonDefaultCompositionMode() )
179 if ( !mChildren.empty() )
181 for (
const Rule *rule : mChildren )
183 if ( !rule->accept( visitor ) )
196 for (
const Rule *rule : std::as_const( mChildren ) )
198 if ( rule->settings() )
199 list << rule->ruleKey();
201 rule->subProviderIds( list );
208 mChildren.append( rule );
209 rule->mParent =
this;
215 mChildren.insert( i, rule );
216 rule->mParent =
this;
222 delete mChildren.at( i );
223 mChildren.removeAt( i );
231 if ( key == mRuleKey )
234 for (
Rule *rule : mChildren )
236 const Rule *r = rule->findRuleByKey( key );
245 if ( key == mRuleKey )
248 for (
Rule *rule : std::as_const( mChildren ) )
250 Rule *r = rule->findRuleByKey( key );
260 Rule *newrule =
new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
266 for (
Rule *rule : mChildren )
267 newrule->
appendChild( rule->clone( resetRuleKey ) );
275 QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral(
"settings" ) );
276 if ( !settingsElem.isNull() )
279 settings->readXml( settingsElem, context );
282 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
283 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
284 int scaleMinDenom = ruleElem.attribute( QStringLiteral(
"scalemindenom" ), QStringLiteral(
"0" ) ).toInt();
285 int scaleMaxDenom = ruleElem.attribute( QStringLiteral(
"scalemaxdenom" ), QStringLiteral(
"0" ) ).toInt();
288 ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
290 ruleKey = QUuid::createUuid().toString();
296 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
298 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
299 while ( !childRuleElem.isNull() )
301 Rule *childRule =
create( childRuleElem, context );
310 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
318 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
322 ruleElem.appendChild( mSettings->writeXml( doc, context ) );
324 if ( !mFilterExp.isEmpty() )
325 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
327 ruleElem.setAttribute( QStringLiteral(
"scalemindenom" ), mMaximumScale );
329 ruleElem.setAttribute( QStringLiteral(
"scalemaxdenom" ), mMinimumScale );
330 if ( !mDescription.isEmpty() )
331 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
333 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
334 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
336 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
339 ruleElem.appendChild( rule->
save( doc, context ) );
351 [
this](
const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
353 return item.first == this;
366 for (
Rule *rule : std::as_const( mChildren ) )
377 [
this](
const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
379 return item.first == this;
385 if ( !p->
prepare( context, attributeNames ) )
395 attributeNames.unite( mFilter->referencedColumns() );
400 for (
Rule *rule : std::as_const( mChildren ) )
408 QList< QgsLabelFeature * > labels;
409 if ( !isFilterOK( feature, context )
415 bool registered =
false;
419 [
this](
const std::pair<QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider *> &item )
421 return item.first == this;
426 labels.append( it->second->registerFeature( feature, context, obstacleGeometry, symbol ) );
430 bool matchedAChild =
false;
433 for (
Rule *rule : std::as_const( mChildren ) )
436 if ( !rule->isElse() )
439 QList< QgsLabelFeature * > added;
440 std::tie( res, added ) = rule->registerFeature( feature, context,
subProviders, obstacleGeometry );
441 labels.append( added );
444 registered |= matchedAChild;
449 if ( !matchedAChild )
451 for (
Rule *rule : std::as_const( mElseRules ) )
454 QList< QgsLabelFeature * > added;
455 std::tie( res, added ) = rule->registerFeature( feature, context,
subProviders, obstacleGeometry, symbol ) ;
458 labels.append( added );
462 if ( !mIsActive || ( matchedAChild && !registered ) )
464 else if ( registered )
472 if ( ! mFilter || mElseRule )
480bool QgsRuleBasedLabeling::Rule::isScaleOK(
double scale )
const
513 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
514 for (
int i = 0; i < origDescendants.count(); ++i )
515 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
537 QDomElement rulesElem = element.firstChildElement( QStringLiteral(
"rules" ) );
549 return QStringLiteral(
"rule-based" );
554 QDomElement elem = doc.createElement( QStringLiteral(
"labeling" ) );
555 elem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"rule-based" ) );
557 QDomElement rulesElem =
mRootRule->save( doc, context );
558 rulesElem.setTagName( QStringLiteral(
"rules" ) );
559 elem.appendChild( rulesElem );
592 return mRootRule->requiresAdvancedEffects();
597 return mRootRule->hasNonDefaultCompositionMode();
614 toSld( parent, context );
625 for (
Rule *rule : rules )
631 QDomDocument doc = parent.ownerDocument();
633 QDomElement ruleElement = doc.createElement( QStringLiteral(
"se:Rule" ) );
634 parent.appendChild( ruleElement );
636 if ( !rule->filterExpression().isEmpty() )
644 QVariantMap localProps = oldProps;
667 for (
Rule *rule : rules )
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...
A geometry is the spatial representation of a feature.
Contains settings for how a map layer will be labeled.
@ FontBlendMode
Text blend mode.
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).
~QgsRuleBasedLabeling() override
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.
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.
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).
Contains information relating to a node (i.e.
Contains information relating to the style entity currently being visited.