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 )
92 for (
Rule *
c : mChildren )
95 l +=
c->descendants();
100 void QgsRuleBasedLabeling::Rule::initFilter()
102 if ( mElseRule || mFilterExp.compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
107 else if ( !mFilterExp.isEmpty() )
118 void QgsRuleBasedLabeling::Rule::updateElseRules()
121 Q_FOREACH (
Rule *rule, mChildren )
133 Q_FOREACH (
Rule *rule, mChildren )
144 Q_FOREACH (
const Rule *rule, mChildren )
156 mChildren.append( rule );
157 rule->mParent =
this;
163 mChildren.insert( i, rule );
164 rule->mParent =
this;
170 delete mChildren.at( i );
171 mChildren.removeAt( i );
179 if ( key == mRuleKey )
182 Q_FOREACH (
Rule *rule, mChildren )
193 if ( key == mRuleKey )
196 for (
Rule *rule : qgis::as_const( mChildren ) )
208 Rule *newrule =
new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
211 Q_FOREACH (
Rule *rule, mChildren )
219 QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral(
"settings" ) );
220 if ( !settingsElem.isNull() )
223 settings->
readXml( settingsElem, context );
226 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
227 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
228 int scaleMinDenom = ruleElem.attribute( QStringLiteral(
"scalemindenom" ), QStringLiteral(
"0" ) ).toInt();
229 int scaleMaxDenom = ruleElem.attribute( QStringLiteral(
"scalemaxdenom" ), QStringLiteral(
"0" ) ).toInt();
230 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
231 Rule *rule =
new Rule( settings, scaleMinDenom, scaleMaxDenom, filterExp, description );
233 if ( !ruleKey.isEmpty() )
234 rule->mRuleKey = ruleKey;
236 rule->
setActive( ruleElem.attribute( QStringLiteral(
"active" ), QStringLiteral(
"1" ) ).toInt() );
238 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
239 while ( !childRuleElem.isNull() )
241 Rule *childRule =
create( childRuleElem, context );
250 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
258 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
262 ruleElem.appendChild( mSettings->
writeXml( doc, context ) );
264 if ( !mFilterExp.isEmpty() )
265 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
266 if ( mMaximumScale != 0 )
267 ruleElem.setAttribute( QStringLiteral(
"scalemindenom" ), mMaximumScale );
268 if ( mMinimumScale != 0 )
269 ruleElem.setAttribute( QStringLiteral(
"scalemaxdenom" ), mMinimumScale );
270 if ( !mDescription.isEmpty() )
271 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
273 ruleElem.setAttribute( QStringLiteral(
"active" ), 0 );
274 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
276 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
290 delete subProviders.value(
this,
nullptr );
291 subProviders[
this] = p;
295 Q_FOREACH (
Rule *rule, mChildren )
306 if ( !p->
prepare( context, attributeNames ) )
308 subProviders.remove(
this );
320 Q_FOREACH (
Rule *rule, mChildren )
322 rule->
prepare( context, attributeNames, subProviders );
328 if ( !isFilterOK( feature, context )
332 bool registered =
false;
335 if ( subProviders.contains(
this ) && mIsActive )
337 subProviders[
this]->registerFeature( feature, context, obstacleGeometry );
341 bool willRegisterSomething =
false;
344 Q_FOREACH (
Rule *rule, mChildren )
352 registered |= willRegisterSomething;
357 if ( !willRegisterSomething )
359 Q_FOREACH (
Rule *rule, mElseRules )
367 else if ( registered )
375 if ( ! mFilter || mElseRule )
380 return res.toInt() != 0;
383 bool QgsRuleBasedLabeling::Rule::isScaleOK(
double scale )
const 389 if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
391 if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
412 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
413 for (
int i = 0; i < origDescendants.count(); ++i )
414 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
427 QDomElement rulesElem = element.firstChildElement( QStringLiteral(
"rules" ) );
439 return QStringLiteral(
"rule-based" );
444 QDomElement elem = doc.createElement( QStringLiteral(
"labeling" ) );
445 elem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"rule-based" ) );
448 rulesElem.setTagName( QStringLiteral(
"rules" ) );
449 elem.appendChild( rulesElem );
498 for (
Rule *rule : rules )
504 QDomDocument doc = parent.ownerDocument();
506 QDomElement ruleElement = doc.createElement( QStringLiteral(
"se:Rule" ) );
507 parent.appendChild( ruleElement );
509 if ( !rule->filterExpression().isEmpty() )
Class for parsing and evaluation of expressions (formerly called "search strings").
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
Gets 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
Returns 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
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QVariant evaluate()
Evaluate the feature and return the result.
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
Returns subproviders.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
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
Returns all children rules of this rule.
QMap< QString, QString > QgsStringMap
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.
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
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
Gets 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)
Sets 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
Returns 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
Gets 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.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
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.