34 #include <QDomDocument> 35 #include <QDomElement> 42 , mMaximumScale( scaleMinDenom )
43 , mMinimumScale( scaleMaxDenom )
44 , mFilterExp( filterExp )
46 , mDescription( description )
47 , mElseRule( elseRule )
50 mFilterExp = QStringLiteral(
"ELSE" );
52 mRuleKey = QUuid::createUuid().toString();
58 qDeleteAll( mChildren );
64 if ( mFilterExp.trimmed().compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
69 else if ( mFilterExp.trimmed().isEmpty() )
77 mFilter = qgis::make_unique< QgsExpression >( mFilterExp );
83 mChildren.append( rule );
90 mChildren.insert( i, rule );
97 mChildren.removeAll( rule );
104 delete mChildren.takeAt( i );
110 mChildren.removeAll( rule );
111 rule->mParent =
nullptr;
118 Rule *rule = mChildren.takeAt( i );
119 rule->mParent =
nullptr;
128 if ( key == mRuleKey )
131 const auto constMChildren = mChildren;
132 for (
Rule *rule : constMChildren )
141 void QgsRuleBasedRenderer::Rule::updateElseRules()
144 const auto constMChildren = mChildren;
145 for (
Rule *rule : constMChildren )
147 if ( rule->isElse() )
154 mFilterExp = QStringLiteral(
"ELSE" );
172 if ( !mChildren.empty() )
174 for (
const Rule *rule : mChildren )
177 if ( !rule->accept( visitor ) )
191 off.fill( QChar(
' ' ), indent );
192 QString symbolDump = ( mSymbol ? mSymbol->dump() : QStringLiteral(
"[]" ) );
193 QString msg = off + QStringLiteral(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
194 .arg( mLabel ).arg( mMaximumScale ).arg( mMinimumScale )
195 .arg( mFilterExp, symbolDump );
198 const auto constMChildren = mChildren;
199 for (
Rule *rule : constMChildren )
201 lst.append( rule->dump( indent + 2 ) );
203 msg += lst.join( QStringLiteral(
"\n" ) );
212 attrs.unite( mFilter->referencedColumns() );
214 attrs.unite( mSymbol->usedAttributes( context ) );
217 const auto constMChildren = mChildren;
218 for (
Rule *rule : constMChildren )
220 attrs.unite( rule->usedAttributes( context ) );
227 if ( mFilter && mFilter->needsGeometry() )
230 const auto constMChildren = mChildren;
231 for (
Rule *rule : constMChildren )
233 if ( rule->needsGeometry() )
244 lst.append( mSymbol.get() );
246 const auto constMChildren = mChildren;
247 for (
Rule *rule : constMChildren )
249 lst += rule->symbols( context );
256 mSymbol.reset( sym );
261 mFilterExp = filterExp;
268 if ( currentLevel != -1 )
270 lst <<
QgsLegendSymbolItem( mSymbol.get(), mLabel, mRuleKey,
true, mMaximumScale, mMinimumScale, currentLevel, mParent ? mParent->mRuleKey : QString() );
273 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
284 if ( ! mFilter || mElseRule || ! context )
298 if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
300 if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
307 QgsSymbol *sym = mSymbol ? mSymbol->clone() :
nullptr;
308 Rule *newrule =
new Rule( sym, mMaximumScale, mMinimumScale, mFilterExp, mLabel, mDescription );
311 const auto constMChildren = mChildren;
312 for (
Rule *rule : constMChildren )
319 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
323 int symbolIndex = symbolMap.size();
324 symbolMap[QString::number( symbolIndex )] = mSymbol.get();
325 ruleElem.setAttribute( QStringLiteral(
"symbol" ), symbolIndex );
327 if ( !mFilterExp.isEmpty() )
328 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
329 if ( mMaximumScale != 0 )
330 ruleElem.setAttribute( QStringLiteral(
"scalemindenom" ), mMaximumScale );
331 if ( mMinimumScale != 0 )
332 ruleElem.setAttribute( QStringLiteral(
"scalemaxdenom" ), mMinimumScale );
333 if ( !mLabel.isEmpty() )
334 ruleElem.setAttribute( QStringLiteral(
"label" ), mLabel );
335 if ( !mDescription.isEmpty() )
336 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
338 ruleElem.setAttribute( QStringLiteral(
"checkstate" ), 0 );
339 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
341 const auto constMChildren = mChildren;
342 for (
Rule *rule : constMChildren )
344 ruleElem.appendChild( rule->save( doc, symbolMap ) );
353 if (
symbols( context ).isEmpty() )
356 if ( !mFilterExp.isEmpty() )
358 if ( !props.value( QStringLiteral(
"filter" ), QString() ).isEmpty() )
359 props[ QStringLiteral(
"filter" )] += QLatin1String(
" AND " );
360 props[ QStringLiteral(
"filter" )] += mFilterExp;
367 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
368 element.appendChild( ruleElem );
372 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
373 nameElem.appendChild( doc.createTextNode( mLabel ) );
374 ruleElem.appendChild( nameElem );
376 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
378 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
379 if ( !mLabel.isEmpty() )
381 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
382 titleElem.appendChild( doc.createTextNode( mLabel ) );
383 descrElem.appendChild( titleElem );
385 if ( !mDescription.isEmpty() )
387 QDomElement abstractElem = doc.createElement( QStringLiteral(
"se:Abstract" ) );
388 abstractElem.appendChild( doc.createTextNode( mDescription ) );
389 descrElem.appendChild( abstractElem );
391 ruleElem.appendChild( descrElem );
394 if ( !props.value( QStringLiteral(
"filter" ), QString() ).isEmpty() )
401 mSymbol->toSld( doc, ruleElem, props );
405 const auto constMChildren = mChildren;
406 for (
Rule *rule : constMChildren )
408 rule->toSld( doc, element, props );
414 mActiveChildren.clear();
427 mSymbol->startRender( context, fields );
431 QStringList subfilters;
432 const auto constMChildren = mChildren;
433 for (
Rule *rule : constMChildren )
436 if ( rule->startRender( context, fields, subfilter ) )
439 mActiveChildren.append( rule );
440 subfilters.append( subfilter );
448 if ( subfilters.length() > 1 || !subfilters.value( 0 ).isEmpty() )
450 if ( subfilters.contains( QStringLiteral(
"TRUE" ) ) )
452 sf = QStringLiteral(
"TRUE" );
456 else if ( subfilters.count() > 50 )
458 std::function<QString( const QStringList & )>bt = [ &bt ](
const QStringList & subf )
460 if ( subf.count( ) == 1 )
464 else if ( subf.count( ) == 2 )
466 return subf.join( QStringLiteral(
") OR (" ) ).prepend(
'(' ).append(
')' );
470 int midpos =
static_cast<int>( subf.length() / 2 );
471 return QStringLiteral(
"(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ) ).arg( bt( subf.mid( midpos ) ) );
474 sf = bt( subfilters );
478 sf = subfilters.join( QStringLiteral(
") OR (" ) ).prepend(
'(' ).append(
')' );
489 if ( mSymbol || sf.isEmpty() )
490 filter = QStringLiteral(
"TRUE" );
496 else if ( !mFilterExp.trimmed().isEmpty() && !sf.isEmpty() )
497 filter = QStringLiteral(
"(%1) AND (%2)" ).arg( mFilterExp, sf );
498 else if ( !mFilterExp.trimmed().isEmpty() )
500 else if ( sf.isEmpty() )
501 filter = QStringLiteral(
"TRUE" );
505 filter = filter.trimmed();
512 QSet<int> symbolZLevelsSet;
518 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
520 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
525 QList<Rule *>::iterator it;
526 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
531 return symbolZLevelsSet;
538 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
540 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
541 mSymbolNormZLevels.insert( normLevel );
546 const auto constMActiveChildren = mActiveChildren;
547 for (
Rule *rule : constMActiveChildren )
549 rule->setNormZLevels( zLevelsToNormLevels );
559 bool rendered =
false;
562 if ( mSymbol && mIsActive )
565 const auto constMSymbolNormZLevels = mSymbolNormZLevels;
566 for (
int normZLevel : constMSymbolNormZLevels )
569 renderQueue[normZLevel].jobs.append(
new RenderJob( featToRender, mSymbol.get() ) );
574 bool willrendersomething =
false;
577 const auto constMChildren = mChildren;
578 for (
Rule *rule : constMChildren )
581 if ( !rule->isElse() )
583 RenderResult res = rule->renderFeature( featToRender, context, renderQueue );
591 if ( !willrendersomething )
593 const auto constMElseRules = mElseRules;
594 for (
Rule *rule : constMElseRules )
596 rendered |= rule->renderFeature( featToRender, context, renderQueue ) ==
Rendered;
599 if ( !mIsActive || ( mSymbol && !rendered ) )
615 const auto constMActiveChildren = mActiveChildren;
616 for (
Rule *rule : constMActiveChildren )
618 if ( rule->isElse() )
620 if ( rule->children().isEmpty() )
623 lst.removeOne( rule );
632 return rule->willRenderFeature( feature, context );
635 else if ( rule->willRenderFeature( feature, context ) )
649 lst.append( mSymbol.get() );
651 const auto constMActiveChildren = mActiveChildren;
652 for (
Rule *rule : constMActiveChildren )
654 lst += rule->symbolsForFeature( feature, context );
664 lst.insert( mRuleKey );
666 const auto constMActiveChildren = mActiveChildren;
667 for (
Rule *rule : constMActiveChildren )
669 bool validKey =
false;
670 if ( rule->isElse() )
673 lst.removeOne( rule );
680 else if ( !rule->isElse( ) && rule->willRenderFeature( feature, context ) )
687 lst.unite( rule->legendKeysForFeature( feature, context ) );
704 listChildren = mActiveChildren;
706 const auto constListChildren = listChildren;
707 for (
Rule *rule : constListChildren )
709 lst += rule->rulesForFeature( feature, context, onlyActive );
717 mSymbol->stopRender( context );
719 const auto constMActiveChildren = mActiveChildren;
720 for (
Rule *rule : constMActiveChildren )
722 rule->stopRender( context );
725 mActiveChildren.clear();
726 mSymbolNormZLevels.clear();
731 QString symbolIdx = ruleElem.attribute( QStringLiteral(
"symbol" ) );
733 if ( !symbolIdx.isEmpty() )
735 if ( symbolMap.contains( symbolIdx ) )
737 symbol = symbolMap.take( symbolIdx );
741 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
745 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
746 QString
label = ruleElem.attribute( QStringLiteral(
"label" ) );
747 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
748 int scaleMinDenom = ruleElem.attribute( QStringLiteral(
"scalemindenom" ), QStringLiteral(
"0" ) ).toInt();
749 int scaleMaxDenom = ruleElem.attribute( QStringLiteral(
"scalemaxdenom" ), QStringLiteral(
"0" ) ).toInt();
750 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
751 Rule *rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
753 if ( !ruleKey.isEmpty() )
754 rule->mRuleKey = ruleKey;
756 rule->
setActive( ruleElem.attribute( QStringLiteral(
"checkstate" ), QStringLiteral(
"1" ) ).toInt() );
758 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
759 while ( !childRuleElem.isNull() )
761 Rule *childRule =
create( childRuleElem, symbolMap );
768 QgsDebugMsg( QStringLiteral(
"failed to init a child rule!" ) );
770 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
782 l +=
c->descendants();
789 if ( ruleElem.localName() != QLatin1String(
"Rule" ) )
791 QgsDebugMsg( QStringLiteral(
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
796 int scaleMinDenom = 0, scaleMaxDenom = 0;
800 QDomElement childElem = ruleElem.firstChildElement();
801 while ( !childElem.isNull() )
803 if ( childElem.localName() == QLatin1String(
"Name" ) )
807 if ( label.isEmpty() )
808 label = childElem.firstChild().nodeValue();
810 else if ( childElem.localName() == QLatin1String(
"Description" ) )
813 QDomElement titleElem = childElem.firstChildElement( QStringLiteral(
"Title" ) );
814 if ( !titleElem.isNull() )
816 label = titleElem.firstChild().nodeValue();
819 QDomElement abstractElem = childElem.firstChildElement( QStringLiteral(
"Abstract" ) );
820 if ( !abstractElem.isNull() )
822 description = abstractElem.firstChild().nodeValue();
825 else if ( childElem.localName() == QLatin1String(
"Abstract" ) )
828 description = childElem.firstChild().nodeValue();
830 else if ( childElem.localName() == QLatin1String(
"Title" ) )
833 label = childElem.firstChild().nodeValue();
835 else if ( childElem.localName() == QLatin1String(
"Filter" ) )
851 else if ( childElem.localName() == QLatin1String(
"MinScaleDenominator" ) )
854 int v = childElem.firstChild().nodeValue().toInt( &ok );
858 else if ( childElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
861 int v = childElem.firstChild().nodeValue().toInt( &ok );
865 else if ( childElem.localName().endsWith( QLatin1String(
"Symbolizer" ) ) )
871 childElem = childElem.nextSiblingElement();
876 if ( !layers.isEmpty() )
893 QgsDebugMsg( QStringLiteral(
"invalid geometry type: found %1" ).arg( geomType ) );
899 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
934 bool drawVertexMarker )
954 QList<int> symbolZLevels = symbolZLevelsSet.toList();
955 std::sort( symbolZLevels.begin(), symbolZLevels.end() );
959 QMap<int, int> zLevelsToNormLevels;
960 int maxNormLevel = -1;
961 const auto constSymbolZLevels = symbolZLevels;
962 for (
int zLevel : constSymbolZLevels )
964 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
966 QgsDebugMsgLevel( QStringLiteral(
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ), 4 );
984 for (
const RenderLevel &level : constMRenderQueue )
988 for (
const RenderJob *job : qgis::as_const( level.jobs ) )
995 for (
int i = 0; i < count; i++ )
1002 int flags = job->ftr.flags;
1044 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
1045 for (
int i = 0; i < origDescendants.count(); ++i )
1046 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
1069 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"RuleRenderer" ) );
1070 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1071 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1076 rulesElem.setTagName( QStringLiteral(
"rules" ) );
1077 rendererElem.appendChild( rulesElem );
1080 rendererElem.appendChild( symbolsElem );
1087 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
1089 rendererElem.appendChild( orderBy );
1091 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1093 return rendererElem;
1104 return rule ? rule->
active() :
true;
1132 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
1133 if ( symbolsElem.isNull() )
1138 QDomElement rulesElem = element.firstChildElement( QStringLiteral(
"rules" ) );
1155 Rule *root =
nullptr;
1157 QDomElement ruleElem = element.firstChildElement( QStringLiteral(
"Rule" ) );
1158 while ( !ruleElem.isNull() )
1165 root =
new Rule(
nullptr );
1170 ruleElem = ruleElem.nextSiblingElement( QStringLiteral(
"Rule" ) );
1198 const auto constCategories = r->
categories();
1203 if ( cat.value().type() == QVariant::Int )
1204 value = cat.value().toString();
1205 else if ( cat.value().type() == QVariant::Double )
1208 value = QString::number( cat.value().toDouble(),
'f', 4 );
1211 QString
filter = QStringLiteral(
"%1 = %2" ).arg( attr, value );
1228 else if ( !testExpr.
isField() )
1231 attr = QStringLiteral(
"(%1)" ).arg( attr );
1234 bool firstRange =
true;
1235 const auto constRanges = r->
ranges();
1240 QString
filter = QStringLiteral(
"%1 %2 %3 AND %1 <= %4" ).arg( attr, firstRange ? QStringLiteral(
">=" ) : QStringLiteral(
">" ),
1241 QString::number( rng.lowerValue(),
'f', 4 ),
1242 QString::number( rng.upperValue(),
'f', 4 ) );
1251 std::sort( scales.begin(), scales.end() );
1255 const auto constScales = scales;
1256 for (
int scale : constScales )
1260 if ( maxDenom != 0 && maxDenom <= scale )
1262 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, scale, QString(), QStringLiteral(
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
1266 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QStringLiteral(
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
1271 QString msg( QStringLiteral(
"Rule-based renderer:\n" ) );
1303 std::unique_ptr< QgsRuleBasedRenderer > r;
1304 if ( renderer->
type() == QLatin1String(
"RuleRenderer" ) )
1306 r.reset( dynamic_cast<QgsRuleBasedRenderer *>( renderer->
clone() ) );
1308 else if ( renderer->
type() == QLatin1String(
"singleSymbol" ) )
1311 if ( !singleSymbolRenderer )
1314 std::unique_ptr< QgsSymbol > origSymbol( singleSymbolRenderer->
symbol()->
clone() );
1315 r = qgis::make_unique< QgsRuleBasedRenderer >( origSymbol.release() );
1317 else if ( renderer->
type() == QLatin1String(
"categorizedSymbol" ) )
1320 if ( !categorizedRenderer )
1333 std::unique_ptr< QgsRuleBasedRenderer::Rule > rootrule = qgis::make_unique< QgsRuleBasedRenderer::Rule >( nullptr );
1340 std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = qgis::make_unique< QgsRuleBasedRenderer::Rule >( nullptr );
1345 if ( category.
value().type() == QVariant::List )
1348 const QVariantList list = category.
value().toList();
1349 for (
const QVariant &v : list )
1352 if ( QVariant( v ).convert( QVariant::Double ) )
1354 values << v.toString();
1362 if ( values.empty() )
1364 expression = QStringLiteral(
"ELSE" );
1368 expression = QStringLiteral(
"%1 IN (%2)" ).arg( attr, values.join(
',' ) );
1374 if ( category.
value().convert( QVariant::Double ) )
1376 value = category.
value().toString();
1384 if ( value == QLatin1String(
"''" ) )
1386 expression = QStringLiteral(
"ELSE" );
1390 expression = QStringLiteral(
"%1 = %2" ).arg( attr, value );
1393 rule->setFilterExpression( expression );
1399 std::unique_ptr< QgsSymbol > origSymbol( category.
symbol()->
clone() );
1400 rule->setSymbol( origSymbol.release() );
1402 rootrule->appendChild( rule.release() );
1405 r = qgis::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
1407 else if ( renderer->
type() == QLatin1String(
"graduatedSymbol" ) )
1410 if ( !graduatedRenderer )
1422 else if ( !testExpr.
isField() )
1425 attr = QStringLiteral(
"(%1)" ).arg( attr );
1428 std::unique_ptr< QgsRuleBasedRenderer::Rule > rootrule = qgis::make_unique< QgsRuleBasedRenderer::Rule >( nullptr );
1432 for (
int i = 0; i < graduatedRenderer->
ranges().size(); ++i )
1434 range = graduatedRenderer->
ranges().value( i );
1435 std::unique_ptr< QgsRuleBasedRenderer::Rule > rule = qgis::make_unique< QgsRuleBasedRenderer::Rule >( nullptr );
1436 rule->setLabel( range.
label() );
1439 expression = attr +
" >= " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1440 attr +
" <= " + QString::number( range.
upperValue(),
'f' );
1444 expression = attr +
" > " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1445 attr +
" <= " + QString::number( range.
upperValue(),
'f' );
1447 rule->setFilterExpression( expression );
1453 std::unique_ptr< QgsSymbol > symbol( range.
symbol()->
clone() );
1454 rule->setSymbol( symbol.release() );
1456 rootrule->appendChild( rule.release() );
1459 r = qgis::make_unique< QgsRuleBasedRenderer >( rootrule.release() );
1461 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
1464 if ( pointDistanceRenderer )
1467 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
1470 if ( invertedPolygonRenderer )
1485 QString sizeExpression;
1486 switch ( symbol->
type() )
1492 if ( ! sizeScaleField.isEmpty() )
1494 sizeExpression = QStringLiteral(
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
1497 if ( ! rotationField.isEmpty() )
1504 if ( ! sizeScaleField.isEmpty() )
1511 sizeExpression = QStringLiteral(
"%1*(%2)" ).arg( lsl->
width() ).arg( sizeScaleField );
1520 sizeExpression = QStringLiteral(
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
QgsRuleBasedRenderer(QgsRuleBasedRenderer::Rule *root)
Constructs the renderer from given tree of rules (takes ownership)
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
static void mergeScaleDependencies(double mScaleMinDenom, double mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
Class for parsing and evaluation of expressions (formerly called "search strings").
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
The class is used as a container of context for various read/write operations on other objects...
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the attributes used to evaluate the expression of this rule.
double rendererScale() const
Returns the renderer map scale.
QDomElement save(QDomDocument &doc, QgsSymbolMap &symbolMap) const
A symbol entity for QgsStyle databases.
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
QList< QgsLegendSymbolItem > QgsLegendSymbolList
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QgsFeatureRequest::OrderBy mOrderBy
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
QgsRuleBasedRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Abstract base class for all rendered symbols.
QgsRuleBasedRenderer::Rule * takeChild(QgsRuleBasedRenderer::Rule *rule)
take child rule out, set parent as nullptr
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
QList< QgsRuleBasedRenderer::RenderLevel > RenderQueue
Rendering queue: a list of rendering levels.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
const QgsRuleBasedRenderer::RuleList & children()
Returns all children rules of this rule.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
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...
This class keeps data about a rules for rule-based renderer.
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
QgsSymbol * symbol() const
Returns the symbol which will be used to render this category.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
store renderer info to XML element
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer) ...
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
QString classAttribute() const
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static QgsProperty fromField(const QString &fieldName, bool isActive=true)
Returns a new FieldBasedProperty created from the specified field name.
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
QString classAttribute() const
Returns the class attribute for the renderer, which is the field name or expression string from the l...
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
Container of fields for a vector layer.
#define RENDERER_TAG_NAME
void setUsingSymbolLevels(bool usingSymbolLevels)
void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
QSet< int > collectZLevels()
Gets all used z-levels from this rule and children.
Rule * mRootRule
the root node with hierarchical list of rules
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
QList< FeatureToRender > mCurrentFeatures
static void clearSymbolMap(QgsSymbolMap &symbols)
double maximumScale() const
Returns the maximum map scale (i.e.
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
only tell whether a feature will be rendered without actually rendering it
QgsPaintEffect * mPaintEffect
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
An interface for classes which can visit style entity (e.g.
void setNormZLevels(const QMap< int, int > &zLevelsToNormLevels)
assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering ...
QString description() const
A human readable description for this rule.
QString parserErrorString() const
Returns parser error.
QMap< QString, QString > QgsStringMap
virtual double width() const
Returns the estimated width for the line symbol layer.
A marker symbol type, for rendering Point and MultiPoint geometries.
A line symbol type, for rendering LineString and MultiLineString geometries.
bool startRender(QgsRenderContext &context, const QgsFields &fields, QString &filter)
prepare the rule for rendering and its children (build active children array)
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
void renderFeatureWithSymbol(const QgsFeature &feature, QgsSymbol *symbol, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker) SIP_THROW(QgsCsException)
Render the feature with the symbol using context.
bool active() const
Returns if this rule is active.
QList< QgsRuleBasedRenderer::Rule * > RuleList
QString dump(int indent=0) const
Dump for debug purpose.
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
double lowerValue() const
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
RenderResult
The result of rendering a rule.
QList< QgsSymbol * > QgsSymbolList
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
static QgsFeatureRenderer * createFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType)
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
#define QgsDebugMsgLevel(str, level)
const QgsCategoryList & categories() const
Returns a list of all categories recognized by the renderer.
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a new rule-based renderer instance from XML.
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.
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.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
double size() const
Returns the symbol size.
QgsSymbolList symbols(const QgsRenderContext &context=QgsRenderContext()) const
A QgsRuleBasedRenderer rendering job, consisting of a feature to be rendered with a particular symbol...
void removeChild(QgsRuleBasedRenderer::Rule *rule)
delete child rule
QgsExpression * filter() const
A filter that will check if this rule applies.
Contains information relating to a node (i.e.
~QgsRuleBasedRenderer() override
QList< QgsSymbolLayer * > QgsSymbolLayerList
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
bool isFilterOK(const QgsFeature &f, QgsRenderContext *context=nullptr) const
Check if a given feature shall be rendered by this rule.
QgsSymbol * symbol() const
double minimumScale() const
Returns the minimum map scale (i.e.
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all child rules associated with the rule...
void insertChild(int i, QgsRuleBasedRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
Render level: a list of jobs to be drawn at particular level for a QgsRuleBasedRenderer.
bool isScaleOK(double scale) const
Check if this rule applies for a given scale.
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 ...
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
void stopRender(QgsRenderContext &context)
Stop a rendering process.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
QgsRuleBasedRenderer::Rule * takeChildAt(int i)
take child rule out, set parent as nullptr
void setSymbol(QgsSymbol *sym)
Sets a new symbol (or nullptr). Deletes old symbol.
QVariant value() const
Returns the value corresponding to this category.
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 ...
QString expression() const
Returns the original, unmodified expression string.
QgsExpressionContext & expressionContext()
Gets the expression context.
Rule based symbology or label child rule.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
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 ...
void setActive(bool state)
Sets if this rule is active.
QgsRuleBasedRenderer::Rule * clone() const
clone this rule, return new instance
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
tell which symbols will be used to render the feature
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
void setIsElse(bool iselse)
Sets if this rule is an ELSE rule.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
bool usingSymbolLevels() const
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
SymbolType type() const
Returns the symbol's type.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
static QgsRuleBasedRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsRuleBasedRenderer from an existing renderer.
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
bool isField() const
Checks whether an expression consists only of a single field reference.
double upperValue() const
bool renderFeature(const QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override SIP_THROW(QgsCsException)
Render a feature using this renderer in the given context.
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
QMap< QString, QgsSymbol *> QgsSymbolMap
bool needsGeometry() const
Returns true if this rule or one of its chilren needs the geometry to be applied. ...
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
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.
QgsRuleBasedRenderer * clone() const override
Create a deep copy of this renderer.
QgsLegendSymbolList legendSymbolItems(int currentLevel=-1) const
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...
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
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 ...
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns whether the renderer will render a feature or not.
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...
void setFilterExpression(const QString &filterExp)
Set the expression used to check if a given feature shall be rendered with this rule.
Feature for rendering by a QgsRuleBasedRenderer.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
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...
void removeChildAt(int i)
delete child rule
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
static QgsRuleBasedRenderer::Rule * create(QDomElement &ruleElem, QgsSymbolMap &symbolMap)
Create a rule from an XML definition.
QgsRuleBasedRenderer::Rule * findRuleByKey(const QString &key)
Try to find a rule given its unique key.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
const QgsRangeList & ranges() const
void setLabel(const QString &label)
Sets the label for this category, which is used to represent the category within legends and the laye...
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
Contains information relating to the style entity currently being visited.
QgsSymbol * symbol() const
Returns the symbol which will be rendered for every feature.
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
void appendChild(QgsRuleBasedRenderer::Rule *rule)
add child rule, take ownership, sets this as parent
static QgsRuleBasedRenderer::Rule * createFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType)
Create a rule from the SLD provided in element and for the specified geometry type.
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
used from subclasses to create SLD Rule elements following SLD v1.1 specs
QString dump() const override
Returns debug information about this renderer.
virtual QString layerType() const =0
Returns a string that represents this layer type.
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
Returns which legend keys match the feature.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.