33 #include <QDomDocument> 34 #include <QDomElement> 41 , mMaximumScale( scaleMinDenom )
42 , mMinimumScale( scaleMaxDenom )
43 , mFilterExp( filterExp )
45 , mDescription( description )
46 , mElseRule( elseRule )
49 mFilterExp = QStringLiteral(
"ELSE" );
51 mRuleKey = QUuid::createUuid().toString();
57 qDeleteAll( mChildren );
63 if ( mFilterExp.trimmed().compare( QLatin1String(
"ELSE" ), Qt::CaseInsensitive ) == 0 )
68 else if ( mFilterExp.trimmed().isEmpty() )
76 mFilter = qgis::make_unique< QgsExpression >( mFilterExp );
82 mChildren.append( rule );
89 mChildren.insert( i, rule );
96 mChildren.removeAll( rule );
103 delete mChildren.takeAt( i );
109 mChildren.removeAll( rule );
110 rule->mParent =
nullptr;
117 Rule *rule = mChildren.takeAt( i );
118 rule->mParent =
nullptr;
127 if ( key == mRuleKey )
130 Q_FOREACH (
Rule *rule, mChildren )
139 void QgsRuleBasedRenderer::Rule::updateElseRules()
142 Q_FOREACH (
Rule *rule, mChildren )
151 mFilterExp = QStringLiteral(
"ELSE" );
160 off.fill( QChar(
' ' ), indent );
161 QString symbolDump = ( mSymbol ? mSymbol->dump() : QStringLiteral(
"[]" ) );
162 QString msg = off + QStringLiteral(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
163 .arg( mLabel ).arg( mMaximumScale ).arg( mMinimumScale )
164 .arg( mFilterExp, symbolDump );
167 Q_FOREACH (
Rule *rule, mChildren )
169 lst.append( rule->
dump( indent + 2 ) );
171 msg += lst.join( QStringLiteral(
"\n" ) );
180 attrs.unite( mFilter->referencedColumns() );
182 attrs.unite( mSymbol->usedAttributes( context ) );
185 Q_FOREACH (
Rule *rule, mChildren )
194 if ( mFilter && mFilter->needsGeometry() )
197 Q_FOREACH (
Rule *rule, mChildren )
210 lst.append( mSymbol.get() );
212 Q_FOREACH (
Rule *rule, mChildren )
214 lst += rule->
symbols( context );
221 mSymbol.reset( sym );
226 mFilterExp = filterExp;
233 if ( currentLevel != -1 )
235 lst <<
QgsLegendSymbolItem( mSymbol.get(), mLabel, mRuleKey,
true, mMaximumScale, mMinimumScale, currentLevel, mParent ? mParent->mRuleKey : QString() );
238 for ( RuleList::const_iterator it = mChildren.constBegin(); it != mChildren.constEnd(); ++it )
249 if ( ! mFilter || mElseRule || ! context )
263 if ( !
qgsDoubleNear( mMaximumScale, 0.0 ) && mMaximumScale > scale )
265 if ( !
qgsDoubleNear( mMinimumScale, 0.0 ) && mMinimumScale < scale )
272 QgsSymbol *sym = mSymbol ? mSymbol->clone() :
nullptr;
273 Rule *newrule =
new Rule( sym, mMaximumScale, mMinimumScale, mFilterExp, mLabel, mDescription );
276 Q_FOREACH (
Rule *rule, mChildren )
283 QDomElement ruleElem = doc.createElement( QStringLiteral(
"rule" ) );
287 int symbolIndex = symbolMap.size();
288 symbolMap[QString::number( symbolIndex )] = mSymbol.get();
289 ruleElem.setAttribute( QStringLiteral(
"symbol" ), symbolIndex );
291 if ( !mFilterExp.isEmpty() )
292 ruleElem.setAttribute( QStringLiteral(
"filter" ), mFilterExp );
293 if ( mMaximumScale != 0 )
294 ruleElem.setAttribute( QStringLiteral(
"scalemindenom" ), mMaximumScale );
295 if ( mMinimumScale != 0 )
296 ruleElem.setAttribute( QStringLiteral(
"scalemaxdenom" ), mMinimumScale );
297 if ( !mLabel.isEmpty() )
298 ruleElem.setAttribute( QStringLiteral(
"label" ), mLabel );
299 if ( !mDescription.isEmpty() )
300 ruleElem.setAttribute( QStringLiteral(
"description" ), mDescription );
302 ruleElem.setAttribute( QStringLiteral(
"checkstate" ), 0 );
303 ruleElem.setAttribute( QStringLiteral(
"key" ), mRuleKey );
305 Q_FOREACH (
Rule *rule, mChildren )
307 ruleElem.appendChild( rule->
save( doc, symbolMap ) );
316 if (
symbols( context ).isEmpty() )
319 if ( !mFilterExp.isEmpty() )
321 if ( !props.value( QStringLiteral(
"filter" ), QString() ).isEmpty() )
322 props[ QStringLiteral(
"filter" )] += QLatin1String(
" AND " );
323 props[ QStringLiteral(
"filter" )] += mFilterExp;
330 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
331 element.appendChild( ruleElem );
335 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
336 nameElem.appendChild( doc.createTextNode( mLabel ) );
337 ruleElem.appendChild( nameElem );
339 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
341 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
342 if ( !mLabel.isEmpty() )
344 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
345 titleElem.appendChild( doc.createTextNode( mLabel ) );
346 descrElem.appendChild( titleElem );
348 if ( !mDescription.isEmpty() )
350 QDomElement abstractElem = doc.createElement( QStringLiteral(
"se:Abstract" ) );
351 abstractElem.appendChild( doc.createTextNode( mDescription ) );
352 descrElem.appendChild( abstractElem );
354 ruleElem.appendChild( descrElem );
357 if ( !props.value( QStringLiteral(
"filter" ), QString() ).isEmpty() )
364 mSymbol->toSld( doc, ruleElem, props );
368 Q_FOREACH (
Rule *rule, mChildren )
370 rule->
toSld( doc, element, props );
376 mActiveChildren.clear();
389 mSymbol->startRender( context, fields );
393 QStringList subfilters;
394 Q_FOREACH (
Rule *rule, mChildren )
397 if ( rule->
startRender( context, fields, subfilter ) )
400 mActiveChildren.append( rule );
401 subfilters.append( subfilter );
409 if ( subfilters.length() > 1 || !subfilters.value( 0 ).isEmpty() )
411 if ( subfilters.contains( QStringLiteral(
"TRUE" ) ) )
413 sf = QStringLiteral(
"TRUE" );
417 else if ( subfilters.count() > 50 )
419 std::function<QString( const QStringList & )>bt = [ &bt ](
const QStringList & subf )
421 if ( subf.count( ) == 1 )
425 else if ( subf.count( ) == 2 )
427 return subf.join( QStringLiteral(
") OR (" ) ).prepend(
'(' ).append(
')' );
431 int midpos =
static_cast<int>( subf.length() / 2 );
432 return QStringLiteral(
"(%1) OR (%2)" ).arg( bt( subf.mid( 0, midpos ) ) ).arg( bt( subf.mid( midpos ) ) );
435 sf = bt( subfilters );
439 sf = subfilters.join( QStringLiteral(
") OR (" ) ).prepend(
'(' ).append(
')' );
450 if ( mSymbol || sf.isEmpty() )
451 filter = QStringLiteral(
"TRUE" );
457 else if ( !mFilterExp.trimmed().isEmpty() && !sf.isEmpty() )
458 filter = QStringLiteral(
"(%1) AND (%2)" ).arg( mFilterExp, sf );
459 else if ( !mFilterExp.trimmed().isEmpty() )
461 else if ( sf.isEmpty() )
462 filter = QStringLiteral(
"TRUE" );
466 filter = filter.trimmed();
473 QSet<int> symbolZLevelsSet;
479 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
481 symbolZLevelsSet.insert( mSymbol->symbolLayer( i )->renderingPass() );
486 QList<Rule *>::iterator it;
487 for ( it = mActiveChildren.begin(); it != mActiveChildren.end(); ++it )
492 return symbolZLevelsSet;
499 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
501 int normLevel = zLevelsToNormLevels.value( mSymbol->symbolLayer( i )->renderingPass() );
502 mSymbolNormZLevels.insert( normLevel );
507 Q_FOREACH (
Rule *rule, mActiveChildren )
519 bool rendered =
false;
522 if ( mSymbol && mIsActive )
525 Q_FOREACH (
int normZLevel, mSymbolNormZLevels )
528 renderQueue[normZLevel].jobs.append(
new RenderJob( featToRender, mSymbol.get() ) );
533 bool willrendersomething =
false;
536 Q_FOREACH (
Rule *rule, mChildren )
549 if ( !willrendersomething )
551 Q_FOREACH (
Rule *rule, mElseRules )
556 if ( !mIsActive || ( mSymbol && !rendered ) )
572 Q_FOREACH (
Rule *rule, mActiveChildren )
579 lst.removeOne( rule );
605 lst.append( mSymbol.get() );
607 Q_FOREACH (
Rule *rule, mActiveChildren )
619 lst.insert( mRuleKey );
621 Q_FOREACH (
Rule *rule, mActiveChildren )
623 bool validKey =
false;
627 lst.removeOne( rule );
658 listChildren = mActiveChildren;
660 Q_FOREACH (
Rule *rule, listChildren )
670 mSymbol->stopRender( context );
672 Q_FOREACH (
Rule *rule, mActiveChildren )
677 mActiveChildren.clear();
678 mSymbolNormZLevels.clear();
683 QString symbolIdx = ruleElem.attribute( QStringLiteral(
"symbol" ) );
685 if ( !symbolIdx.isEmpty() )
687 if ( symbolMap.contains( symbolIdx ) )
689 symbol = symbolMap.take( symbolIdx );
693 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
697 QString filterExp = ruleElem.attribute( QStringLiteral(
"filter" ) );
698 QString
label = ruleElem.attribute( QStringLiteral(
"label" ) );
699 QString
description = ruleElem.attribute( QStringLiteral(
"description" ) );
700 int scaleMinDenom = ruleElem.attribute( QStringLiteral(
"scalemindenom" ), QStringLiteral(
"0" ) ).toInt();
701 int scaleMaxDenom = ruleElem.attribute( QStringLiteral(
"scalemaxdenom" ), QStringLiteral(
"0" ) ).toInt();
702 QString
ruleKey = ruleElem.attribute( QStringLiteral(
"key" ) );
703 Rule *rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
705 if ( !ruleKey.isEmpty() )
706 rule->mRuleKey = ruleKey;
708 rule->
setActive( ruleElem.attribute( QStringLiteral(
"checkstate" ), QStringLiteral(
"1" ) ).toInt() );
710 QDomElement childRuleElem = ruleElem.firstChildElement( QStringLiteral(
"rule" ) );
711 while ( !childRuleElem.isNull() )
713 Rule *childRule =
create( childRuleElem, symbolMap );
720 QgsDebugMsg( QStringLiteral(
"failed to init a child rule!" ) );
722 childRuleElem = childRuleElem.nextSiblingElement( QStringLiteral(
"rule" ) );
734 l +=
c->descendants();
741 if ( ruleElem.localName() != QLatin1String(
"Rule" ) )
743 QgsDebugMsg( QStringLiteral(
"invalid element: Rule element expected, %1 found!" ).arg( ruleElem.tagName() ) );
748 int scaleMinDenom = 0, scaleMaxDenom = 0;
752 QDomElement childElem = ruleElem.firstChildElement();
753 while ( !childElem.isNull() )
755 if ( childElem.localName() == QLatin1String(
"Name" ) )
759 if ( label.isEmpty() )
760 label = childElem.firstChild().nodeValue();
762 else if ( childElem.localName() == QLatin1String(
"Description" ) )
765 QDomElement titleElem = childElem.firstChildElement( QStringLiteral(
"Title" ) );
766 if ( !titleElem.isNull() )
768 label = titleElem.firstChild().nodeValue();
771 QDomElement abstractElem = childElem.firstChildElement( QStringLiteral(
"Abstract" ) );
772 if ( !abstractElem.isNull() )
774 description = abstractElem.firstChild().nodeValue();
777 else if ( childElem.localName() == QLatin1String(
"Abstract" ) )
780 description = childElem.firstChild().nodeValue();
782 else if ( childElem.localName() == QLatin1String(
"Title" ) )
785 label = childElem.firstChild().nodeValue();
787 else if ( childElem.localName() == QLatin1String(
"Filter" ) )
803 else if ( childElem.localName() == QLatin1String(
"MinScaleDenominator" ) )
806 int v = childElem.firstChild().nodeValue().toInt( &ok );
810 else if ( childElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
813 int v = childElem.firstChild().nodeValue().toInt( &ok );
817 else if ( childElem.localName().endsWith( QLatin1String(
"Symbolizer" ) ) )
823 childElem = childElem.nextSiblingElement();
828 if ( !layers.isEmpty() )
845 QgsDebugMsg( QStringLiteral(
"invalid geometry type: found %1" ).arg( geomType ) );
851 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
886 bool drawVertexMarker )
906 QList<int> symbolZLevels = symbolZLevelsSet.toList();
907 std::sort( symbolZLevels.begin(), symbolZLevels.end() );
911 QMap<int, int> zLevelsToNormLevels;
912 int maxNormLevel = -1;
913 Q_FOREACH (
int zLevel, symbolZLevels )
915 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
917 QgsDebugMsgLevel( QStringLiteral(
"zLevel %1 -> %2" ).arg( zLevel ).arg( maxNormLevel ), 4 );
945 for (
int i = 0; i < count; i++ )
994 Q_ASSERT( origDescendants.count() == clonedDescendants.count() );
995 for (
int i = 0; i < origDescendants.count(); ++i )
996 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
1019 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"RuleRenderer" ) );
1020 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1021 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1026 rulesElem.setTagName( QStringLiteral(
"rules" ) );
1027 rendererElem.appendChild( rulesElem );
1030 rendererElem.appendChild( symbolsElem );
1037 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
1039 rendererElem.appendChild( orderBy );
1041 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1043 return rendererElem;
1054 return rule ? rule->
active() :
true;
1082 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
1083 if ( symbolsElem.isNull() )
1088 QDomElement rulesElem = element.firstChildElement( QStringLiteral(
"rules" ) );
1105 Rule *root =
nullptr;
1107 QDomElement ruleElem = element.firstChildElement( QStringLiteral(
"Rule" ) );
1108 while ( !ruleElem.isNull() )
1115 root =
new Rule(
nullptr );
1120 ruleElem = ruleElem.nextSiblingElement( QStringLiteral(
"Rule" ) );
1152 if ( cat.
value().type() == QVariant::Int )
1153 value = cat.
value().toString();
1154 else if ( cat.
value().type() == QVariant::Double )
1157 value = QString::number( cat.
value().toDouble(),
'f', 4 );
1160 QString
filter = QStringLiteral(
"%1 = %2" ).arg( attr, value );
1177 else if ( !testExpr.
isField() )
1180 attr = QStringLiteral(
"(%1)" ).arg( attr );
1183 bool firstRange =
true;
1188 QString
filter = QStringLiteral(
"%1 %2 %3 AND %1 <= %4" ).arg( attr, firstRange ? QStringLiteral(
">=" ) : QStringLiteral(
">" ),
1190 QString::number( rng.
upperValue(),
'f', 4 ) );
1199 std::sort( scales.begin(), scales.end() );
1203 Q_FOREACH (
int scale, scales )
1207 if ( maxDenom != 0 && maxDenom <= scale )
1209 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, scale, QString(), QStringLiteral(
"%1 - %2" ).arg( oldScale ).arg( scale ) ) );
1213 initialRule->
appendChild(
new Rule( symbol->
clone(), oldScale, maxDenom, QString(), QStringLiteral(
"%1 - %2" ).arg( oldScale ).arg( maxDenom ) ) );
1218 QString msg( QStringLiteral(
"Rule-based renderer:\n" ) );
1246 if ( renderer->
type() == QLatin1String(
"RuleRenderer" ) )
1250 else if ( renderer->
type() == QLatin1String(
"singleSymbol" ) )
1253 if ( !singleSymbolRenderer )
1259 else if ( renderer->
type() == QLatin1String(
"categorizedSymbol" ) )
1262 if ( !categorizedRenderer )
1280 for (
int i = 0; i < categorizedRenderer->
categories().size(); ++i )
1282 category = categorizedRenderer->
categories().value( i );
1289 if ( QVariant( category.
value() ).convert( QVariant::Double ) )
1291 value = category.
value().toString();
1299 if ( value == QLatin1String(
"''" ) )
1301 expression = QStringLiteral(
"ELSE" );
1305 expression = QStringLiteral(
"%1 = %2" ).arg( attr, value );
1321 else if ( renderer->
type() == QLatin1String(
"graduatedSymbol" ) )
1324 if ( !graduatedRenderer )
1336 else if ( !testExpr.
isField() )
1339 attr = QStringLiteral(
"(%1)" ).arg( attr );
1346 for (
int i = 0; i < graduatedRenderer->
ranges().size(); ++i )
1348 range = graduatedRenderer->
ranges().value( i );
1353 expression = attr +
" >= " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1354 attr +
" <= " + QString::number( range.
upperValue(),
'f' );
1358 expression = attr +
" > " + QString::number( range.
lowerValue(),
'f' ) +
" AND " + \
1359 attr +
" <= " + QString::number( range.
upperValue(),
'f' );
1375 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
1378 if ( pointDistanceRenderer )
1381 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
1384 if ( invertedPolygonRenderer )
1399 QString sizeExpression;
1400 switch ( symbol->
type() )
1406 if ( ! sizeScaleField.isEmpty() )
1408 sizeExpression = QStringLiteral(
"%1*(%2)" ).arg( msl->
size() ).arg( sizeScaleField );
1411 if ( ! rotationField.isEmpty() )
1418 if ( ! sizeScaleField.isEmpty() )
1425 sizeExpression = QStringLiteral(
"%1*(%2)" ).arg( lsl->
width() ).arg( sizeScaleField );
1434 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.
Class for parsing and evaluation of expressions (formerly called "search strings").
The class is used as a container of context for various read/write operations on other objects...
QgsSymbol * symbol() const
Returns the symbol which will be rendered for every feature.
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
QgsSymbolList originalSymbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
QList< QgsLegendSymbolItem > QgsLegendSymbolList
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QgsFeatureRequest::OrderBy mOrderBy
QgsRuleBasedRenderer::Rule * clone() const
clone this rule, return new instance
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
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 null
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.
bool active() const
Returns if this rule is active.
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 toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
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...
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
This class keeps data about a rules for rule-based renderer.
double rendererScale() const
Returns the renderer map scale.
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) ...
double size() const
Returns the symbol size.
QString classAttribute() const
bool usingSymbolLevels() 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.
static QgsProperty fromExpression(const QString &expression, bool isActive=true)
Returns a new ExpressionBasedProperty created from the specified expression.
QgsExpression * filter() const
A filter that will check if this rule applies.
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
QgsRuleBasedRenderer::FeatureToRender & ftr
Feature to render.
QgsSymbolList symbols(const QgsRenderContext &context=QgsRenderContext()) const
Container of fields for a vector layer.
#define RENDERER_TAG_NAME
void setUsingSymbolLevels(bool usingSymbolLevels)
double lowerValue() const
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
QList< FeatureToRender > mCurrentFeatures
static void clearSymbolMap(QgsSymbolMap &symbols)
bool willRenderFeature(const QgsFeature &feature, QgsRenderContext *context=nullptr)
only tell whether a feature will be rendered without actually rendering it
QgsSymbol * symbol() const
QgsPaintEffect * mPaintEffect
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
void setNormZLevels(const QMap< int, int > &zLevelsToNormLevels)
assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering ...
QMap< QString, QString > QgsStringMap
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)
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
double maximumScale() const
Returns the maximum map scale (i.e.
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.
QList< QgsRuleBasedRenderer::Rule * > RuleList
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 dump(int indent=0) const
Dump for debug purpose.
double upperValue() const
const QgsCategoryList & categories() const
Returns a list of all categories recognized by the renderer.
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)
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.
bool renderingStopped() const
Returns TRUE if the rendering operation has been stopped and any ongoing rendering should be canceled...
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.
A QgsRuleBasedRenderer rendering job, consisting of a feature to be rendered with a particular symbol...
void removeChild(QgsRuleBasedRenderer::Rule *rule)
delete child rule
~QgsRuleBasedRenderer() override
QList< QgsSymbolLayer * > QgsSymbolLayerList
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
QList< QgsRuleBasedRenderer::RenderJob * > jobs
List of jobs to render, owned by this object.
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the attributes used to evaluate the expression of this rule.
int renderingPass() const
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.
const QgsRangeList & ranges() const
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 a specific symbol layer contained in the symbol.
void stopRender(QgsRenderContext &context)
Stop a rendering process.
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this 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 null
void setSymbol(QgsSymbol *sym)
Sets a new symbol (or NULL). Deletes old symbol.
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 ...
double minimumScale() const
Returns the minimum map scale (i.e.
bool isElse() const
Check if this rule is an ELSE rule.
QgsExpressionContext & expressionContext()
Gets the expression context.
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 ...
QString classAttribute() const
Returns the class attribute for the renderer, which is the field name or expression string from the l...
virtual double width() const
Returns the estimated width for the line symbol layer.
void setActive(bool state)
Sets if this rule is active.
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.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
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.
void setLabel(const QString &label)
QgsSymbol * symbol
Symbol to render feature with (not owned by this object).
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.
QgsSymbol * symbol() const
Returns the symbol which will be used to render this category.
QVariant value() const
Returns the value corresponding to this category.
bool isFilterOK(const QgsFeature &f, QgsRenderContext *context=nullptr) const
Check if a given feature shall be rendered by this rule.
bool needsGeometry() const
Returns true if this rule or one of its chilren needs the geometry to be applied. ...
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
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.
SymbolType type() const
Returns the symbol's type.
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
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
QgsSymbolList symbolsForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns list of symbols used for rendering the feature.
QgsRuleBasedRenderer::RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
QString description() const
A human readable description for this rule.
QString expression() const
Returns the original, unmodified expression string.
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
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.
bool isScaleOK(double scale) const
Check if this rule applies for a given scale.
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 ...
QString ruleKey() const
Unique rule identifier (for identification of rule within 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.
QString parserErrorString() const
Returns parser error.
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
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.
QDomElement save(QDomDocument &doc, QgsSymbolMap &symbolMap) const
QgsLegendSymbolList legendSymbolItems(int currentLevel=-1) const
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.