38#include <QDomDocument> 
   46  , mMaximumScale( scaleMinDenom )
 
   47  , mMinimumScale( scaleMaxDenom )
 
   48  , mFilterExp( filterExp )
 
   50  , mDescription( description )
 
   51  , mElseRule( elseRule )
 
   54    mFilterExp = QStringLiteral( 
"ELSE" );
 
   56  mRuleKey = QUuid::createUuid().toString();
 
 
   62  qDeleteAll( mChildren );
 
 
   68  if ( mFilterExp.trimmed().compare( QLatin1String( 
"ELSE" ), Qt::CaseInsensitive ) == 0 )
 
   73  else if ( mFilterExp.trimmed().isEmpty() )
 
   81    mFilter = std::make_unique< QgsExpression >( mFilterExp );
 
 
   87  mChildren.append( rule );
 
 
   94  mChildren.insert( i, rule );
 
 
  101  mChildren.removeAll( rule );
 
 
  108  delete mChildren.takeAt( i );
 
 
  114  mChildren.removeAll( rule );
 
  115  rule->mParent = 
nullptr;
 
 
  122  Rule *rule = mChildren.takeAt( i );
 
  123  rule->mParent = 
nullptr;
 
 
  132  if ( key == mRuleKey )
 
  135  const auto constMChildren = mChildren;
 
  136  for ( 
Rule *rule : constMChildren )
 
 
  145void QgsRuleBasedRenderer::Rule::updateElseRules()
 
  148  const auto constMChildren = mChildren;
 
  149  for ( 
Rule *rule : constMChildren )
 
  151    if ( rule->isElse() )
 
  158  mFilterExp = QStringLiteral( 
"ELSE" );
 
 
  176  if ( !mChildren.empty() )
 
  178    for ( 
const Rule *rule : mChildren )
 
  181      if ( !rule->accept( visitor ) )
 
 
  195  off.fill( QChar( 
' ' ), indent );
 
  196  QString symbolDump = ( mSymbol ? mSymbol->dump() : QStringLiteral( 
"[]" ) );
 
  197  QString msg = off + QStringLiteral( 
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
 
  198                .arg( mLabel ).arg( mMaximumScale ).arg( mMinimumScale )
 
  199                .arg( mFilterExp, symbolDump );
 
  202  const auto constMChildren = mChildren;
 
  203  for ( 
Rule *rule : constMChildren )
 
  205    lst.append( rule->dump( indent + 2 ) );
 
  207  msg += lst.join( QLatin1Char( 
'\n' ) );
 
 
  216    attrs.unite( 
mFilter->referencedColumns() );
 
  218    attrs.unite( mSymbol->usedAttributes( context ) );
 
  221  const auto constMChildren = mChildren;
 
  222  for ( 
Rule *rule : constMChildren )
 
  224    attrs.unite( rule->usedAttributes( context ) );
 
 
  234  const auto constMChildren = mChildren;
 
  235  for ( 
Rule *rule : constMChildren )
 
  237    if ( rule->needsGeometry() )
 
 
  248    lst.append( mSymbol.get() );
 
  250  const auto constMChildren = mChildren;
 
  251  for ( 
Rule *rule : constMChildren )
 
  253    lst += rule->symbols( context );
 
 
  260  mSymbol.reset( sym );
 
 
  265  mFilterExp = filterExp;
 
 
  272  if ( currentLevel != -1 ) 
 
  274    lst << 
QgsLegendSymbolItem( mSymbol.get(), mLabel, mRuleKey, 
true, mMaximumScale, mMinimumScale, currentLevel, mParent ? mParent->mRuleKey : QString() );
 
  277  for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
 
 
  288  if ( ! 
mFilter || mElseRule || ! context )
 
 
  317  Rule *newrule = 
new Rule( sym, mMaximumScale, mMinimumScale, mFilterExp, mLabel, mDescription );
 
  320  const auto constMChildren = mChildren;
 
  321  for ( 
Rule *rule : constMChildren )
 
 
  328  QDomElement ruleElem = doc.createElement( QStringLiteral( 
"rule" ) );
 
  332    int symbolIndex = symbolMap.size();
 
  333    symbolMap[QString::number( symbolIndex )] = mSymbol.get();
 
  334    ruleElem.setAttribute( QStringLiteral( 
"symbol" ), symbolIndex );
 
  336  if ( !mFilterExp.isEmpty() )
 
  337    ruleElem.setAttribute( QStringLiteral( 
"filter" ), mFilterExp );
 
  338  if ( mMaximumScale != 0 )
 
  339    ruleElem.setAttribute( QStringLiteral( 
"scalemindenom" ), mMaximumScale );
 
  340  if ( mMinimumScale != 0 )
 
  341    ruleElem.setAttribute( QStringLiteral( 
"scalemaxdenom" ), mMinimumScale );
 
  342  if ( !mLabel.isEmpty() )
 
  343    ruleElem.setAttribute( QStringLiteral( 
"label" ), mLabel );
 
  344  if ( !mDescription.isEmpty() )
 
  345    ruleElem.setAttribute( QStringLiteral( 
"description" ), mDescription );
 
  347    ruleElem.setAttribute( QStringLiteral( 
"checkstate" ), 0 );
 
  348  ruleElem.setAttribute( QStringLiteral( 
"key" ), mRuleKey );
 
  350  const auto constMChildren = mChildren;
 
  351  for ( 
Rule *rule : constMChildren )
 
  353    ruleElem.
appendChild( rule->save( doc, symbolMap ) );
 
 
  362  toSld( doc, element, context );
 
 
  369  if ( 
symbols( context ).isEmpty() )
 
  373  QVariantMap props = oldProps;
 
  374  if ( !mFilterExp.isEmpty() )
 
  376    QString 
filter = props.value( QStringLiteral( 
"filter" ), QString() ).toString();
 
  378      filter += QLatin1String( 
" AND " );
 
  380    props[ QStringLiteral( 
"filter" )] = 
filter;
 
  388    QDomElement ruleElem = doc.createElement( QStringLiteral( 
"se:Rule" ) );
 
  392    QDomElement nameElem = doc.createElement( QStringLiteral( 
"se:Name" ) );
 
  393    nameElem.appendChild( doc.createTextNode( mLabel ) );
 
  394    ruleElem.appendChild( nameElem );
 
  396    if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
 
  398      QDomElement descrElem = doc.createElement( QStringLiteral( 
"se:Description" ) );
 
  399      if ( !mLabel.isEmpty() )
 
  401        QDomElement titleElem = doc.createElement( QStringLiteral( 
"se:Title" ) );
 
  402        titleElem.appendChild( doc.createTextNode( mLabel ) );
 
  403        descrElem.appendChild( titleElem );
 
  405      if ( !mDescription.isEmpty() )
 
  407        QDomElement abstractElem = doc.createElement( QStringLiteral( 
"se:Abstract" ) );
 
  408        abstractElem.appendChild( doc.createTextNode( mDescription ) );
 
  409        descrElem.appendChild( abstractElem );
 
  411      ruleElem.appendChild( descrElem );
 
  414    if ( !props.value( QStringLiteral( 
"filter" ), QString() ).toString().isEmpty() )
 
  422    mSymbol->toSld( doc, ruleElem, exportContext );
 
  428      element.appendChild( ruleElem );
 
  434  for ( 
Rule *rule : std::as_const( mChildren ) )
 
  436    if ( !rule->toSld( doc, element, exportContext ) )
 
 
  445  mActiveChildren.clear();
 
  458    mSymbol->startRender( context, fields );
 
  462  QStringList subfilters;
 
  463  const auto constMChildren = mChildren;
 
  464  for ( 
Rule *rule : constMChildren )
 
  467    if ( rule->startRender( context, fields, subfilter ) )
 
  470      mActiveChildren.append( rule );
 
  471      subfilters.append( subfilter );
 
  479  if ( subfilters.length() > 1 || !subfilters.value( 0 ).isEmpty() )
 
  481    if ( subfilters.contains( QStringLiteral( 
"TRUE" ) ) )
 
  483      sf = QStringLiteral( 
"TRUE" );
 
  494      else if ( subfilters.count() > 50 )
 
  496        std::function<QString( 
const QStringList & )>bt = [ &bt ]( 
const QStringList & subf )
 
  498          if ( subf.count( ) == 1 )
 
  502          else if ( subf.count( ) == 2 )
 
  504            return subf.join( QLatin1String( 
") OR (" ) ).prepend( 
'(' ).append( 
')' );
 
  508            int midpos = 
static_cast<int>( subf.length() / 2 );
 
  509            return QStringLiteral( 
"(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ), bt( subf.mid( midpos ) ) );
 
  512        sf = bt( subfilters );
 
  516        sf = subfilters.join( QLatin1String( 
") OR (" ) ).prepend( 
'(' ).append( 
')' );
 
  528    if ( mSymbol || sf.isEmpty() )
 
  529      filter = QStringLiteral( 
"TRUE" );
 
  535  else if ( !mFilterExp.trimmed().isEmpty() && !sf.isEmpty() )
 
  536    filter = QStringLiteral( 
"(%1) AND (%2)" ).arg( mFilterExp, sf );
 
  537  else if ( !mFilterExp.trimmed().isEmpty() )
 
  539  else if ( sf.isEmpty() )
 
  540    filter = QStringLiteral( 
"TRUE" );
 
 
  551  return !mActiveChildren.empty();
 
 
  556  QSet<int> symbolZLevelsSet;
 
  562    for ( 
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
 
  564      symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
 
  569  QList<Rule *>::iterator it;
 
  570  for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
 
  575  return symbolZLevelsSet;
 
 
  582    for ( 
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
 
  584      int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
 
  585      mSymbolNormZLevels.insert( normLevel );
 
  590  const auto constMActiveChildren = mActiveChildren;
 
  591  for ( 
Rule *rule : constMActiveChildren )
 
 
  600  if ( !isFilterOK( featToRender.
feat, &context ) )
 
  603  bool rendered = 
false;
 
  606  if ( mSymbol && mIsActive )
 
  609    const auto constMSymbolNormZLevels = mSymbolNormZLevels;
 
  610    for ( 
int normZLevel : constMSymbolNormZLevels )
 
  613      renderQueue[normZLevel].jobs.append( 
new RenderJob( featToRender, mSymbol.get() ) );
 
  618  bool matchedAChild = 
false;
 
  621  const auto constMChildren = mChildren;
 
  622  for ( 
Rule *rule : constMChildren )
 
  625    if ( !rule->isElse() )
 
  627      const RenderResult res = rule->renderFeature( featToRender, context, renderQueue );
 
  629      matchedAChild |= ( res == Rendered || res == Inactive );
 
  630      rendered |= ( res == Rendered );
 
  635  if ( !matchedAChild )
 
  637    const auto constMElseRules = mElseRules;
 
  638    for ( 
Rule *rule : constMElseRules )
 
  640      const RenderResult res = rule->renderFeature( featToRender, context, renderQueue );
 
  641      matchedAChild |= ( res == Rendered || res == Inactive );
 
  642      rendered |= res == Rendered;
 
  645  if ( !mIsActive || ( mSymbol && !rendered ) || ( matchedAChild && !rendered ) )
 
 
  655  if ( !isFilterOK( feature, context ) )
 
  661  const auto constMActiveChildren = mActiveChildren;
 
  662  for ( 
Rule *rule : constMActiveChildren )
 
  664    if ( rule->isElse() )
 
  666      if ( rule->children().isEmpty() )
 
  668        RuleList lst = rulesForFeature( feature, context, 
false );
 
  669        lst.removeOne( rule );
 
  678        return rule->willRenderFeature( feature, context );
 
  681    else if ( rule->willRenderFeature( feature, context ) )
 
 
  692  if ( !isFilterOK( feature, context ) )
 
  695    lst.append( mSymbol.get() );
 
  697  const auto constMActiveChildren = mActiveChildren;
 
  698  for ( 
Rule *rule : constMActiveChildren )
 
  700    lst += rule->symbolsForFeature( feature, context );
 
 
  708  if ( !isFilterOK( feature, context ) )
 
  711  res.insert( mRuleKey );
 
  714  bool matchedNonElseRule = 
false;
 
  715  for ( 
Rule *rule : std::as_const( mActiveChildren ) )
 
  717    if ( rule->isElse() )
 
  721    if ( rule->willRenderFeature( feature, context ) )
 
  723      res.unite( rule->legendKeysForFeature( feature, context ) );
 
  724      matchedNonElseRule = 
true;
 
  729  if ( !matchedNonElseRule )
 
  731    for ( 
Rule *rule : std::as_const( mActiveChildren ) )
 
  733      if ( rule->isElse() )
 
  735        if ( rule->children().isEmpty() )
 
  737          RuleList lst = rulesForFeature( feature, context, 
false );
 
  738          lst.removeOne( rule );
 
  742            res.unite( rule->legendKeysForFeature( feature, context ) );
 
  747          res.unite( rule->legendKeysForFeature( feature, context ) );
 
 
  758  if ( ! isFilterOK( feature, context ) || ( context && ! isScaleOK( context->
rendererScale() ) ) )
 
  766    listChildren = mActiveChildren;
 
  768  for ( 
Rule *rule : std::as_const( listChildren ) )
 
  770    lst += rule->rulesForFeature( feature, context, onlyActive );
 
 
  778    mSymbol->stopRender( context );
 
  780  const auto constMActiveChildren = mActiveChildren;
 
  781  for ( 
Rule *rule : constMActiveChildren )
 
  783    rule->stopRender( context );
 
  786  mActiveChildren.clear();
 
  787  mSymbolNormZLevels.clear();
 
 
  792  QString symbolIdx = ruleElem.attribute( QStringLiteral( 
"symbol" ) );
 
  794  if ( !symbolIdx.isEmpty() )
 
  796    if ( symbolMap.contains( symbolIdx ) )
 
  798      symbol = symbolMap.take( symbolIdx );
 
  802      QgsDebugError( 
"symbol for rule " + symbolIdx + 
" not found!" );
 
  806  QString filterExp = ruleElem.attribute( QStringLiteral( 
"filter" ) );
 
  807  QString label = ruleElem.attribute( QStringLiteral( 
"label" ) );
 
  808  QString description = ruleElem.attribute( QStringLiteral( 
"description" ) );
 
  809  int scaleMinDenom = ruleElem.attribute( QStringLiteral( 
"scalemindenom" ), QStringLiteral( 
"0" ) ).toInt();
 
  810  int scaleMaxDenom = ruleElem.attribute( QStringLiteral( 
"scalemaxdenom" ), QStringLiteral( 
"0" ) ).toInt();
 
  813    ruleKey = ruleElem.attribute( QStringLiteral( 
"key" ) );
 
  815    ruleKey = QUuid::createUuid().toString();
 
  816  Rule *rule = 
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
 
  818  if ( !ruleKey.isEmpty() )
 
  819    rule->mRuleKey = ruleKey;
 
  821  rule->
setActive( ruleElem.attribute( QStringLiteral( 
"checkstate" ), QStringLiteral( 
"1" ) ).toInt() );
 
  823  QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral( 
"rule" ) );
 
  824  while ( !childRuleElem.isNull() )
 
  826    Rule *childRule = 
create( childRuleElem, symbolMap );
 
  833      QgsDebugError( QStringLiteral( 
"failed to init a child rule!" ) );
 
  835    childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral( 
"rule" ) );
 
 
  854  if ( ruleElem.localName() != QLatin1String( 
"Rule" ) )
 
  856    QgsDebugError( QStringLiteral( 
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
 
  860  QString label, description, filterExp;
 
  861  int scaleMinDenom = 0, scaleMaxDenom = 0;
 
  865  QDomElement childElem = ruleElem.firstChildElement();
 
  866  while ( !childElem.isNull() )
 
  868    if ( childElem.localName() == QLatin1String( 
"Name" ) )
 
  872      if ( label.isEmpty() )
 
  873        label = childElem.firstChild().nodeValue();
 
  875    else if ( childElem.localName() == QLatin1String( 
"Description" ) )
 
  878      QDomElement titleElem = childElem.firstChildElement( QStringLiteral( 
"Title" ) );
 
  879      if ( !titleElem.isNull() )
 
  881        label = titleElem.firstChild().nodeValue();
 
  884      QDomElement abstractElem = childElem.firstChildElement( QStringLiteral( 
"Abstract" ) );
 
  885      if ( !abstractElem.isNull() )
 
  887        description = abstractElem.firstChild().nodeValue();
 
  890    else if ( childElem.localName() == QLatin1String( 
"Abstract" ) )
 
  893      description = childElem.firstChild().nodeValue();
 
  895    else if ( childElem.localName() == QLatin1String( 
"Title" ) )
 
  898      label = childElem.firstChild().nodeValue();
 
  900    else if ( childElem.localName() == QLatin1String( 
"Filter" ) )
 
  905        if ( 
filter->hasParserError() )
 
  911          filterExp = 
filter->expression();
 
  916    else if ( childElem.localName() == QLatin1String( 
"ElseFilter" ) )
 
  918      filterExp = QLatin1String( 
"ELSE" );
 
  921    else if ( childElem.localName() == QLatin1String( 
"MinScaleDenominator" ) )
 
  924      int v = childElem.firstChild().nodeValue().toInt( &ok );
 
  928    else if ( childElem.localName() == QLatin1String( 
"MaxScaleDenominator" ) )
 
  931      int v = childElem.firstChild().nodeValue().toInt( &ok );
 
  935    else if ( childElem.localName().endsWith( QLatin1String( 
"Symbolizer" ) ) )
 
  941    childElem = childElem.nextSiblingElement();
 
  946  if ( !layers.isEmpty() )
 
  969  return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
 
 
 1004  std::function< void( 
Rule *rule ) > exploreRule;
 
 1005  exploreRule = [&res, &exploreRule]( 
Rule * rule )
 
 1018      exploreRule( child );
 
 
 1030    bool drawVertexMarker )
 
 
 1050  QList<int> symbolZLevels( symbolZLevelsSet.begin(), symbolZLevelsSet.end() );
 
 1051  std::sort( symbolZLevels.begin(), symbolZLevels.end() );
 
 1055  QMap<int, int> zLevelsToNormLevels;
 
 1056  int maxNormLevel = -1;
 
 1057  const auto constSymbolZLevels = symbolZLevels;
 
 1058  for ( 
int zLevel : constSymbolZLevels )
 
 1060    zLevelsToNormLevels[zLevel] = ++maxNormLevel;
 
 1062    QgsDebugMsgLevel( QStringLiteral( 
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ), 4 );
 
 
 1085    for ( 
const RenderLevel &level : constMRenderQueue )
 
 1089      for ( 
const RenderJob *job : std::as_const( level.jobs ) )
 
 1096        for ( 
int i = 0; i < count; i++ )
 
 1103            int flags = job->ftr.flags;
 
 
 1145  Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
 
 1146  for ( 
int i = 0; i < origDescendants.count(); ++i )
 
 1147    clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
 
 
 1159  toSld( doc, element, context );
 
 
 1176  rendererElem.setAttribute( QStringLiteral( 
"type" ), QStringLiteral( 
"RuleRenderer" ) );
 
 1181  rulesElem.setTagName( QStringLiteral( 
"rules" ) ); 
 
 1182  rendererElem.appendChild( rulesElem );
 
 1185  rendererElem.appendChild( symbolsElem );
 
 1189  return rendererElem;
 
 
 1200  return rule ? rule->
active() : 
true;
 
 
 1217  std::function<QString( 
Rule *rule )> ruleToExpression;
 
 1218  ruleToExpression = [&ruleToExpression]( 
Rule * rule ) -> QString
 
 1224      QStringList otherRules;
 
 1225      const QList<QgsRuleBasedRenderer::Rule *> siblings = rule->
parent()->
children();
 
 1226      for ( 
Rule *sibling : siblings )
 
 1228        if ( sibling == rule || sibling->
isElse() )
 
 1231        const QString siblingExpression = ruleToExpression( sibling );
 
 1232        if ( siblingExpression.isEmpty() )
 
 1233          return QStringLiteral( 
"FALSE" ); 
 
 1235        otherRules.append( siblingExpression );
 
 1238      if ( otherRules.empty() )
 
 1239        return QStringLiteral( 
"TRUE" ); 
 
 1242                 otherRules.size() > 1
 
 1243                 ?  QStringLiteral( 
"NOT ((%1))" ).arg( otherRules.join( QLatin1String( 
") OR (" ) ) )
 
 1244                 : QStringLiteral( 
"NOT (%1)" ).arg( otherRules.at( 0 ) )
 
 1249      QStringList ruleParts;
 
 1254        ruleParts.append( QStringLiteral( 
"@map_scale <= %1" ).arg( rule->
minimumScale() ) );
 
 1257        ruleParts.append( QStringLiteral( 
"@map_scale >= %1" ).arg( rule->
maximumScale() ) );
 
 1259      if ( !ruleParts.empty() )
 
 1262                 ruleParts.size() > 1
 
 1263                 ?  QStringLiteral( 
"(%1)" ).arg( ruleParts.join( QLatin1String( 
") AND (" ) ) )
 
 1277    const QString ruleFilter = ruleToExpression( rule );
 
 1278    if ( !ruleFilter.isEmpty() )
 
 1279      parts.append( ruleFilter );
 
 1285  return parts.empty() ? QStringLiteral( 
"TRUE" )
 
 1286         : ( parts.size() > 1
 
 1287             ?  QStringLiteral( 
"(%1)" ).arg( parts.join( QLatin1String( 
") AND (" ) ) )
 
 
 1309  QDomElement symbolsElem = element.firstChildElement( QStringLiteral( 
"symbols" ) );
 
 1310  if ( symbolsElem.isNull() )
 
 1315  QDomElement rulesElem = element.firstChildElement( QStringLiteral( 
"rules" ) );
 
 
 1332  Rule *root = 
nullptr;
 
 1334  QDomElement ruleElem = element.firstChildElement( QStringLiteral( 
"Rule" ) );
 
 1335  while ( !ruleElem.isNull() )
 
 1342        root = 
new Rule( 
nullptr );
 
 1347    ruleElem = ruleElem.nextSiblingElement( QStringLiteral( 
"Rule" ) );
 
 
 1375  const auto constCategories = r->
categories();
 
 1382    else if ( cat.value().userType() == QMetaType::Type::Int )
 
 1383      value = cat.value().toString();
 
 1384    else if ( cat.value().userType() == QMetaType::Type::Double )
 
 1387      value = QString::number( cat.value().toDouble(), 
'f', 4 );
 
 1390    const QString 
filter = QStringLiteral( 
"%1 %2 %3" ).arg( attr, 
QgsVariantUtils::isNull( cat.value() ) ? QStringLiteral( 
"IS" ) : QStringLiteral( 
"=" ), value );
 
 1391    const QString label = !cat.label().isEmpty() ? cat.label() :
 
 1392                          cat.value().isValid() ? value : QString();
 
 
 1408  else if ( !testExpr.
isField() )
 
 1411    attr = QStringLiteral( 
"(%1)" ).arg( attr );
 
 1414  bool firstRange = 
true;
 
 1415  const auto constRanges = r->
ranges();
 
 1420    QString 
filter = QStringLiteral( 
"%1 %2 %3 AND %1 <= %4" ).arg( attr, firstRange ? QStringLiteral( 
">=" ) : QStringLiteral( 
">" ),
 
 1421                     QString::number( rng.lowerValue(), 
'f', 4 ),
 
 1422                     QString::number( rng.upperValue(), 
'f', 4 ) );
 
 1424    QString label = rng.label().isEmpty() ? 
filter : rng.label();
 
 
 1431  std::sort( scales.begin(), scales.end() ); 
 
 1435  const auto constScales = scales;
 
 1436  for ( 
int scale : constScales )
 
 1440    if ( maxDenom != 0 && maxDenom  <= scale )
 
 1442    initialRule->
appendChild( 
new Rule( symbol->
clone(), oldScale, scale, QString(), QStringLiteral( 
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
 
 1446  initialRule->
appendChild( 
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QStringLiteral( 
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
 
 
 1451  QString msg( QStringLiteral( 
"Rule-based renderer:\n" ) );
 
 
 1483  std::unique_ptr< QgsRuleBasedRenderer > r;
 
 1484  if ( renderer->
type() == QLatin1String( 
"RuleRenderer" ) )
 
 1488  else if ( renderer->
type() == QLatin1String( 
"singleSymbol" ) )
 
 1491    if ( !singleSymbolRenderer )
 
 1494    std::unique_ptr< QgsSymbol > origSymbol( singleSymbolRenderer->
symbol()->
clone() );
 
 1495    r = std::make_unique< QgsRuleBasedRenderer >( origSymbol.release() );
 
 1497  else if ( renderer->
type() == QLatin1String( 
"categorizedSymbol" ) )
 
 1500    if ( !categorizedRenderer )
 
 1505    bool isField = 
false;
 
 1515    if ( isField && !attr.contains( 
'\"' ) )
 
 1521    auto rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1528      auto rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1530      rule->setLabel( category.
label() );
 
 1533      if ( category.
value().userType() == QMetaType::Type::QVariantList )
 
 1536        const QVariantList list = category.
value().toList();
 
 1537        for ( 
const QVariant &v : list )
 
 1540          if ( QVariant( v ).convert( QMetaType::Type::Double ) )
 
 1542            values << v.toString();
 
 1550        if ( values.empty() )
 
 1552          expression = QStringLiteral( 
"ELSE" );
 
 1556          expression = QStringLiteral( 
"%1 IN (%2)" ).arg( attr, values.join( 
',' ) );
 
 1562        if ( category.
value().convert( QMetaType::Type::Double ) )
 
 1564          value = category.
value().toString();
 
 1572        if ( value == QLatin1String( 
"''" ) )
 
 1574          expression = QStringLiteral( 
"ELSE" );
 
 1578          expression = QStringLiteral( 
"%1 = %2" ).arg( attr, value );
 
 1581      rule->setFilterExpression( expression );
 
 1587      std::unique_ptr< QgsSymbol > origSymbol( category.
symbol()->
clone() );
 
 1588      rule->setSymbol( origSymbol.release() );
 
 1590      rootrule->appendChild( rule.release() );
 
 1593    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 1595  else if ( renderer->
type() == QLatin1String( 
"graduatedSymbol" ) )
 
 1598    if ( !graduatedRenderer )
 
 1604    bool isField = 
false;
 
 1614    if ( isField  && !attr.contains( 
'\"' ) )
 
 1619    else if ( !isField )
 
 1622      attr = QStringLiteral( 
"(%1)" ).arg( attr );
 
 1625    auto rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1629    const bool isInverted = ranges.size() > 1 ?
 
 1630                            ranges.at( 0 ).upperValue() > ranges.at( 1 ).upperValue() :
 
 1633    for ( 
int i = 0; i < ranges.size(); ++i )
 
 1635      range = ranges.value( i );
 
 1636      auto rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1638      rule->setLabel( range.
label() );
 
 1639      const QString upperValue = QString::number( range.
upperValue(), 
'f', 16 );
 
 1640      const QString lowerValue = QString::number( range.
lowerValue(), 
'f', 16 );
 
 1644        expression = !isInverted ?
 
 1645                     QStringLiteral( 
"%1 <= %2" ).arg( attr, upperValue ) :
 
 1646                     QStringLiteral( 
"%1 > %2" ).arg( attr, lowerValue );
 
 1648      else if ( i == ranges.size() - 1 )
 
 1650        expression = !isInverted ?
 
 1651                     QStringLiteral( 
"%1 > %2" ).arg( attr, lowerValue ) :
 
 1652                     QStringLiteral( 
"%1 <= %2" ).arg( attr, upperValue );
 
 1656        expression = attr + 
" > " + lowerValue + 
" AND " + \
 
 1657                     attr + 
" <= " + upperValue;
 
 1659      rule->setFilterExpression( expression );
 
 1665      std::unique_ptr< QgsSymbol > symbol( range.
symbol()->
clone() );
 
 1666      rule->setSymbol( symbol.release() );
 
 1668      rootrule->appendChild( rule.release() );
 
 1671    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 1673  else if ( renderer->
type() == QLatin1String( 
"pointDisplacement" ) || renderer->
type() == QLatin1String( 
"pointCluster" ) )
 
 1678  else if ( renderer->
type() == QLatin1String( 
"invertedPolygonRenderer" ) )
 
 1683  else if ( renderer->
type() == QLatin1String( 
"mergedFeatureRenderer" ) )
 
 1688  else if ( renderer->
type() == QLatin1String( 
"embeddedSymbol" ) && layer )
 
 1692    auto rootrule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1699    while ( it.
nextFeature( feature ) && rootrule->children().size() < 500 )
 
 1703        auto rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1704        rule->setFilterExpression( QStringLiteral( 
"$id=%1" ).arg( feature.
id() ) );
 
 1705        rule->setLabel( QString::number( feature.
id() ) );
 
 1707        rootrule->appendChild( rule.release() );
 
 1711    auto rule = std::make_unique< QgsRuleBasedRenderer::Rule >( 
nullptr );
 
 1712    rule->setFilterExpression( QStringLiteral( 
"ELSE" ) );
 
 1713    rule->setLabel( QObject::tr( 
"All other features" ) );
 
 1715    rootrule->appendChild( rule.release() );
 
 1717    r = std::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
 
 
 1730  QString sizeExpression;
 
 1731  switch ( symbol->
type() )
 
 1737        if ( ! sizeScaleField.isEmpty() )
 
 1739          sizeExpression = QStringLiteral( 
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
 
 1742        if ( ! rotationField.isEmpty() )
 
 1749      if ( ! sizeScaleField.isEmpty() )
 
 1756            sizeExpression = QStringLiteral( 
"%1*(%2)" ).arg( lsl->
width() ).arg( sizeScaleField );
 
 1765              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.
 
QFlags< FeatureRendererFlag > FeatureRendererFlags
Flags controlling behavior of vector feature renderers.
 
@ AffectsLabeling
If present, indicates that the renderer will participate in the map labeling problem.
 
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
 
@ AffectsLabeling
If present, indicates that the symbol will participate in the map labeling problem.
 
A feature renderer which represents features using a list of renderer categories.
 
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.
 
Handles 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.
 
Abstract base class for all 2D vector feature renderers.
 
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.
 
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.
 
A vector feature renderer which uses numeric attributes to classify features into different ranges.
 
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.
 
A polygon-only feature renderer used to display features inverted.
 
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
 
Abstract base class for line symbol layers.
 
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.
 
A polygon or line-only feature renderer used to render a set of features merged (or dissolved) into a...
 
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.
 
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.
 
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...
 
Represents a value range for a QgsGraduatedSymbolRenderer.
 
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.
 
Represents an individual rule for a 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
Returns a list of the symbols used by this rule and all children of this rule.
 
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.
 
Q_DECL_DEPRECATED 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.
 
Qgis::FeatureRendererFlags flags() const override
Returns flags associated with the renderer.
 
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.
 
Q_DECL_DEPRECATED 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.
 
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.
 
A feature renderer which renders all features with the same symbol.
 
QgsSymbol * symbol() const
Returns the symbol which will be rendered for every feature.
 
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 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 Q_DECL_DEPRECATED bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates an OGC function element.
 
static bool hasSldSymbolizer(const QDomElement &element)
Returns true if a DOM element contains an SLD Symbolizer element.
 
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 dataset.
 
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< QgsRendererRange > QgsRangeList
 
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.