36#include <QDomDocument> 
   44  , mMaximumScale( scaleMinDenom )
 
   45  , mMinimumScale( scaleMaxDenom )
 
   46  , mFilterExp( filterExp )
 
   48  , mDescription( description )
 
   49  , mElseRule( elseRule )
 
   52    mFilterExp = QStringLiteral( 
"ELSE" );
 
   54  mRuleKey = QUuid::createUuid().toString();
 
 
   60  qDeleteAll( mChildren );
 
 
   66  if ( mFilterExp.trimmed().compare( QLatin1String( 
"ELSE" ), Qt::CaseInsensitive ) == 0 )
 
   71  else if ( mFilterExp.trimmed().isEmpty() )
 
   79    mFilter = std::make_unique< QgsExpression >( mFilterExp );
 
 
   85  mChildren.append( rule );
 
 
   92  mChildren.insert( i, rule );
 
 
   99  mChildren.removeAll( rule );
 
 
  106  delete mChildren.takeAt( i );
 
 
  112  mChildren.removeAll( rule );
 
  113  rule->mParent = 
nullptr;
 
 
  120  Rule *rule = mChildren.takeAt( i );
 
  121  rule->mParent = 
nullptr;
 
 
  130  if ( key == mRuleKey )
 
  133  const auto constMChildren = mChildren;
 
  134  for ( 
Rule *rule : constMChildren )
 
 
  143void QgsRuleBasedRenderer::Rule::updateElseRules()
 
  146  const auto constMChildren = mChildren;
 
  147  for ( 
Rule *rule : constMChildren )
 
  149    if ( rule->isElse() )
 
  156  mFilterExp = QStringLiteral( 
"ELSE" );
 
 
  174  if ( !mChildren.empty() )
 
  176    for ( 
const Rule *rule : mChildren )
 
  179      if ( !rule->accept( visitor ) )
 
 
  193  off.fill( QChar( 
' ' ), indent );
 
  194  QString symbolDump = ( mSymbol ? mSymbol->dump() : QStringLiteral( 
"[]" ) );
 
  195  QString msg = off + QStringLiteral( 
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
 
  196                .arg( mLabel ).arg( mMaximumScale ).arg( mMinimumScale )
 
  197                .arg( mFilterExp, symbolDump );
 
  200  const auto constMChildren = mChildren;
 
  201  for ( 
Rule *rule : constMChildren )
 
  203    lst.append( rule->dump( indent + 2 ) );
 
  205  msg += lst.join( QLatin1Char( 
'\n' ) );
 
 
  214    attrs.unite( 
mFilter->referencedColumns() );
 
  216    attrs.unite( mSymbol->usedAttributes( context ) );
 
  219  const auto constMChildren = mChildren;
 
  220  for ( 
Rule *rule : constMChildren )
 
  222    attrs.unite( rule->usedAttributes( context ) );
 
 
  232  const auto constMChildren = mChildren;
 
  233  for ( 
Rule *rule : constMChildren )
 
  235    if ( rule->needsGeometry() )
 
 
  246    lst.append( mSymbol.get() );
 
  248  const auto constMChildren = mChildren;
 
  249  for ( 
Rule *rule : constMChildren )
 
  251    lst += rule->symbols( context );
 
 
  258  mSymbol.reset( sym );
 
 
  263  mFilterExp = filterExp;
 
 
  270  if ( currentLevel != -1 ) 
 
  272    lst << 
QgsLegendSymbolItem( mSymbol.get(), mLabel, mRuleKey, 
true, mMaximumScale, mMinimumScale, currentLevel, mParent ? mParent->mRuleKey : QString() );
 
  275  for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
 
 
  286  if ( ! 
mFilter || mElseRule || ! context )
 
 
  300  if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
 
  302  if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
 
 
  310  Rule *newrule = 
new Rule( sym, mMaximumScale, mMinimumScale, mFilterExp, mLabel, mDescription );
 
  313  const auto constMChildren = mChildren;
 
  314  for ( 
Rule *rule : constMChildren )
 
 
  321  QDomElement ruleElem = doc.createElement( QStringLiteral( 
"rule" ) );
 
  325    int symbolIndex = symbolMap.size();
 
  326    symbolMap[QString::number( symbolIndex )] = mSymbol.get();
 
  327    ruleElem.setAttribute( QStringLiteral( 
"symbol" ), symbolIndex );
 
  329  if ( !mFilterExp.isEmpty() )
 
  330    ruleElem.setAttribute( QStringLiteral( 
"filter" ), mFilterExp );
 
  331  if ( mMaximumScale != 0 )
 
  332    ruleElem.setAttribute( QStringLiteral( 
"scalemindenom" ), mMaximumScale );
 
  333  if ( mMinimumScale != 0 )
 
  334    ruleElem.setAttribute( QStringLiteral( 
"scalemaxdenom" ), mMinimumScale );
 
  335  if ( !mLabel.isEmpty() )
 
  336    ruleElem.setAttribute( QStringLiteral( 
"label" ), mLabel );
 
  337  if ( !mDescription.isEmpty() )
 
  338    ruleElem.setAttribute( QStringLiteral( 
"description" ), mDescription );
 
  340    ruleElem.setAttribute( QStringLiteral( 
"checkstate" ), 0 );
 
  341  ruleElem.setAttribute( QStringLiteral( 
"key" ), mRuleKey );
 
  343  const auto constMChildren = mChildren;
 
  344  for ( 
Rule *rule : constMChildren )
 
  346    ruleElem.
appendChild( rule->save( doc, symbolMap ) );
 
 
  355  if ( 
symbols( context ).isEmpty() )
 
  358  if ( !mFilterExp.isEmpty() )
 
  360    QString 
filter = props.value( QStringLiteral( 
"filter" ), QString() ).toString();
 
  362      filter += QLatin1String( 
" AND " );
 
  364    props[ QStringLiteral( 
"filter" )] = 
filter;
 
  371    QDomElement ruleElem = doc.createElement( QStringLiteral( 
"se:Rule" ) );
 
  372    element.appendChild( ruleElem );
 
  376    QDomElement nameElem = doc.createElement( QStringLiteral( 
"se:Name" ) );
 
  377    nameElem.appendChild( doc.createTextNode( mLabel ) );
 
  378    ruleElem.appendChild( nameElem );
 
  380    if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
 
  382      QDomElement descrElem = doc.createElement( QStringLiteral( 
"se:Description" ) );
 
  383      if ( !mLabel.isEmpty() )
 
  385        QDomElement titleElem = doc.createElement( QStringLiteral( 
"se:Title" ) );
 
  386        titleElem.appendChild( doc.createTextNode( mLabel ) );
 
  387        descrElem.appendChild( titleElem );
 
  389      if ( !mDescription.isEmpty() )
 
  391        QDomElement abstractElem = doc.createElement( QStringLiteral( 
"se:Abstract" ) );
 
  392        abstractElem.appendChild( doc.createTextNode( mDescription ) );
 
  393        descrElem.appendChild( abstractElem );
 
  395      ruleElem.appendChild( descrElem );
 
  398    if ( !props.value( QStringLiteral( 
"filter" ), QString() ).toString().isEmpty() )
 
  405    mSymbol->toSld( doc, ruleElem, props );
 
  409  const auto constMChildren = mChildren;
 
  410  for ( 
Rule *rule : constMChildren )
 
  412    rule->toSld( doc, element, props );
 
 
  418  mActiveChildren.clear();
 
  431    mSymbol->startRender( context, fields );
 
  435  QStringList subfilters;
 
  436  const auto constMChildren = mChildren;
 
  437  for ( 
Rule *rule : constMChildren )
 
  440    if ( rule->startRender( context, fields, subfilter ) )
 
  443      mActiveChildren.append( rule );
 
  444      subfilters.append( subfilter );
 
  452  if ( subfilters.length() > 1 || !subfilters.value( 0 ).isEmpty() )
 
  454    if ( subfilters.contains( QStringLiteral( 
"TRUE" ) ) )
 
  456      sf = QStringLiteral( 
"TRUE" );
 
  467      else if ( subfilters.count() > 50 )
 
  469        std::function<QString( 
const QStringList & )>bt = [ &bt ]( 
const QStringList & subf )
 
  471          if ( subf.count( ) == 1 )
 
  475          else if ( subf.count( ) == 2 )
 
  477            return subf.join( QLatin1String( 
") OR (" ) ).prepend( 
'(' ).append( 
')' );
 
  481            int midpos = 
static_cast<int>( subf.length() / 2 );
 
  482            return QStringLiteral( 
"(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ), bt( subf.mid( midpos ) ) );
 
  485        sf = bt( subfilters );
 
  489        sf = subfilters.join( QLatin1String( 
") OR (" ) ).prepend( 
'(' ).append( 
')' );
 
  501    if ( mSymbol || sf.isEmpty() )
 
  502      filter = QStringLiteral( 
"TRUE" );
 
  508  else if ( !mFilterExp.trimmed().isEmpty() && !sf.isEmpty() )
 
  509    filter = QStringLiteral( 
"(%1) AND (%2)" ).arg( mFilterExp, sf );
 
  510  else if ( !mFilterExp.trimmed().isEmpty() )
 
  512  else if ( sf.isEmpty() )
 
  513    filter = QStringLiteral( 
"TRUE" );
 
 
  524  return !mActiveChildren.empty();
 
 
  529  QSet<int> symbolZLevelsSet;
 
  535    for ( 
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
 
  537      symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
 
  542  QList<Rule *>::iterator it;
 
  543  for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
 
  548  return symbolZLevelsSet;
 
 
  555    for ( 
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
 
  557      int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
 
  558      mSymbolNormZLevels.insert( normLevel );
 
  563  const auto constMActiveChildren = mActiveChildren;
 
  564  for ( 
Rule *rule : constMActiveChildren )
 
 
  573  if ( !isFilterOK( featToRender.
feat, &context ) )
 
  576  bool rendered = 
false;
 
  579  if ( mSymbol && mIsActive )
 
  582    const auto constMSymbolNormZLevels = mSymbolNormZLevels;
 
  583    for ( 
int normZLevel : constMSymbolNormZLevels )
 
  586      renderQueue[normZLevel].jobs.append( 
new RenderJob( featToRender, mSymbol.get() ) );
 
  591  bool matchedAChild = 
false;
 
  594  const auto constMChildren = mChildren;
 
  595  for ( 
Rule *rule : constMChildren )
 
  598    if ( !rule->isElse() )
 
  600      const RenderResult res = rule->renderFeature( featToRender, context, renderQueue );
 
  602      matchedAChild |= ( res == Rendered || res == Inactive );
 
  603      rendered |= ( res == Rendered );
 
  608  if ( !matchedAChild )
 
  610    const auto constMElseRules = mElseRules;
 
  611    for ( 
Rule *rule : constMElseRules )
 
  613      const RenderResult res = rule->renderFeature( featToRender, context, renderQueue );
 
  614      matchedAChild |= ( res == Rendered || res == Inactive );
 
  615      rendered |= res == Rendered;
 
  618  if ( !mIsActive || ( mSymbol && !rendered ) || ( matchedAChild && !rendered ) )
 
 
  628  if ( !isFilterOK( feature, context ) )
 
  634  const auto constMActiveChildren = mActiveChildren;
 
  635  for ( 
Rule *rule : constMActiveChildren )
 
  637    if ( rule->isElse() )
 
  639      if ( rule->children().isEmpty() )
 
  641        RuleList lst = rulesForFeature( feature, context, 
false );
 
  642        lst.removeOne( rule );
 
  651        return rule->willRenderFeature( feature, context );
 
  654    else if ( rule->willRenderFeature( feature, context ) )
 
 
  665  if ( !isFilterOK( feature, context ) )
 
  668    lst.append( mSymbol.get() );
 
  670  const auto constMActiveChildren = mActiveChildren;
 
  671  for ( 
Rule *rule : constMActiveChildren )
 
  673    lst += rule->symbolsForFeature( feature, context );
 
 
  681  if ( !isFilterOK( feature, context ) )
 
  684  res.insert( mRuleKey );
 
  687  bool matchedNonElseRule = 
false;
 
  688  for ( 
Rule *rule : std::as_const( mActiveChildren ) )
 
  690    if ( rule->isElse() )
 
  694    if ( rule->willRenderFeature( feature, context ) )
 
  696      res.unite( rule->legendKeysForFeature( feature, context ) );
 
  697      matchedNonElseRule = 
true;
 
  702  if ( !matchedNonElseRule )
 
  704    for ( 
Rule *rule : std::as_const( mActiveChildren ) )
 
  706      if ( rule->isElse() )
 
  708        if ( rule->children().isEmpty() )
 
  710          RuleList lst = rulesForFeature( feature, context, 
false );
 
  711          lst.removeOne( rule );
 
  715            res.unite( rule->legendKeysForFeature( feature, context ) );
 
  720          res.unite( rule->legendKeysForFeature( feature, context ) );
 
 
  731  if ( ! isFilterOK( feature, context ) || ( context && ! isScaleOK( context->
rendererScale() ) ) )
 
  739    listChildren = mActiveChildren;
 
  741  const auto constListChildren = listChildren;
 
  742  for ( 
Rule *rule : constListChildren )
 
  744    lst += rule->rulesForFeature( feature, context, onlyActive );
 
 
  752    mSymbol->stopRender( context );
 
  754  const auto constMActiveChildren = mActiveChildren;
 
  755  for ( 
Rule *rule : constMActiveChildren )
 
  757    rule->stopRender( context );
 
  760  mActiveChildren.clear();
 
  761  mSymbolNormZLevels.clear();
 
 
  766  QString symbolIdx = ruleElem.attribute( QStringLiteral( 
"symbol" ) );
 
  768  if ( !symbolIdx.isEmpty() )
 
  770    if ( symbolMap.contains( symbolIdx ) )
 
  772      symbol = symbolMap.take( symbolIdx );
 
  776      QgsDebugError( 
"symbol for rule " + symbolIdx + 
" not found!" );
 
  780  QString filterExp = ruleElem.attribute( QStringLiteral( 
"filter" ) );
 
  781  QString label = ruleElem.attribute( QStringLiteral( 
"label" ) );
 
  782  QString description = ruleElem.attribute( QStringLiteral( 
"description" ) );
 
  783  int scaleMinDenom = ruleElem.attribute( QStringLiteral( 
"scalemindenom" ), QStringLiteral( 
"0" ) ).toInt();
 
  784  int scaleMaxDenom = ruleElem.attribute( QStringLiteral( 
"scalemaxdenom" ), QStringLiteral( 
"0" ) ).toInt();
 
  787    ruleKey = ruleElem.attribute( QStringLiteral( 
"key" ) );
 
  789    ruleKey = QUuid::createUuid().toString();
 
  790  Rule *rule = 
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
 
  792  if ( !ruleKey.isEmpty() )
 
  793    rule->mRuleKey = ruleKey;
 
  795  rule->
setActive( ruleElem.attribute( QStringLiteral( 
"checkstate" ), QStringLiteral( 
"1" ) ).toInt() );
 
  797  QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( 
"rule" ) );
 
  798  while ( !childRuleElem.isNull() )
 
  800    Rule *childRule = 
create( childRuleElem, symbolMap );
 
  807      QgsDebugError( QStringLiteral( 
"failed to init a child rule!" ) );
 
  809    childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( 
"rule" ) );
 
 
  828  if ( ruleElem.localName() != QLatin1String( 
"Rule" ) )
 
  830    QgsDebugError( QStringLiteral( 
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
 
  834  QString label, description, filterExp;
 
  835  int scaleMinDenom = 0, scaleMaxDenom = 0;
 
  839  QDomElement childElem = ruleElem.firstChildElement();
 
  840  while ( !childElem.isNull() )
 
  842    if ( childElem.localName() == QLatin1String( 
"Name" ) )
 
  846      if ( label.isEmpty() )
 
  847        label = childElem.firstChild().nodeValue();
 
  849    else if ( childElem.localName() == QLatin1String( 
"Description" ) )
 
  852      QDomElement titleElem = childElem.firstChildElement( QStringLiteral( 
"Title" ) );
 
  853      if ( !titleElem.isNull() )
 
  855        label = titleElem.firstChild().nodeValue();
 
  858      QDomElement abstractElem = childElem.firstChildElement( QStringLiteral( 
"Abstract" ) );
 
  859      if ( !abstractElem.isNull() )
 
  861        description = abstractElem.firstChild().nodeValue();
 
  864    else if ( childElem.localName() == QLatin1String( 
"Abstract" ) )
 
  867      description = childElem.firstChild().nodeValue();
 
  869    else if ( childElem.localName() == QLatin1String( 
"Title" ) )
 
  872      label = childElem.firstChild().nodeValue();
 
  874    else if ( childElem.localName() == QLatin1String( 
"Filter" ) )
 
  879        if ( 
filter->hasParserError() )
 
  885          filterExp = 
filter->expression();
 
  890    else if ( childElem.localName() == QLatin1String( 
"ElseFilter" ) )
 
  892      filterExp = QLatin1String( 
"ELSE" );
 
  895    else if ( childElem.localName() == QLatin1String( 
"MinScaleDenominator" ) )
 
  898      int v = childElem.firstChild().nodeValue().toInt( &ok );
 
  902    else if ( childElem.localName() == QLatin1String( 
"MaxScaleDenominator" ) )
 
  905      int v = childElem.firstChild().nodeValue().toInt( &ok );
 
  909    else if ( childElem.localName().endsWith( QLatin1String( 
"Symbolizer" ) ) )
 
  915    childElem = childElem.nextSiblingElement();
 
  920  if ( !layers.isEmpty() )
 
  943  return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
 
 
  978    bool drawVertexMarker )
 
 
  998  QList<int> symbolZLevels( symbolZLevelsSet.begin(), symbolZLevelsSet.end() );
 
  999  std::sort( symbolZLevels.begin(), symbolZLevels.end() );
 
 1003  QMap<int, int> zLevelsToNormLevels;
 
 1004  int maxNormLevel = -1;
 
 1005  const auto constSymbolZLevels = symbolZLevels;
 
 1006  for ( 
int zLevel : constSymbolZLevels )
 
 1008    zLevelsToNormLevels[zLevel] = ++maxNormLevel;
 
 1010    QgsDebugMsgLevel( QStringLiteral( 
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ), 4 );
 
 
 1033    for ( 
const RenderLevel &level : constMRenderQueue )
 
 1037      for ( 
const RenderJob *job : std::as_const( level.jobs ) )
 
 1044        for ( 
int i = 0; i < count; i++ )
 
 1051            int flags = job->ftr.flags;
 
 
 1093  Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
 
 1094  for ( 
int i = 0; i < origDescendants.count(); ++i )
 
 1095    clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
 
 
 1117  rendererElem.setAttribute( QStringLiteral( 
"type" ), QStringLiteral( 
"RuleRenderer" ) );
 
 1122  rulesElem.setTagName( QStringLiteral( 
"rules" ) ); 
 
 1123  rendererElem.appendChild( rulesElem );
 
 1126  rendererElem.appendChild( symbolsElem );
 
 1130  return rendererElem;
 
 
 1141  return rule ? rule->
active() : 
true;
 
 
 1158  std::function<QString( 
Rule *rule )> ruleToExpression;
 
 1159  ruleToExpression = [&ruleToExpression]( 
Rule * rule ) -> QString
 
 1165      QStringList otherRules;
 
 1166      const QList<QgsRuleBasedRenderer::Rule *> siblings = rule->
parent()->
children();
 
 1167      for ( 
Rule *sibling : siblings )
 
 1169        if ( sibling == rule || sibling->
isElse() )
 
 1172        const QString siblingExpression = ruleToExpression( sibling );
 
 1173        if ( siblingExpression.isEmpty() )
 
 1174          return QStringLiteral( 
"FALSE" ); 
 
 1176        otherRules.append( siblingExpression );
 
 1179      if ( otherRules.empty() )
 
 1180        return QStringLiteral( 
"TRUE" ); 
 
 1183                 otherRules.size() > 1
 
 1184                 ?  QStringLiteral( 
"NOT ((%1))" ).arg( otherRules.join( QLatin1String( 
") OR (" ) ) )
 
 1185                 : QStringLiteral( 
"NOT (%1)" ).arg( otherRules.at( 0 ) )
 
 1190      QStringList ruleParts;
 
 1195        ruleParts.append( QStringLiteral( 
"@map_scale <= %1" ).arg( rule->
minimumScale() ) );
 
 1198        ruleParts.append( QStringLiteral( 
"@map_scale >= %1" ).arg( rule->
maximumScale() ) );
 
 1200      if ( !ruleParts.empty() )
 
 1203                 ruleParts.size() > 1
 
 1204                 ?  QStringLiteral( 
"(%1)" ).arg( ruleParts.join( QLatin1String( 
") AND (" ) ) )
 
 1218    const QString ruleFilter = ruleToExpression( rule );
 
 1219    if ( !ruleFilter.isEmpty() )
 
 1220      parts.append( ruleFilter );
 
 1226  return parts.empty() ? QStringLiteral( 
"TRUE" )
 
 1227         : ( parts.size() > 1
 
 1228             ?  QStringLiteral( 
"(%1)" ).arg( parts.join( QLatin1String( 
") AND (" ) ) )
 
 
 1250  QDomElement symbolsElem = element.firstChildElement( QStringLiteral( 
"symbols" ) );
 
 1251  if ( symbolsElem.isNull() )
 
 1256  QDomElement rulesElem = element.firstChildElement( QStringLiteral( 
"rules" ) );
 
 
 1273  Rule *root = 
nullptr;
 
 1275  QDomElement ruleElem = element.firstChildElement( QStringLiteral( 
"Rule" ) );
 
 1276  while ( !ruleElem.isNull() )
 
 1283        root = 
new Rule( 
nullptr );
 
 1288    ruleElem = ruleElem.nextSiblingElement( QStringLiteral( 
"Rule" ) );
 
 
 1316  const auto constCategories = r->
categories();
 
 1323    else if ( cat.value().userType() == QMetaType::Type::Int )
 
 1324      value = cat.value().toString();
 
 1325    else if ( cat.value().userType() == QMetaType::Type::Double )
 
 1328      value = QString::number( cat.value().toDouble(), 
'f', 4 );
 
 1331    const QString 
filter = QStringLiteral( 
"%1 %2 %3" ).arg( attr, 
QgsVariantUtils::isNull( cat.value() ) ? QStringLiteral( 
"IS" ) : QStringLiteral( 
"=" ), value );
 
 1332    const QString label = !cat.label().isEmpty() ? cat.label() :
 
 1333                          cat.value().isValid() ? value : QString();
 
 
 1349  else if ( !testExpr.
isField() )
 
 1352    attr = QStringLiteral( 
"(%1)" ).arg( attr );
 
 1355  bool firstRange = 
true;
 
 1356  const auto constRanges = r->
ranges();
 
 1361    QString 
filter = QStringLiteral( 
"%1 %2 %3 AND %1 <= %4" ).arg( attr, firstRange ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
 1362                     QString::number( rng.lowerValue(), 
'f', 4 ),
 
 1363                     QString::number( rng.upperValue(), 
'f', 4 ) );
 
 1365    QString label = rng.label().isEmpty() ? 
filter : rng.label();
 
 
 1372  std::sort( scales.begin(), scales.end() ); 
 
 1376  const auto constScales = scales;
 
 1377  for ( 
int scale : constScales )
 
 1381    if ( maxDenom != 0 && maxDenom  <= scale )
 
 1383    initialRule->
appendChild( 
new Rule( symbol->
clone(), oldScale, scale, QString(), QStringLiteral( 
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
 
 1387  initialRule->
appendChild( 
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QStringLiteral( 
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
 
 
 1392  QString msg( QStringLiteral( 
"Rule-based renderer:\n" ) );
 
 
 1424  std::unique_ptr< QgsRuleBasedRenderer > r;
 
 1425  if ( renderer->
type() == QLatin1String( 
"RuleRenderer" ) )
 
 1429  else if ( renderer->
type() == QLatin1String( 
"singleSymbol" ) )
 
 1432    if ( !singleSymbolRenderer )
 
 1435    std::unique_ptr< QgsSymbol > origSymbol( singleSymbolRenderer->
symbol()->
clone() );
 
 1436    r = std::make_unique< QgsRuleBasedRenderer >( origSymbol.release() );
 
 1438  else if ( renderer->
type() == QLatin1String( 
"categorizedSymbol" ) )
 
 1441    if ( !categorizedRenderer )
 
 1446    bool isField = 
false;
 
 1456    if ( isField && !attr.contains( 
'\"' ) )
 
 1462    std::unique_ptr< QgsRuleBasedRenderer::Rule > rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1469      std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1471      rule->setLabel( category.
label() );
 
 1474      if ( category.
value().userType() == QMetaType::Type::QVariantList )
 
 1477        const QVariantList list = category.
value().toList();
 
 1478        for ( 
const QVariant &v : list )
 
 1481          if ( QVariant( v ).convert( QMetaType::Type::Double ) )
 
 1483            values << v.toString();
 
 1491        if ( values.empty() )
 
 1493          expression = QStringLiteral( 
"ELSE" );
 
 1497          expression = QStringLiteral( 
"%1 IN (%2)" ).arg( attr, values.join( 
',' ) );
 
 1503        if ( category.
value().convert( QMetaType::Type::Double ) )
 
 1505          value = category.
value().toString();
 
 1513        if ( value == QLatin1String( 
"''" ) )
 
 1515          expression = QStringLiteral( 
"ELSE" );
 
 1519          expression = QStringLiteral( 
"%1 = %2" ).arg( attr, value );
 
 1522      rule->setFilterExpression( expression );
 
 1528      std::unique_ptr< QgsSymbol > origSymbol( category.
symbol()->
clone() );
 
 1529      rule->setSymbol( origSymbol.release() );
 
 1531      rootrule->appendChild( rule.release() );
 
 1534    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 1536  else if ( renderer->
type() == QLatin1String( 
"graduatedSymbol" ) )
 
 1539    if ( !graduatedRenderer )
 
 1545    bool isField = 
false;
 
 1555    if ( isField  && !attr.contains( 
'\"' ) )
 
 1560    else if ( !isField )
 
 1563      attr = QStringLiteral( 
"(%1)" ).arg( attr );
 
 1566    std::unique_ptr< QgsRuleBasedRenderer::Rule > rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1570    for ( 
int i = 0; i < graduatedRenderer->
ranges().size(); ++i )
 
 1572      range = graduatedRenderer->
ranges().value( i );
 
 1573      std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1574      rule->setLabel( range.
label() );
 
 1577        expression = attr + 
" >= " + QString::number( range.
lowerValue(), 
'f' ) + 
" AND " + \
 
 1578                     attr + 
" <= " + QString::number( range.
upperValue(), 
'f' );
 
 1582        expression = attr + 
" > " + QString::number( range.
lowerValue(), 
'f' ) + 
" AND " + \
 
 1583                     attr + 
" <= " + QString::number( range.
upperValue(), 
'f' );
 
 1585      rule->setFilterExpression( expression );
 
 1591      std::unique_ptr< QgsSymbol > symbol( range.
symbol()->
clone() );
 
 1592      rule->setSymbol( symbol.release() );
 
 1594      rootrule->appendChild( rule.release() );
 
 1597    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 1599  else if ( renderer->
type() == QLatin1String( 
"pointDisplacement" ) || renderer->
type() == QLatin1String( 
"pointCluster" ) )
 
 1604  else if ( renderer->
type() == QLatin1String( 
"invertedPolygonRenderer" ) )
 
 1609  else if ( renderer->
type() == QLatin1String( 
"mergedFeatureRenderer" ) )
 
 1614  else if ( renderer->
type() == QLatin1String( 
"embeddedSymbol" ) && layer )
 
 1618    std::unique_ptr< QgsRuleBasedRenderer::Rule > rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1625    while ( it.
nextFeature( feature ) && rootrule->children().size() < 500 )
 
 1629        std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1630        rule->setFilterExpression( QStringLiteral( 
"$id=%1" ).arg( feature.
id() ) );
 
 1631        rule->setLabel( QString::number( feature.
id() ) );
 
 1633        rootrule->appendChild( rule.release() );
 
 1637    std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1638    rule->setFilterExpression( QStringLiteral( 
"ELSE" ) );
 
 1639    rule->setLabel( QObject::tr( 
"All other features" ) );
 
 1641    rootrule->appendChild( rule.release() );
 
 1643    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 
 1656  QString sizeExpression;
 
 1657  switch ( symbol->
type() )
 
 1663        if ( ! sizeScaleField.isEmpty() )
 
 1665          sizeExpression = QStringLiteral( 
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
 
 1668        if ( ! rotationField.isEmpty() )
 
 1675      if ( ! sizeScaleField.isEmpty() )
 
 1682            sizeExpression = QStringLiteral( 
"%1*(%2)" ).arg( lsl->
width() ).arg( sizeScaleField );
 
 1691              sizeExpression = QStringLiteral( 
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
 
 
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
 
@ EmbeddedSymbols
Retrieve any embedded feature symbology (since QGIS 3.20)
 
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
 
const QgsCategoryList & categories() const
Returns a list of all categories recognized by the renderer.
 
QString classAttribute() const
Returns the class attribute for the renderer, which is the field name or expression string from the l...
 
A vector feature renderer which uses embedded feature symbology to render per-feature symbols.
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
 
Class for parsing and evaluation of expressions (formerly called "search strings").
 
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
 
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
 
bool isField() const
Checks whether an expression consists only of a single field reference.
 
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
 
static int expressionToLayerFieldIndex(const QString &expression, const QgsVectorLayer *layer)
Attempts to resolve an expression to a field index from the given layer.
 
static bool attemptReduceToInClause(const QStringList &expressions, QString &result)
Attempts to reduce a list of expressions to a single "field IN (val1, val2, ... )" type expression.
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
 
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
 
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
 
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
 
void renderFeatureWithSymbol(const QgsFeature &feature, QgsSymbol *symbol, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker)
Render the feature with the symbol using context.
 
virtual const QgsFeatureRenderer * embeddedRenderer() const
Returns the current embedded renderer (subrenderer) for this feature renderer.
 
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
 
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
 
This class wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
 
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
const QgsSymbol * embeddedSymbol() const
Returns the feature's embedded symbology, or nullptr if the feature has no embedded symbol.
 
Container of fields for a vector layer.
 
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
 
QString classAttribute() const
Returns the attribute name (or expression) used for the classification.
 
const QgsRangeList & ranges() const
Returns a list of all ranges used in the classification.
 
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted,...
 
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
 
virtual double width() const
Returns the estimated width for the line symbol layer.
 
A line symbol type, for rendering LineString and MultiLineString geometries.
 
Abstract base class for marker symbol layers.
 
double size() const
Returns the symbol size.
 
A marker symbol type, for rendering Point and MultiPoint geometries.
 
QgsMergedFeatureRenderer is a polygon or line-only feature renderer used to renderer a set of feature...
 
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
 
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
 
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
 
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
 
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.
 
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
 
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
 
QgsSymbol * symbol() const
Returns the symbol which will be used to render this category.
 
QVariant value() const
Returns the value corresponding to this category.
 
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
 
QString label() const
Returns the label used for the range.
 
QgsSymbol * symbol() const
Returns the symbol used for the range.
 
double upperValue() const
Returns the upper bound of the range.
 
double lowerValue() const
Returns the lower bound of the range.
 
This class keeps data about a rules for rule-based renderer.
 
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all child rules associated with the rule...
 
QgsRuleBasedRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra... you get it.
 
void setSymbol(QgsSymbol *sym)
Sets a new symbol (or nullptr). Deletes old symbol.
 
void removeChild(QgsRuleBasedRenderer::Rule *rule)
delete child rule
 
QgsRuleBasedRenderer::Rule * findRuleByKey(const QString &key)
Try to find a rule given its unique key.
 
void insertChild(int i, QgsRuleBasedRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
 
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
 
bool needsGeometry() const
Returns true if this rule or one of its children needs the geometry to be applied.
 
QgsRuleBasedRenderer::Rule * takeChild(QgsRuleBasedRenderer::Rule *rule)
take child rule out, set parent as nullptr
 
const QgsRuleBasedRenderer::RuleList & children() const
Returns all children rules of this rule.
 
RenderResult
The result of rendering a rule.
 
@ Rendered
Something was rendered.
 
QgsRuleBasedRenderer::RuleList rulesForFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr, bool onlyActive=true)
Returns the list of rules used to render the feature in a specific context.
 
double maximumScale() const
Returns the maximum map scale (i.e.
 
QgsRuleBasedRenderer::Rule * parent()
The parent rule.
 
void setIsElse(bool iselse)
Sets if this rule is an ELSE rule.
 
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
tell which symbols will be used to render the feature
 
bool isElse() const
Check if this rule is an ELSE rule.
 
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
Returns which legend keys match the feature.
 
QgsRuleBasedRenderer::Rule * clone() const
clone this rule, return new instance
 
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
only tell whether a feature will be rendered without actually rendering it
 
void removeChildAt(int i)
delete child rule
 
void setActive(bool state)
Sets if this rule is active.
 
Rule(QgsSymbol *symbol, int maximumScale=0, int minimumScale=0, const QString &filterExp=QString(), const QString &label=QString(), const QString &description=QString(), bool elseRule=false)
Constructor takes ownership of the symbol.
 
bool isFilterOK(const QgsFeature &f, QgsRenderContext *context=nullptr) const
Check if a given feature shall be rendered by this rule.
 
QgsSymbolList symbols(const QgsRenderContext &context=QgsRenderContext()) const
 
bool isScaleOK(double scale) const
Check if this rule applies for a given scale.
 
static QgsRuleBasedRenderer::Rule * createFromSld(QDomElement &element, Qgis::GeometryType geomType)
Create a rule from the SLD provided in element and for the specified geometry type.
 
void setNormZLevels(const QMap< int, int > &zLevelsToNormLevels)
assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering
 
QDomElement save(QDomDocument &doc, QgsSymbolMap &symbolMap) const
 
void appendChild(QgsRuleBasedRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
 
QgsRuleBasedRenderer::Rule * takeChildAt(int i)
take child rule out, set parent as nullptr
 
QSet< int > collectZLevels()
Gets all used z-levels from this rule and children.
 
double minimumScale() const
Returns the minimum map scale (i.e.
 
void stopRender(QgsRenderContext &context)
Stop a rendering process.
 
bool hasActiveChildren() const
Returns true if the rule has any active children.
 
QgsRuleBasedRenderer::Rule::RenderResult renderFeature(QgsRuleBasedRenderer::FeatureToRender &featToRender, QgsRenderContext &context, QgsRuleBasedRenderer::RenderQueue &renderQueue)
Render a given feature, will recursively call subclasses and only render if the constraints apply.
 
QgsLegendSymbolList legendSymbolItems(int currentLevel=-1) const
 
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the attributes used to evaluate the expression of this rule.
 
void setFilterExpression(const QString &filterExp)
Set the expression used to check if a given feature shall be rendered with this rule.
 
QString dump(int indent=0) const
Dump for debug purpose.
 
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer)
 
bool startRender(QgsRenderContext &context, const QgsFields &fields, QString &filter)
prepare the rule for rendering and its children (build active children array)
 
static QgsRuleBasedRenderer::Rule * create(QDomElement &ruleElem, QgsSymbolMap &symbolMap, bool reuseId=true)
Create a rule from an XML definition.
 
QString filterExpression() const
A filter that will check if this rule applies.
 
bool active() const
Returns if this rule is active.
 
void toSld(QDomDocument &doc, QDomElement &element, QVariantMap props) const
Saves the symbol layer as SLD.
 
static void refineRuleCategories(QgsRuleBasedRenderer::Rule *initialRule, QgsCategorizedSymbolRenderer *r)
take a rule and create a list of new rules based on the categories from categorized symbol renderer
 
static void convertToDataDefinedSymbology(QgsSymbol *symbol, const QString &sizeScaleField, const QString &rotationField=QString())
helper function to convert the size scale and rotation fields present in some other renderers to data...
 
bool legendSymbolItemChecked(const QString &key) override
Returns true if the legend symbology item with the specified key is checked.
 
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
 
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
 
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
 
bool canSkipRender() override
Returns true if the renderer can be entirely skipped, i.e.
 
void checkLegendSymbolItem(const QString &key, bool state=true) override
Sets whether the legend symbology item with the specified ley should be checked.
 
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for current feature. Should not be used individually: there could be more symbols for ...
 
QList< QgsRuleBasedRenderer::RenderLevel > RenderQueue
Rendering queue: a list of rendering levels.
 
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
 
static void refineRuleRanges(QgsRuleBasedRenderer::Rule *initialRule, QgsGraduatedSymbolRenderer *r)
take a rule and create a list of new rules based on the ranges from graduated symbol renderer
 
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
 
QString dump() const override
Returns debug information about this renderer.
 
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
 
static QgsRuleBasedRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer, QgsVectorLayer *layer=nullptr)
Creates a new QgsRuleBasedRenderer from an existing renderer.
 
bool legendSymbolItemsCheckable() const override
Returns true if symbology items in legend are checkable.
 
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
 
QString filter(const QgsFields &fields=QgsFields()) override
If a renderer does not require all the features this method may be overridden and return an expressio...
 
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
 
static void refineRuleScales(QgsRuleBasedRenderer::Rule *initialRule, QList< int > scales)
take a rule and create a list of new rules with intervals of scales given by the passed scale denomin...
 
QList< QgsRuleBasedRenderer::Rule * > RuleList
 
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
 
Rule * mRootRule
the root node with hierarchical list of rules
 
~QgsRuleBasedRenderer() override
 
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
 
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
 
QgsRuleBasedRenderer * clone() const override
Create a deep copy of this renderer.
 
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a new rule-based renderer instance from XML.
 
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
 
static QgsFeatureRenderer * createFromSld(QDomElement &element, Qgis::GeometryType geomType)
Creates a new rule based renderer from an SLD XML element.
 
QList< FeatureToRender > mCurrentFeatures
 
QString legendKeyToExpression(const QString &key, QgsVectorLayer *layer, bool &ok) const override
Attempts to convert the specified legend rule key to a QGIS expression matching the features displaye...
 
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Render a feature using this renderer in the given context.
 
QgsRuleBasedRenderer(QgsRuleBasedRenderer::Rule *root)
Constructs the renderer from given tree of rules (takes ownership)
 
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
 
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const override
used from subclasses to create SLD Rule elements following SLD v1.1 specs
 
QgsSymbol * symbol() const
Returns the symbol which will be rendered for every feature.
 
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 symbol 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 bool createSymbolLayerListFromSld(QDomElement &element, Qgis::GeometryType geomType, QList< QgsSymbolLayer * > &layers)
Creates a symbol layer list from a DOM 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.
 
static void clearSymbolMap(QgsSymbolMap &symbols)
 
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
 
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
 
@ StrokeWidth
Stroke width.
 
virtual QString layerType() const =0
Returns a string that represents this layer type.
 
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
 
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
 
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
 
Abstract base class for all rendered symbols.
 
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
 
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
 
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
 
Qgis::SymbolType type() const
Returns the symbol's type.
 
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
 
Represents a vector layer which manages a vector based data sets.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
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
 
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QList< QgsLegendSymbolItem > QgsLegendSymbolList
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)
 
#define RENDERER_TAG_NAME
 
QMap< QString, QgsSymbol * > QgsSymbolMap
 
QList< QgsSymbol * > QgsSymbolList
 
QList< QgsSymbolLayer * > QgsSymbolLayerList
 
Feature for rendering by a QgsRuleBasedRenderer.
 
A QgsRuleBasedRenderer rendering job, consisting of a feature to be rendered with a particular symbol...
 
Render level: a list of jobs to be drawn at particular level for a QgsRuleBasedRenderer.
 
Contains information relating to a node (i.e.
 
Contains information relating to the style entity currently being visited.