32 #include <QDomDocument>
33 #include <QDomElement>
38 : mParent( NULL ), mSymbol( symbol )
39 , mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom )
40 , mFilterExp( filterExp ), mLabel( label ), mDescription( description )
41 , mElseRule( elseRule )
53 qDeleteAll( mChildren );
59 if ( mElseRule || mFilterExp.compare(
"ELSE", Qt::CaseInsensitive ) == 0 )
64 else if ( !mFilterExp.isEmpty() )
77 mChildren.append( rule );
84 mChildren.insert( i, rule );
91 mChildren.removeAll( rule );
98 Rule* rule = mChildren[i];
99 mChildren.removeAt( i );
106 mChildren.removeAll( rule );
113 Rule* rule = mChildren.takeAt( i );
123 if ( key == mRuleKey )
126 foreach (
Rule* rule, mChildren )
138 foreach (
Rule* rule, mChildren )
150 QString symbolDump = ( mSymbol ? mSymbol->dump() :
QString(
"[]" ) );
151 QString msg = off +
QString(
"RULE %1 - scale [%2,%3] - filter %4 - symbol %5\n" )
152 .
arg( mLabel ).
arg( mScaleMinDenom ).
arg( mScaleMaxDenom )
153 .
arg( mFilterExp ).
arg( symbolDump );
156 foreach (
Rule* rule, mChildren )
160 msg += lst.
join(
"\n" );
169 attrs.
unite( mFilter->referencedColumns().toSet() );
171 attrs.
unite( mSymbol->usedAttributes() );
205 if ( mSymbol && ( ruleFilter.
isEmpty() || mLabel == ruleFilter ) )
206 lst << qMakePair( mLabel, mSymbol );
211 if ( scaleDenominator == -1 || rule->
isScaleOK( scaleDenominator ) )
222 if ( currentLevel != -1 )
224 lst <<
QgsLegendSymbolItemV2( mSymbol, mLabel, mRuleKey,
true, mScaleMinDenom, mScaleMaxDenom, currentLevel, mParent ? mParent->mRuleKey :
QString() );
238 if ( ! mFilter || mElseRule )
241 QVariant res = mFilter->evaluate( &f );
242 return res.
toInt() != 0;
249 if ( mScaleMinDenom == 0 && mScaleMaxDenom == 0 )
251 if ( mScaleMinDenom != 0 && mScaleMinDenom > scale )
253 if ( mScaleMaxDenom != 0 && mScaleMaxDenom < scale )
261 Rule* newrule =
new Rule( sym, mScaleMinDenom, mScaleMaxDenom, mFilterExp, mLabel, mDescription );
264 foreach (
Rule* rule, mChildren )
275 int symbolIndex = symbolMap.
size();
279 if ( !mFilterExp.isEmpty() )
281 if ( mScaleMinDenom != 0 )
282 ruleElem.
setAttribute(
"scalemindenom", mScaleMinDenom );
283 if ( mScaleMaxDenom != 0 )
284 ruleElem.
setAttribute(
"scalemaxdenom", mScaleMaxDenom );
285 if ( !mLabel.isEmpty() )
287 if ( !mDescription.isEmpty() )
307 if ( !mFilterExp.isEmpty() )
309 if ( !props.
value(
"filter",
"" ).isEmpty() )
310 props[
"filter" ] +=
" AND ";
311 props[
"filter" ] += mFilterExp;
314 if ( mScaleMinDenom != 0 )
317 int parentScaleMinDenom = props.
value(
"scaleMinDenom",
"0" ).toInt( &ok );
318 if ( !ok || parentScaleMinDenom <= 0 )
321 props[
"scaleMinDenom" ] =
QString::number( qMax( parentScaleMinDenom, mScaleMinDenom ) );
324 if ( mScaleMaxDenom != 0 )
327 int parentScaleMaxDenom = props.
value(
"scaleMaxDenom",
"0" ).toInt( &ok );
328 if ( !ok || parentScaleMaxDenom <= 0 )
331 props[
"scaleMaxDenom" ] =
QString::number( qMin( parentScaleMaxDenom, mScaleMaxDenom ) );
345 if ( !mLabel.isEmpty() || !mDescription.isEmpty() )
348 if ( !mLabel.isEmpty() )
354 if ( !mDescription.isEmpty() )
363 if ( !props.
value(
"filter",
"" ).isEmpty() )
368 if ( !props.
value(
"scaleMinDenom",
"" ).isEmpty() )
375 if ( !props.
value(
"scaleMaxDenom",
"" ).isEmpty() )
382 mSymbol->toSld( doc, ruleElem, props );
388 ( *it )->toSld( doc, element, props );
394 mActiveChildren.clear();
405 mFilter->prepare( fields );
407 mSymbol->startRender( context, &fields );
417 mActiveChildren.append( rule );
431 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
433 symbolZLevelsSet.
insert( mSymbol->symbolLayer( i )->renderingPass() );
439 for ( it = mActiveChildren.
begin(); it != mActiveChildren.
end(); ++it )
444 return symbolZLevelsSet;
451 for (
int i = 0; i < mSymbol->symbolLayerCount(); i++ )
453 int normLevel = zLevelsToNormLevels.
value( mSymbol->symbolLayer( i )->renderingPass() );
454 mSymbolNormZLevels.append( normLevel );
469 if ( !isFilterOK( featToRender.
feat ) )
472 bool rendered =
false;
478 foreach (
int normZLevel, mSymbolNormZLevels )
481 renderQueue[normZLevel].jobs.
append(
new RenderJob( featToRender, mSymbol ) );
486 bool willrendersomething =
false;
497 willrendersomething |= rule->
renderFeature( featToRender, context, renderQueue );
498 rendered |= willrendersomething;
502 if ( !willrendersomething )
504 foreach (
Rule* rule, mElseRules )
506 rendered |= rule->
renderFeature( featToRender, context, renderQueue );
515 if ( !isFilterOK( feat ) )
532 if ( !isFilterOK( feat ) )
548 if ( !isFilterOK( feat ) )
565 mSymbol->stopRender( context );
573 mActiveChildren.clear();
574 mSymbolNormZLevels.clear();
583 if ( symbolMap.
contains( symbolIdx ) )
585 symbol = symbolMap.
take( symbolIdx );
589 QgsDebugMsg(
"symbol for rule " + symbolIdx +
" not found!" );
596 int scaleMinDenom = ruleElem.
attribute(
"scalemindenom",
"0" ).
toInt();
597 int scaleMaxDenom = ruleElem.
attribute(
"scalemaxdenom",
"0" ).
toInt();
599 Rule* rule =
new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
607 while ( !childRuleElem.
isNull() )
609 Rule* childRule =
create( childRuleElem, symbolMap );
632 QString label, description, filterExp;
633 int scaleMinDenom = 0, scaleMaxDenom = 0;
638 while ( !childElem.
isNull() )
647 else if ( childElem.
localName() ==
"Description" )
651 if ( !titleElem.
isNull() )
657 if ( !abstractElem.
isNull() )
662 else if ( childElem.
localName() ==
"Abstract" )
667 else if ( childElem.
localName() ==
"Title" )
672 else if ( childElem.
localName() ==
"Filter" )
688 else if ( childElem.
localName() ==
"MinScaleDenominator" )
695 else if ( childElem.
localName() ==
"MaxScaleDenominator" )
713 if ( layers.
size() > 0 )
736 return new Rule( symbol, scaleMinDenom, scaleMaxDenom, filterExp, label, description );
770 bool drawVertexMarker )
789 qSort( symbolZLevels );
794 int maxNormLevel = -1;
795 foreach (
int zLevel, symbolZLevels )
797 zLevelsToNormLevels[zLevel] = ++maxNormLevel;
822 for (
int i = 0; i < count; i++ )
861 Q_ASSERT( origDescendants.
count() == clonedDescendants.
count() );
862 for (
int i = 0; i < origDescendants.
count(); ++i )
863 clonedDescendants[i]->setRuleKey( origDescendants[i]->ruleKey() );
912 lst << qMakePair( pair.first, pix );
950 if ( symbolsElem.
isNull() )
975 while ( !ruleElem.
isNull() )
982 root =
new Rule( 0 );
1010 if ( cat.
value().
type() == QVariant::Int )
1012 else if ( cat.
value().
type() == QVariant::Double )
1045 foreach (
int scale, scales )
1049 if ( maxDenom != 0 && maxDenom <= scale )
1060 QString msg(
"Rule-based renderer:\n" );
1082 if ( renderer->
type() ==
"RuleRenderer" )
1087 if ( renderer->
type() ==
"singleSymbol" )
1090 if ( !singleSymbolRenderer )
1098 if ( renderer->
type() ==
"categorizedSymbol" )
1101 if ( !categorizedRenderer )
1109 for (
int i = 0; i < categorizedRenderer->
categories().
size(); ++i )
1118 if (
QVariant( category.
value() ).convert( QVariant::Double ) )
1128 if ( value ==
"''" )
1130 expression =
"ELSE";
1134 expression = categorizedRenderer->
classAttribute() +
" = " + value;
1152 if ( renderer->
type() ==
"graduatedSymbol" )
1156 if ( !graduatedRenderer )
1163 for (
int i = 0; i < graduatedRenderer->
ranges().
size();++i )
1195 if ( renderer->
type() ==
"pointDisplacement" )
1198 if ( pointDisplacementRenderer )
1201 if ( renderer->
type() ==
"invertedPolygonRenderer" )
1204 if ( invertedPolygonRenderer )
1214 switch ( symbol->
type() )
1220 if ( ! sizeScaleField.
isNull() )
1222 sizeExpression =
QString(
"%1*(%2)" ).
arg( msl->
size() ).arg( sizeScaleField );
1225 if ( ! rotationField.
isNull() )
1232 if ( ! sizeScaleField.
isNull() )
1239 sizeExpression =
QString(
"%1*(%2)" ).
arg( lsl->
width() ).arg( sizeScaleField );
1248 sizeExpression =
QString(
"%1*(%2)" ).
arg( msl->
size() ).arg( sizeScaleField );
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props)
Class for parsing and evaluation of expressions (formerly called "search strings").
QgsSymbolV2List symbolsForFeature(QgsFeature &feat)
tell which symbols will be used to render the feature
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 ...
#define RENDERER_TAG_NAME
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
QgsSymbolV2 * symbol() const
A container class for data source field mapping or expression.
const QgsCategoryList & categories() const
bool contains(const Key &key) const
static QString quotedColumnRef(QString name)
return quoted column reference (in double quotes)
virtual double width() const
QString & fill(QChar ch, int size)
virtual QgsSymbolV2List symbols() override
for symbol levels
QSet< int > collectZLevels()
get all used z-levels from this rule and children
QDomNode appendChild(const QDomNode &newChild)
const QString expression() const
Alias for dump()
static QgsFeatureRendererV2 * create(QDomElement &element)
QString attribute(const QString &name, const QString &defValue) const
void setTagName(const QString &name)
QString nodeValue() const
static void convertToDataDefinedSymbology(QgsSymbolV2 *symbol, QString sizeScaleField, QString rotationField)
helper function to convert the size scale and rotation fields present in some other renderers to data...
QString classAttribute() const
double rendererScale() const
virtual QgsSymbolV2 * clone() const =0
virtual QgsFeatureRendererV2 * clone() const override
static QgsFeatureRendererV2 * createFromSld(QDomElement &element, QGis::GeometryType geomType)
void setLabel(QString label)
bool isScaleOK(double scale) const
QDomElement nextSiblingElement(const QString &tagName) const
bool startRender(QgsRenderContext &context, const QgsFields &fields)
prepare the rule for rendering and its children (build active children array)
Rule * clone() const
clone this rule, return new instance
~QgsRuleBasedRendererV2()
RuleList rulesForFeature(QgsFeature &feat)
tell which rules will be used to render the feature
Container of fields for a vector layer.
void removeChild(Rule *rule)
delete child rule
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...
virtual bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="") override
return a list of item text / symbol
QMap< QString, QString > QgsStringMap
QgsPaintEffect * mPaintEffect
void removeChildAt(int i)
delete child rule
virtual void checkLegendSymbolItem(QString key, bool state=true) override
item in symbology was checked
QString rotationField() const override
return rotation field name (or empty string if not set or not supported by renderer) ...
void renderFeatureWithSymbol(QgsFeature &feature, QgsSymbolV2 *symbol, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker)
void setCheckState(bool state)
double upperValue() const
static bool createSymbolLayerV2ListFromSld(QDomElement &element, QGis::GeometryType geomType, QgsSymbolLayerV2List &layers)
void stopRender(QgsRenderContext &context)
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat) override
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
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)
Rule(QgsSymbolV2 *symbol, int scaleMinDenom=0, int scaleMaxDenom=0, QString filterExp=QString(), QString label=QString(), QString description=QString(), bool elseRule=false)
Constructor takes ownership of the symbol.
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
int scaleMinDenom() const
int toInt(bool *ok) const
void takeChild(Rule *rule)
take child rule out, set parent as null
QList< T > values() const
virtual void stopRender(QgsRenderContext &context) override
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
void setAttribute(const QString &name, const QString &value)
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, QString function)
int toInt(bool *ok, int base) const
void appendChild(Rule *rule)
add child rule, take ownership, sets this as parent
static QDomElement saveSymbols(QgsSymbolV2Map &symbols, QString tagName, QDomDocument &doc)
static Rule * create(QDomElement &ruleElem, QgsSymbolV2Map &symbolMap)
QString rotationField() const override
return rotation field name (or empty string if not set or not supported by renderer) ...
QgsSymbolV2 * symbol() const
QDomElement save(QDomDocument &doc, QgsSymbolV2Map &symbolMap)
bool isFilterOK(QgsFeature &f) const
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
used from subclasses to create SLD Rule elements following SLD v1.1 specs
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
virtual QgsLegendSymbologyList legendSymbologyItems(QSize iconSize) override
return a list of symbology items for the legend
QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
QString ruleKey() const
Unique rule identifier (for identification of rule within renderer)
QList< RenderJob * > jobs
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
virtual bool willRenderFeature(QgsFeature &feat) override
return whether the renderer will render a feature or not.
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 ...
QString dump(int offset=0) const
Rule * takeChildAt(int i)
take child rule out, set parent as null
bool renderFeature(FeatureToRender &featToRender, QgsRenderContext &context, RenderQueue &renderQueue)
RuleList descendants() const
virtual bool legendSymbolItemChecked(QString key) override
items of symbology items in legend is checked
QgsFeatureRendererV2 * embeddedRenderer() const
QDomText createTextNode(const QString &value)
QgsLegendSymbolListV2 legendSymbolItemsV2(int currentLevel=-1) const
int renderingPass() const
virtual QString layerType() const =0
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
QString rotationField() const override
return rotation field name (or empty string if not set or not supported by renderer) ...
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
int scaleMaxDenom() const
QString sizeScaleField() const
Contains information about the context of a rendering operation.
const QgsFeatureRendererV2 * embeddedRenderer() const
QDomNode firstChild() const
void copyPaintEffect(QgsFeatureRendererV2 *destRenderer) const
Copies paint effect of this renderer to another renderer.
QSet< T > & unite(const QSet< T > &other)
double lowerValue() const
const QgsRangeList & ranges() const
QString sizeScaleField() const
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)
QDomElement firstChildElement(const QString &tagName) const
bool usingSymbolLevels() const
QString sizeScaleField() const
static QgsExpression * expressionFromOgcFilter(const QDomElement &element)
Parse XML with OGC filter into QGIS expression.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
QSet< QString > usedAttributes()
static QString quotedString(QString text)
return quoted string (in single quotes)
virtual QgsLegendSymbolListV2 legendSymbolItemsV2() const override
Return a list of symbology items for the legend.
QList< T > toList() const
QString classAttribute() const
static void clearSymbolMap(QgsSymbolV2Map &symbols)
void setSymbol(QgsSymbolV2 *sym)
set a new symbol (or NULL). Deletes old symbol.
virtual QList< QString > usedAttributes() override
double toDouble(bool *ok) const
static QgsRuleBasedRendererV2 * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsRuleBasedRendererV2 from an existing renderer.
QgsSymbolLayerV2 * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
void insertChild(int i, Rule *rule)
add child rule, take ownership, sets this as parent
QDomElement createElement(const QString &tagName)
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature) override
return symbol for current feature. Should not be used individually: there could be more symbols for a...
static QPixmap symbolPreviewPixmap(QgsSymbolV2 *symbol, QSize size, QgsRenderContext *customContext=0)
bool willRenderFeature(QgsFeature &feat)
only tell whether a feature will be rendered without actually rendering it
QString parserErrorString() const
Returns parser error.
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
void setFilterExpression(QString filterExp)
QgsSymbolV2 * symbol() const
QList< FeatureToRender > mCurrentFeatures
QgsSymbolV2List symbols()
Rule * findRuleByKey(QString key)
Try to find a rule given its unique key.
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...
virtual QgsSymbolV2List symbolsForFeature(QgsFeature &feat) override
return list of symbols used for rendering the feature.
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.