44  return std::get< 1 >( 
mRules->rootRule()->registerFeature( feature, context, 
mSubProviders, obstacleGeometry, symbol ) );
 
 
   49  QList<QgsAbstractLabelProvider *> lst;
 
 
   59  : mSettings( settings )
 
   60  , mMaximumScale( scaleMinDenom )
 
   61  , mMinimumScale( scaleMaxDenom )
 
   62  , mFilterExp( filterExp )
 
   63  , mDescription( description )
 
   64  , mElseRule( elseRule )
 
   67    mFilterExp = QStringLiteral( 
"ELSE" );
 
 
   74  qDeleteAll( mChildren );
 
 
   89  for ( 
Rule *
c : mChildren )
 
   92    l += 
c->descendants();
 
 
   97void QgsRuleBasedLabeling::Rule::initFilter()
 
   99  if ( mFilterExp.trimmed().compare( QLatin1String( 
"ELSE" ), Qt::CaseInsensitive ) == 0 )
 
  104  else if ( mFilterExp.trimmed().isEmpty() )
 
  112    mFilter = std::make_unique< QgsExpression >( mFilterExp );
 
  116void QgsRuleBasedLabeling::Rule::updateElseRules()
 
  119  for ( Rule *rule : std::as_const( mChildren ) )
 
  121    if ( rule->isElse() )
 
  128  if ( mSettings && mSettings->format().containsAdvancedEffects() )
 
  131  for ( 
Rule *rule : std::as_const( mChildren ) )
 
  133    if ( rule->requiresAdvancedEffects() )
 
 
  153  if ( !mChildren.empty() )
 
  155    for ( 
const Rule *rule : mChildren )
 
  157      if ( !rule->accept( visitor ) )
 
 
  170  for ( 
const Rule *rule : std::as_const( mChildren ) )
 
  172    if ( rule->settings() )
 
  173      list << rule->ruleKey();
 
  175    rule->subProviderIds( list );
 
 
  182  mChildren.append( rule );
 
  183  rule->mParent = 
this;
 
 
  189  mChildren.insert( i, rule );
 
  190  rule->mParent = 
this;
 
 
  196  delete mChildren.at( i );
 
  197  mChildren.removeAt( i );
 
 
  205  if ( key == mRuleKey )
 
  208  for ( 
Rule *rule : mChildren )
 
 
  219  if ( key == mRuleKey )
 
  222  for ( 
Rule *rule : std::as_const( mChildren ) )
 
 
  234  Rule *newrule = 
new Rule( s, mMaximumScale, mMinimumScale, mFilterExp, mDescription );
 
  237  for ( 
Rule *rule : mChildren )
 
 
  245  QDomElement settingsElem = ruleElem.firstChildElement( QStringLiteral( 
"settings" ) );
 
  246  if ( !settingsElem.isNull() )
 
  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();
 
  258    ruleKey = ruleElem.attribute( QStringLiteral( 
"key" ) );
 
  260    ruleKey = QUuid::createUuid().toString();
 
  261  Rule *rule = 
new Rule( 
settings, scaleMinDenom, scaleMaxDenom, filterExp, description );
 
  263  if ( !ruleKey.isEmpty() )
 
  264    rule->mRuleKey = ruleKey;
 
  266  rule->
setActive( ruleElem.attribute( QStringLiteral( 
"active" ), QStringLiteral( 
"1" ) ).toInt() );
 
  268  QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( 
"rule" ) );
 
  269  while ( !childRuleElem.isNull() )
 
  271    Rule *childRule = 
create( childRuleElem, context );
 
  280    childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( 
"rule" ) );
 
 
  288  QDomElement ruleElem = doc.createElement( QStringLiteral( 
"rule" ) );
 
  292    ruleElem.
appendChild( mSettings->writeXml( doc, context ) );
 
  294  if ( !mFilterExp.isEmpty() )
 
  295    ruleElem.setAttribute( QStringLiteral( 
"filter" ), mFilterExp );
 
  297    ruleElem.setAttribute( QStringLiteral( 
"scalemindenom" ), mMaximumScale );
 
  299    ruleElem.setAttribute( QStringLiteral( 
"scalemaxdenom" ), mMinimumScale );
 
  300  if ( !mDescription.isEmpty() )
 
  301    ruleElem.setAttribute( QStringLiteral( 
"description" ), mDescription );
 
  303    ruleElem.setAttribute( QStringLiteral( 
"active" ), 0 );
 
  304  ruleElem.setAttribute( QStringLiteral( 
"key" ), mRuleKey );
 
  306  for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
 
 
  325  for ( 
Rule *rule : std::as_const( mChildren ) )
 
 
  336    if ( !p->
prepare( context, attributeNames ) )
 
  345    attributeNames.unite( mFilter->referencedColumns() );
 
  350  for ( 
Rule *rule : std::as_const( mChildren ) )
 
 
  358  QList< QgsLabelFeature * > labels;
 
  359  if ( !isFilterOK( feature, context )
 
  362    return { Filtered, labels };
 
  365  bool registered = 
false;
 
  370    labels.append( 
subProviders[
this]->registerFeature( feature, context, obstacleGeometry, symbol ) );
 
  374  bool matchedAChild = 
false;
 
  377  for ( 
Rule *rule : std::as_const( mChildren ) )
 
  380    if ( !rule->isElse() )
 
  383      QList< QgsLabelFeature * > added;
 
  384      std::tie( res, added ) = rule->registerFeature( feature, context, 
subProviders, obstacleGeometry );
 
  385      labels.append( added );
 
  387      matchedAChild |= ( res == Registered || res == Inactive );
 
  388      registered |= matchedAChild;
 
  393  if ( !matchedAChild )
 
  395    for ( 
Rule *rule : std::as_const( mElseRules ) )
 
  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 );
 
  406  if ( !mIsActive || ( matchedAChild && !registered ) )
 
  407    return { Inactive, labels };
 
  408  else if ( registered )
 
  409    return { Registered, labels };
 
  411    return { Filtered, labels };
 
 
  416  if ( ! mFilter || mElseRule )
 
  424bool QgsRuleBasedLabeling::Rule::isScaleOK( 
double scale )
 const 
  430  if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
 
  432  if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
 
  453  Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
 
  454  for ( 
int i = 0; i < origDescendants.count(); ++i )
 
  455    clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
 
 
  477  QDomElement rulesElem = element.firstChildElement( QStringLiteral( 
"rules" ) );
 
 
  489  return QStringLiteral( 
"rule-based" );
 
 
  494  QDomElement elem = doc.createElement( QStringLiteral( 
"labeling" ) );
 
  495  elem.setAttribute( QStringLiteral( 
"type" ), QStringLiteral( 
"rule-based" ) );
 
  497  QDomElement rulesElem = 
mRootRule->save( doc, context );
 
  498  rulesElem.setTagName( QStringLiteral( 
"rules" ) ); 
 
  499  elem.appendChild( rulesElem );
 
 
  532  return mRootRule->requiresAdvancedEffects();
 
 
  553  for ( 
Rule *rule : rules )
 
  559      QDomDocument doc = parent.ownerDocument();
 
  561      QDomElement ruleElement = doc.createElement( QStringLiteral( 
"se:Rule" ) );
 
  562      parent.appendChild( ruleElement );
 
  564      if ( !rule->filterExpression().isEmpty() )
 
  571      QVariantMap localProps = QVariantMap( props );
 
 
  594  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 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.
 
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
 
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.
 
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
 
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).
 
~QgsRuleBasedLabeling() override
 
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.
 
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 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.
 
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.
 
Container for all settings relating to text rendering.
 
void multiplyOpacity(double opacityFactor)
Multiply opacity by opacityFactor.
 
The QgsVectorLayerLabelProvider class implements a label provider for vector layers.
 
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
 
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)
 
Contains information relating to a node (i.e.
 
Contains information relating to the style entity currently being visited.