48 QList<QgsAbstractLabelProvider *> lst;
60 , mMaximumScale( scaleMinDenom )
61 , mMinimumScale( scaleMaxDenom )
62 , mFilterExp( filterExp )
63 , mDescription( description )
64 , mElseRule( elseRule )
68 mRuleKey = QUuid::createUuid().toString();
76 qDeleteAll( mChildren );
82 if ( mSettings == settings )
89 void QgsRuleBasedLabeling::Rule::initFilter()
91 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
96 else if ( !mFilterExp.isEmpty() )
99 mFilter =
new QgsExpression( mFilterExp );
107 void QgsRuleBasedLabeling::Rule::updateElseRules()
110 Q_FOREACH (
Rule *rule, mChildren )
122 Q_FOREACH (
Rule *rule, mChildren )
133 Q_FOREACH (
const Rule *rule, mChildren )
145 mChildren.append( rule );
146 rule->mParent =
this;
152 mChildren.insert( i, rule );
153 rule->mParent =
this;
159 delete mChildren.at( i );
160 mChildren.removeAt( i );
168 if ( key == mRuleKey )
171 Q_FOREACH (
Rule *rule, mChildren )
182 if ( key == mRuleKey )
185 for (
Rule *rule : qgis::as_const( mChildren ) )
197 Rule *newrule =
new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
200 Q_FOREACH (
Rule *rule, mChildren )
208 QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral(
"settings" ) );
209 if ( !settingsElem.isNull() )
212 settings->
readXml( settingsElem, context );
215 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
216 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
217 int scaleMinDenom = ruleElem.attribute( QStringLiteral(
"scalemindenom" ), QStringLiteral(
"0" ) ).toInt();
218 int scaleMaxDenom = ruleElem.attribute( QStringLiteral(
"scalemaxdenom" ), QStringLiteral(
"0" ) ).toInt();
219 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
220 Rule *rule =
new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );
222 if ( !ruleKey.isEmpty() )
223 rule->mRuleKey = ruleKey;
225 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
227 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
228 while ( !childRuleElem.isNull() )
230 Rule *childRule =
create( childRuleElem, context );
239 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
247 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
251 ruleElem.appendChild( mSettings->
writeXml( doc, context ) );
253 if ( !mFilterExp.isEmpty() )
254 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
255 if ( mMaximumScale != 0 )
256 ruleElem.setAttribute( QStringLiteral(
"scalemindenom" ), mMaximumScale );
257 if ( mMinimumScale != 0 )
258 ruleElem.setAttribute( QStringLiteral(
"scalemaxdenom" ), mMinimumScale );
259 if ( !mDescription.isEmpty() )
260 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
262 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
263 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
265 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
279 delete subProviders.value(
this,
nullptr );
280 subProviders[
this] = p;
284 Q_FOREACH (
Rule *rule, mChildren )
295 if ( !p->
prepare( context, attributeNames ) )
297 subProviders.remove(
this );
304 attributeNames.unite( mFilter->referencedColumns() );
309 Q_FOREACH (
Rule *rule, mChildren )
311 rule->
prepare( context, attributeNames, subProviders );
317 if ( !isFilterOK( feature, context )
321 bool registered =
false;
324 if ( subProviders.contains(
this ) && mIsActive )
326 subProviders[
this]->registerFeature( feature, context, obstacleGeometry );
330 bool willRegisterSomething =
false;
333 Q_FOREACH (
Rule *rule, mChildren )
341 registered |= willRegisterSomething;
346 if ( !willRegisterSomething )
348 Q_FOREACH (
Rule *rule, mElseRules )
356 else if ( registered )
364 if ( ! mFilter || mElseRule )
369 return res.toInt() != 0;
372 bool QgsRuleBasedLabeling::Rule::isScaleOK(
double scale )
const 378 if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
380 if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
401 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
402 for (
int i = 0; i < origDescendants.count(); ++i )
403 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
416 QDomElement rulesElem = element.firstChildElement( QStringLiteral(
"rules" ) );
428 return QStringLiteral(
"rule-based" );
433 QDomElement elem = doc.createElement( QStringLiteral(
"labeling" ) );
434 elem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"rule-based" ) );
437 rulesElem.setTagName( QStringLiteral(
"rules" ) );
438 elem.appendChild( rulesElem );
487 for (
Rule *rule : rules )
493 QDomDocument doc = parent.ownerDocument();
495 QDomElement ruleElement = doc.createElement( QStringLiteral(
"se:Rule" ) );
496 parent.appendChild( ruleElement );
498 if ( !rule->filterExpression().isEmpty() )
The class is used as a container of context for various read/write operations on other objects...
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.
bool requiresAdvancedEffects() const
Returns true if this rule or any of its children requires advanced composition effects to render...
QgsPalLayerSettings * settings() const
Get the labeling settings.
Something was registered.
double rendererScale() const
Returns the renderer map scale.
QgsVectorLayerLabelProvider * provider(QgsVectorLayer *layer) const override
double maximumScale
The maximum map scale (i.e.
~QgsRuleBasedLabeling() override
void setSettings(QgsPalLayerSettings *settings, const QString &providerId=QString()) override
Set pal settings for a specific provider (takes ownership).
QgsRuleBasedLabeling::RuleToProviderMap mSubProviders
label providers are owned by labeling engine
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Rule(QgsPalLayerSettings *settings, int maximumScale=0, int minimumScale=0, const QString &filterExp=QString(), const QString &description=QString(), bool elseRule=false)
takes ownership of settings
bool requiresAdvancedEffects() const override
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const override
Return labeling configuration as XML element.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) const
store labeling info to XML element
const QgsLabelingEngine * mEngine
Associated labeling engine.
void readXml(QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
void insertChild(int i, QgsRuleBasedLabeling::Rule *rule)
add child rule, take ownership, sets this as parent
bool isElse() const
Check if this rule is an ELSE rule.
RegisterResult
The result of registering a rule.
QgsRuleBasedLabeling::Rule * clone() const
clone this rule, return new instance
static void mergeScaleDependencies(int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
QString description() const
A human readable description for this rule.
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
A geometry is the spatial representation of a feature.
bool drawLabels
Whether to draw labels for this layer.
QList< QgsAbstractLabelProvider * > subProviders() override
return subproviders
QString ruleKey() const
Unique rule identifier (for identification of rule within labeling, used as provider ID) ...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QMap< QgsRuleBasedLabeling::Rule *, QgsVectorLayerLabelProvider * > RuleToProviderMap
const QgsRuleBasedLabeling::RuleList & children() const
Return all children rules of this rule.
QMap< QString, QString > QgsStringMap
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
QgsRuleBasedLabeling::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
QList< QgsRuleBasedLabeling::Rule * > RuleList
void prepare(const QgsRenderContext &context, QSet< QString > &attributeNames, RuleToProviderMap &subProviders)
call prepare() on sub-providers and populate attributeNames
static QgsRuleBasedLabeling::Rule * create(const QDomElement &ruleElem, const QgsReadWriteContext &context)
Create a rule from an XML definition.
QgsMapLayer * layer() const
Returns the associated layer, or nullptr if no layer is associated with the provider.
QString type() const override
Unique type string of the labeling configuration implementation.
void appendChild(QgsRuleBasedLabeling::Rule *rule)
add child rule, take ownership, sets this as parent
QStringList subProviders() const override
Get list of sub-providers within the layer's labeling.
bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames) override
Prepare for registration of features.
virtual bool prepare(const QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
std::unique_ptr< QgsRuleBasedLabeling > mRules
owned copy
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context)
Write settings into a DOM element.
virtual QgsVectorLayerLabelProvider * createProvider(QgsVectorLayer *layer, const QString &providerId, bool withFeatureLoop, const QgsPalLayerSettings *settings)
create a label provider
void setSettings(QgsPalLayerSettings *settings)
set new settings (or NULL). Deletes old settings if any.
QgsPalLayerSettings mSettings
Layer's labeling configuration.
QgsRuleBasedLabeling::Rule * rootRule()
QgsRuleBasedLabeling(QgsRuleBasedLabeling::Rule *root)
Constructs the labeling from given tree of rules (takes ownership)
const QgsRuleBasedLabeling::Rule * findRuleByKey(const QString &key) const
Try to find a rule given its unique key.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc...
void setActive(bool state)
Sets if this rule is active.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QgsRuleBasedLabeling * create(const QDomElement &element, const QgsReadWriteContext &context)
Create the instance from a DOM element with saved configuration.
RegisterResult registerFeature(QgsFeature &feature, QgsRenderContext &context, RuleToProviderMap &subProviders, const QgsGeometry &obstacleGeometry=QgsGeometry())
register individual features
QgsRuleBasedLabeling * clone() const override
Return a new copy of the object.
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based labeling) ...
QgsPalLayerSettings settings(const QString &providerId=QString()) const override
Get associated label settings.
void subProviderIds(QStringList &list) const
append rule keys of descendants that contain valid settings (i.e.
Contains information about the context of a rendering operation.
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
void registerFeature(QgsFeature &feature, QgsRenderContext &context, const QgsGeometry &obstacleGeometry=QgsGeometry()) override
Register a feature for labeling as one or more QgsLabelFeature objects stored into mLabels...
virtual void writeTextSymbolizer(QDomNode &parent, QgsPalLayerSettings &settings, const QgsStringMap &props) const
Writes a TextSymbolizer element contents based on the provided labeling settings. ...
QString providerId() const
Returns provider ID - useful in case there is more than one label provider within a layer (e...
void toSld(QDomNode &parent, const QgsStringMap &props) const override
Writes the SE 1.1 TextSymbolizer element based on the current layer labeling settings.
void removeChildAt(int i)
delete child rule
Represents a vector layer which manages a vector based data sets.
void createSubProviders(QgsVectorLayer *layer, RuleToProviderMap &subProviders, QgsRuleBasedLabelProvider *provider)
add providers
bool containsAdvancedEffects() const
Returns true if any component of the font format requires advanced effects such as blend modes...
QgsRuleBasedLabelProvider(const QgsRuleBasedLabeling &rules, QgsVectorLayer *layer, bool withFeatureLoop=true)
void setEngine(const QgsLabelingEngine *engine)
Associate provider with a labeling engine (should be only called internally from QgsLabelingEngine) ...
double minimumScale
The minimum map scale (i.e.