33 #include <QDomDocument> 34 #include <QDomElement> 41 , mScaleMinDenom( scaleMinDenom )
42 , mScaleMaxDenom( scaleMaxDenom )
43 , mFilterExp( filterExp )
45 , mDescription( description )
46 , mElseRule( elseRule )
170 QString msg = off +
QString(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
179 msg += lst.
join(
"\n" );
222 lst += rule->
symbols( context );
258 if ( currentLevel != -1 )
279 return res.
toInt() != 0;
312 int symbolIndex = symbolMap.
size();
341 if (
symbols( context ).isEmpty() )
347 if ( !locProps.
value(
"filter",
"" ).isEmpty() )
348 locProps[
"filter" ] +=
" AND ";
383 if ( !locProps.
value(
"filter",
"" ).isEmpty() )
396 rule->
toSld( doc, element, locProps );
429 if ( rule->
startRender( context, fields , subfilter ) )
433 subfilters.
append( subfilter );
441 if ( subfilters.
length() > 1 || !subfilters.
value( 0 ).isEmpty() )
443 if ( subfilters.
contains(
"TRUE" ) )
498 return symbolZLevelsSet;
525 bool rendered =
false;
539 bool willrendersomething =
false;
555 if ( !willrendersomething )
650 if ( symbolMap.
contains( symbolIdx ) )
652 symbol = symbolMap.
take( symbolIdx );
656 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
666 Rule* rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
674 while ( !childRuleElem.
isNull() )
676 Rule* childRule =
create( childRuleElem, symbolMap );
705 while ( !childElem.
isNull() )
714 else if ( childElem.
localName() ==
"Description" )
718 if ( !titleElem.
isNull() )
724 if ( !abstractElem.
isNull() )
729 else if ( childElem.
localName() ==
"Abstract" )
734 else if ( childElem.
localName() ==
"Title" )
739 else if ( childElem.
localName() ==
"Filter" )
755 else if ( childElem.
localName() ==
"MinScaleDenominator" )
762 else if ( childElem.
localName() ==
"MaxScaleDenominator" )
803 return new Rule( symbol, scaleMinDenom,
scaleMaxDenom, filterExp, label, description );
838 bool drawVertexMarker )
857 qSort( symbolZLevels );
862 int maxNormLevel = -1;
863 Q_FOREACH (
int zLevel, symbolZLevels )
865 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
891 for (
int i = 0; i < count; i++ )
940 Q_ASSERT( origDescendants.
count() == clonedDescendants.
count() );
941 for (
int i = 0; i < origDescendants.
count(); ++i )
942 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
1005 lst << qMakePair( pair.first, pix );
1018 return rule ? rule->
active() :
true;
1052 if ( symbolsElem.
isNull() )
1074 Rule* root =
nullptr;
1077 while ( !ruleElem.
isNull() )
1084 root =
new Rule(
nullptr );
1121 if ( cat.
value().
type() == QVariant::Int )
1123 else if ( cat.
value().
type() == QVariant::Double )
1146 else if ( !testExpr.
isField() )
1152 bool firstRange =
true;
1172 Q_FOREACH (
int scale, scales )
1176 if ( maxDenom != 0 && maxDenom <= scale )
1187 QString msg(
"Rule-based renderer:\n" );
1215 if ( renderer->
type() ==
"RuleRenderer" )
1219 else if ( renderer->
type() ==
"singleSymbol" )
1222 if ( !singleSymbolRenderer )
1229 else if ( renderer->
type() ==
"categorizedSymbol" )
1232 if ( !categorizedRenderer )
1250 for (
int i = 0; i < categorizedRenderer->
categories().
size(); ++i )
1259 if (
QVariant( category.
value() ).convert( QVariant::Double ) )
1269 if ( value ==
"''" )
1271 expression =
"ELSE";
1275 expression =
QString(
"%1 = %2" ).
arg( attr, value );
1292 else if ( renderer->
type() ==
"graduatedSymbol" )
1295 if ( !graduatedRenderer )
1307 else if ( !testExpr.
isField() )
1317 for (
int i = 0; i < graduatedRenderer->
ranges().
size();++i )
1348 else if ( renderer->
type() ==
"pointDisplacement" )
1351 if ( pointDisplacementRenderer )
1354 else if ( renderer->
type() ==
"invertedPolygonRenderer" )
1357 if ( invertedPolygonRenderer )
1373 switch ( symbol->
type() )
1379 if ( ! sizeScaleField.
isEmpty() )
1381 sizeExpression =
QString(
"%1*(%2)" ).
arg( msl->
size() ).arg( sizeScaleField );
1384 if ( ! rotationField.
isEmpty() )
1391 if ( ! sizeScaleField.
isEmpty() )
1398 sizeExpression =
QString(
"%1*(%2)" ).
arg( lsl->
width() ).arg( sizeScaleField );
1407 sizeExpression =
QString(
"%1*(%2)" ).
arg( msl->
size() ).arg( sizeScaleField );
const QgsCategoryList & categories() const
bool active() const
Returns if this rule is active.
static QDomElement saveSymbols(QgsSymbolV2Map &symbols, const QString &tagName, QDomDocument &doc)
bool needsGeometry() const
Returns true if this rule or one of its chilren needs the geometry to be applied. ...
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsExpression * filter() const
A filter that will check if this rule applies.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
void setLabel(const QString &label)
QgsSymbolV2List symbols(const QgsRenderContext &context=QgsRenderContext()) const
static QgsSymbolV2Map loadSymbols(QDomElement &element)
void setNormZLevels(const QMap< int, int > &zLevelsToNormLevels)
assign normalized z-levels [0..N-1] for this rule's symbol for quick access during rendering ...
virtual Q_DECL_DEPRECATED QString rotationField() const
return rotation field name (or empty string if not set or not supported by renderer) ...
#define RENDERER_TAG_NAME
double rendererScale() const
QString & append(QChar ch)
virtual 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...
A container class for data source field mapping or expression.
bool contains(const Key &key) const
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
QString & fill(QChar ch, int size)
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, const QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
QSet< int > collectZLevels()
get all used z-levels from this rule and children
QDomNode appendChild(const QDomNode &newChild)
QgsLegendSymbolListV2 legendSymbolItemsV2(int currentLevel=-1) const
static QgsFeatureRendererV2 * create(QDomElement &element)
virtual QSet< QString > legendKeysForFeature(QgsFeature &feature, QgsRenderContext &context) override
Return legend keys matching a specified feature.
QSet< int > mSymbolNormZLevels
QgsSymbolV2 * symbol() const
QString attribute(const QString &name, const QString &defValue) const
void setTagName(const QString &name)
QString nodeValue() const
Q_DECL_DEPRECATED bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
QgsSymbolV2 * symbol() const
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
double size() const
Returns the symbol size.
void setActive(bool state)
Sets if this rule is active.
QString sizeScaleField() const
QStringList referencedColumns() const
Get list of columns referenced by the expression.
QString & prepend(QChar ch)
virtual QgsSymbolV2 * clone() const =0
QString sizeScaleField() const
static QgsFeatureRendererV2 * createFromSld(QDomElement &element, QGis::GeometryType geomType)
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
bool contains(const QString &str, Qt::CaseSensitivity cs) const
virtual bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QDomElement nextSiblingElement(const QString &tagName) const
Q_DECL_DEPRECATED bool startRender(QgsRenderContext &context, const QgsFields &fields)
Prepare the rule for rendering and its children (build active children array)
~QgsRuleBasedRendererV2()
QDomElement save(QDomDocument &doc, QgsSymbolV2Map &symbolMap) const
Container of fields for a vector layer.
void removeChild(Rule *rule)
delete child rule
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
static void mergeScaleDependencies(int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
virtual void setLegendSymbolItem(const QString &key, QgsSymbolV2 *symbol) override
Sets the symbol to be used for a legend symbol item.
QString join(const QString &separator) const
const_iterator insert(const T &value)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QString sizeScaleField() const
virtual bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
void setIsElse(bool iselse)
Sets if this rule is an ELSE rule.
bool isElse()
Check if this rule is an ELSE rule.
QString parserErrorString() const
Returns parser error.
QMap< QString, QString > QgsStringMap
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
QgsPaintEffect * mPaintEffect
Rule * takeChild(Rule *rule)
take child rule out, set parent as null
void removeChildAt(int i)
delete child rule
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const
Writes the SLD element following the SLD v1.1 specs.
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat, QgsRenderContext &context) override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
QString description() const
A human readable description for this rule.
virtual bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
Rule * findRuleByKey(const QString &key)
Try to find a rule given its unique key.
void renderFeatureWithSymbol(QgsFeature &feature, QgsSymbolV2 *symbol, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker)
virtual void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
static bool createSymbolLayerV2ListFromSld(QDomElement &element, QGis::GeometryType geomType, QgsSymbolLayerV2List &layers)
int renderingPass() const
virtual double width() const
void stopRender(QgsRenderContext &context)
Stop a rendering process.
virtual QgsFeatureRendererV2 * clone() const =0
QString number(int n, int base)
int count(const T &value) const
virtual QDomElement save(QDomDocument &doc) override
store renderer info to XML element
void append(const T &value)
static void refineRuleCategories(Rule *initialRule, QgsCategorizedSymbolRendererV2 *r)
take a rule and create a list of new rules based on the categories from categorized symbol renderer ...
QString localName() const
const QgsFeatureRendererV2 * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QString classAttribute() const
void startRender(QgsRenderContext &context, const QgsFields *fields=nullptr)
int toInt(bool *ok) const
virtual void stopRender(QgsRenderContext &context) override
Needs to be called when a render cycle has finished to clean up.
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
const QgsRangeList & ranges() const
QSet< QString > usedAttributes() const
Return the attributes used to evaluate the expression of this rule.
void setAttribute(const QString &name, const QString &value)
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
bool isFilterOK(QgsFeature &f, QgsRenderContext *context=nullptr) const
Check if a given feature shall be rendered by this rule.
int toInt(bool *ok, int base) const
void appendChild(Rule *rule)
add child rule, take ownership, sets this as parent
static Rule * create(QDomElement &ruleElem, QgsSymbolV2Map &symbolMap)
Create a rule from an XML definition.
int removeAll(const T &value)
RenderResult renderFeature(FeatureToRender &featToRender, QgsRenderContext &context, RenderQueue &renderQueue)
Render a given feature, will recursively call subclasses and only render if the constraints apply...
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QString classAttribute() const
QSet< QString > legendKeysForFeature(QgsFeature &feat, QgsRenderContext *context=nullptr)
Returns which legend keys match the feature.
int symbolLayerCount()
Returns total number of symbol layers contained in the symbol.
This class keeps data about a rules for rule-based renderer.
void setRuleKey(const QString &key)
Override the assigned rule key (should be used just internally by rule-based renderer) ...
virtual void toSld(QDomDocument &doc, QDomElement &element) const override
Writes the SLD element following the SLD v1.1 specs.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
Rule * clone() const
clone this rule, return new instance
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
RuleList descendants() const
Returns all children, grand-children, grand-grand-children, grand-gra...
bool willRenderFeature(QgsFeature &feat, QgsRenderContext *context=nullptr)
only tell whether a feature will be rendered without actually rendering it
bool usingSymbolLevels() const
QList< RenderJob * > jobs
int scaleMaxDenom() const
virtual Q_DECL_DEPRECATED QgsSymbolV2List symbols()
For symbol levels.
Rule * mRootRule
the root node with hierarchical list of rules
virtual bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
Render a feature using this renderer in the given context.
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="") const
static void refineRuleRanges(Rule *initialRule, QgsGraduatedSymbolRendererV2 *r)
take a rule and create a list of new rules based on the ranges from graduated symbol renderer ...
Rule * takeChildAt(int i)
take child rule out, set parent as null
QDomText createTextNode(const QString &value)
QgsSymbolV2List symbolsForFeature(QgsFeature &feat, QgsRenderContext *context=nullptr)
tell which symbols will be used to render the feature
void updateElseRules()
Check which child rules are else rules and update the internal list of else rules.
virtual QString layerType() const =0
Returns a string that represents this layer type.
QString expression() const
Return the original, unmodified expression string.
QgsExpressionContext & expressionContext()
Gets the expression context.
A renderer that automatically displaces points with the same position.
virtual QgsSymbolV2 * subSymbol()
QgsRuleBasedRendererV2(QgsRuleBasedRendererV2::Rule *root)
Constructs the renderer from given tree of rules (takes ownership)
void setUsingSymbolLevels(bool usingSymbolLevels)
virtual QString dump() const override
for debugging
QgsFeatureRequest::OrderBy orderBy() const
Get the order in which features shall be processed by this renderer.
void copyRendererData(QgsFeatureRendererV2 *destRenderer) const
Clones generic renderer data to another renderer.
Contains information about the context of a rendering operation.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const
Creates a DOM element representing the rule in SLD format.
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat, QgsRenderContext &context) override
return list of symbols used for rendering the feature.
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature, QgsRenderContext &context) override
return symbol for current feature. Should not be used individually: there could be more symbols for a...
QDomNode firstChild() const
static void convertToDataDefinedSymbology(QgsSymbolV2 *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 orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
RenderResult
The result of rendering a rule.
void stopRender(QgsRenderContext &context)
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
QSet< T > & unite(const QSet< T > &other)
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
Rule(QgsSymbolV2 *symbol, int scaleMinDenom=0, int scaleMaxDenom=0, const QString &filterExp=QString(), const QString &label=QString(), const QString &description=QString(), bool elseRule=false)
Constructor takes ownership of the symbol.
void insert(int i, const T &value)
static QPixmap symbolPreviewPixmap(QgsSymbolV2 *symbol, QSize size, QgsRenderContext *customContext=nullptr)
QgsFeatureRequest::OrderBy mOrderBy
When drawing a vector layer with rule-based renderer, it goes through the rules and draws features wi...
static Rule * createFromSld(QDomElement &element, QGis::GeometryType geomType)
RuleList rulesForFeature(QgsFeature &feat, QgsRenderContext *context=nullptr)
tell which rules will be used to render the feature
QDomElement firstChildElement(const QString &tagName) const
static QgsExpression * expressionFromOgcFilter(const QDomElement &element)
Parse XML with OGC filter into QGIS expression.
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
bool isField() const
Checks whether an expression consists only of a single field reference.
QgsSymbolV2 * symbol() const
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
Needs to be called when a new render cycle is started.
virtual QgsRuleBasedRendererV2 * clone() const override
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
virtual QgsLegendSymbolListV2 legendSymbolItemsV2() const override
Return a list of symbology items for the legend.
QList< T > toList() const
static void clearSymbolMap(QgsSymbolV2Map &symbols)
void setSymbol(QgsSymbolV2 *sym)
set a new symbol (or NULL). Deletes old symbol.
virtual QList< QString > usedAttributes() override
Returns a set of attributes required for this renderer.
double toDouble(bool *ok) const
Abstract base class for marker symbol layers.
static QgsRuleBasedRendererV2 * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsRuleBasedRendererV2 from an existing renderer.
double lowerValue() const
QgsSymbolLayerV2 * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
const_iterator constEnd() const
void insertChild(int i, Rule *rule)
add child rule, take ownership, sets this as parent
void setFilterExpression(const QString &filterExp)
Set the expression used to check if a given feature shall be rendered with this rule.
QDomElement createElement(const QString &tagName)
const_iterator constBegin() const
QSet< QString > usedAttributes() const
Return a list of attributes required to render this feature.
int scaleMinDenom() const
int compare(const QString &other) const
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, const QString &rule="") override
return a list of item text / symbol
const QgsFeatureRendererV2 * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QString dump(int indent=0) const
Dump for debug purpose.
QList< FeatureToRender > mCurrentFeatures
virtual bool willRenderFeature(QgsFeature &feat, QgsRenderContext &context) override
return whether the renderer will render a feature or not.
double upperValue() const
static void refineRuleScales(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...
const T value(const Key &key) const
virtual Q_DECL_DEPRECATED void setDataDefinedProperty(const QString &property, const QString &expressionString)
Sets a data defined expression for a property.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
bool isScaleOK(double scale) const
Check if this rule applies for a given scale.