33 #include <QDomDocument> 34 #include <QDomElement> 114 if ( !
mSymbol.get() || props.value( QStringLiteral(
"attribute" ), QLatin1String(
"" ) ).isEmpty() )
117 QString attrName = props[ QStringLiteral(
"attribute" )];
119 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
120 element.appendChild( ruleElem );
122 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
123 nameElem.appendChild( doc.createTextNode(
mLabel ) );
124 ruleElem.appendChild( nameElem );
126 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
127 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
128 QString descrStr = QStringLiteral(
"%1 is '%2'" ).arg( attrName,
mValue.toString() );
129 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
130 descrElem.appendChild( titleElem );
131 ruleElem.appendChild( descrElem );
137 filterFunc = QStringLiteral(
"%1 = '%2' or %1 is null" )
138 .arg( attrName.replace(
'\"', QLatin1String(
"\"\"" ) ),
139 mValue.toString().replace(
'\'', QLatin1String(
"''" ) ) );
143 filterFunc = QStringLiteral(
"%1 = '%2'" )
144 .arg( attrName.replace(
'\"', QLatin1String(
"\"\"" ) ),
145 mValue.toString().replace(
'\'', QLatin1String(
"''" ) ) );
153 mSymbol->toSld( doc, ruleElem, props );
160 , mAttrName( attrName )
169 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
199 foundMatchingSymbol =
false;
202 QHash<QString, QgsSymbol *>::const_iterator it =
mSymbolHash.constFind( value.isNull() ? QLatin1String(
"" ) : value.toString() );
216 foundMatchingSymbol =
true;
246 QVariant value = valueForFeature( feature, context );
248 bool foundCategory =
false;
252 if ( !foundCategory )
290 if ( catIndex < 0 || catIndex >=
mCategories.size() )
298 if ( catIndex < 0 || catIndex >=
mCategories.size() )
306 if ( catIndex < 0 || catIndex >=
mCategories.size() )
314 if ( catIndex < 0 || catIndex >=
mCategories.size() )
324 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
333 if ( catIndex < 0 || catIndex >=
mCategories.size() )
362 if ( order == Qt::AscendingOrder )
374 return QString::localeAwareCompare( c1.
label(), c2.
label() ) < 0;
384 if ( order == Qt::AscendingOrder )
430 QSet<QString> attributes;
442 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
456 QString s = QStringLiteral(
"CATEGORIZED: idx %1\n" ).arg(
mAttrName );
481 newProps[ QStringLiteral(
"attribute" )] =
mAttrName;
486 it->toSld( doc, element, newProps );
493 bool isExpression = ( attrNum == -1 );
495 bool hasDefault =
false;
496 bool defaultActive =
false;
497 bool allActive =
true;
498 bool noneActive =
true;
502 QString activeValues;
503 QString inactiveValues;
507 if ( cat.
value() ==
"" )
516 QVariant::Type valType = isExpression ? cat.
value().type() : fields.
at( attrNum ).
type();
521 if ( cat.
value() !=
"" )
523 if ( !inactiveValues.isEmpty() )
524 inactiveValues.append(
',' );
526 inactiveValues.append( value );
531 if ( cat.
value() !=
"" )
533 if ( !activeValues.isEmpty() )
534 activeValues.append(
',' );
536 activeValues.append( value );
541 QString attr = isExpression ?
mAttrName : QStringLiteral(
"\"%1\"" ).arg(
mAttrName );
543 if ( allActive && hasDefault )
547 else if ( noneActive )
549 return QStringLiteral(
"FALSE" );
551 else if ( defaultActive )
553 return QStringLiteral(
"(%1) NOT IN (%2) OR (%1) IS NULL" ).arg( attr, inactiveValues );
557 return QStringLiteral(
"(%1) IN (%2)" ).arg( attr, activeValues );
568 lst.append( cat.
symbol() );
575 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
576 if ( symbolsElem.isNull() )
579 QDomElement catsElem = element.firstChildElement( QStringLiteral(
"categories" ) );
580 if ( catsElem.isNull() )
586 QDomElement catElem = catsElem.firstChildElement();
587 while ( !catElem.isNull() )
589 if ( catElem.tagName() == QLatin1String(
"category" ) )
591 QVariant value = QVariant( catElem.attribute( QStringLiteral(
"value" ) ) );
592 QString symbolName = catElem.attribute( QStringLiteral(
"symbol" ) );
593 QString label = catElem.attribute( QStringLiteral(
"label" ) );
594 bool render = catElem.attribute( QStringLiteral(
"render" ) ) != QLatin1String(
"false" );
595 if ( symbolMap.contains( symbolName ) )
597 QgsSymbol *symbol = symbolMap.take( symbolName );
601 catElem = catElem.nextSiblingElement();
604 QString attrName = element.attribute( QStringLiteral(
"attr" ) );
612 QDomElement sourceSymbolElem = element.firstChildElement( QStringLiteral(
"source-symbol" ) );
613 if ( !sourceSymbolElem.isNull() )
616 if ( sourceSymbolMap.contains( QStringLiteral(
"0" ) ) )
624 QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
625 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
630 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"rotation" ) );
631 if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
643 QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral(
"sizescale" ) );
644 if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
650 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
656 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
660 QDomElement ddsLegendSizeElem = element.firstChildElement( QStringLiteral(
"data-defined-size-legend" ) );
661 if ( !ddsLegendSizeElem.isNull() )
674 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"categorizedSymbol" ) );
675 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
676 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
677 rendererElem.setAttribute( QStringLiteral(
"attr" ),
mAttrName );
684 QDomElement catsElem = doc.createElement( QStringLiteral(
"categories" ) );
685 QgsCategoryList::const_iterator it =
mCategories.constBegin();
689 QString symbolName = QString::number( i );
690 symbols.insert( symbolName, cat.
symbol() );
692 QDomElement catElem = doc.createElement( QStringLiteral(
"category" ) );
693 catElem.setAttribute( QStringLiteral(
"value" ), cat.
value().toString() );
694 catElem.setAttribute( QStringLiteral(
"symbol" ), symbolName );
695 catElem.setAttribute( QStringLiteral(
"label" ), cat.
label() );
696 catElem.setAttribute( QStringLiteral(
"render" ), cat.
renderState() ?
"true" :
"false" );
697 catsElem.appendChild( catElem );
700 rendererElem.appendChild( catsElem );
704 rendererElem.appendChild( symbolsElem );
712 sourceSymbols.insert( QStringLiteral(
"0" ),
mSourceSymbol.get() );
714 rendererElem.appendChild( sourceSymbolElem );
721 rendererElem.appendChild( colorRampElem );
724 QDomElement rotationElem = doc.createElement( QStringLiteral(
"rotation" ) );
725 rendererElem.appendChild( rotationElem );
727 QDomElement sizeScaleElem = doc.createElement( QStringLiteral(
"sizescale" ) );
728 rendererElem.appendChild( sizeScaleElem );
735 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
737 rendererElem.appendChild( orderBy );
739 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
743 QDomElement ddsLegendElem = doc.createElement( QStringLiteral(
"data-defined-size-legend" ) );
745 rendererElem.appendChild( ddsLegendElem );
775 if ( sSize != ddSize )
778 return baseLegendSymbolItems();
795 lst += baseLegendSymbolItems();
800 return baseLegendSymbolItems();
805 QString value = valueForFeature( feature, context ).toString();
810 if ( value == cat.
value() )
813 return QSet< QString >() << QString::number( i );
815 return QSet< QString >();
820 return QSet< QString >();
858 double value = count / num;
885 int index = key.toInt( &ok );
886 if ( ok && index >= 0 && index <
mCategories.size() )
895 int index = key.toInt( &ok );
905 int index = key.toInt( &ok );
913 if ( renderer->
type() == QLatin1String(
"categorizedSymbol" ) )
917 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
920 if ( pointDistanceRenderer )
923 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
926 if ( invertedPolygonRenderer )
938 if ( !symbols.isEmpty() )
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
int lookupField(const QString &fieldName) const
Look up field's index from the field name.
Q_DECL_DEPRECATED QgsSymbol * skipRender()
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...
double rendererScale() const
Returns the renderer map scale.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
QList< QgsLegendSymbolItem > QgsLegendSymbolList
QgsFeatureRequest::OrderBy mOrderBy
void updateColorRamp(QgsColorRamp *ramp)
Update the color ramp used and all symbols colors.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
bool updateCategoryRenderState(int catIndex, bool render)
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
create renderer from XML element
QgsSymbol * symbol() const
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
QgsCategorizedSymbolRenderer(const QString &attrName=QString(), const QgsCategoryList &categories=QgsCategoryList())
Abstract base class for color ramps.
void moveCategory(int from, int to)
Moves the category at index position from to index position to.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
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...
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
bool updateCategoryLabel(int catIndex, const QString &label)
static void clearSymbolMap(QgsSymbolMap &symbols)
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
QgsPaintEffect * mPaintEffect
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
std::unique_ptr< QgsSymbol > mSourceSymbol
int categoryIndexForLabel(const QString &val)
Returns index of category with specified label (-1 if not found or not unique)
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
void swap(QgsRendererCategory &other)
QMap< QString, QString > QgsStringMap
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
bool valueGreaterThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QList< QgsRendererCategory > QgsCategoryList
QgsCategorizedSymbolRenderer * clone() const override
Create a deep copy of this renderer.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
store renderer info to XML element
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend when using data-defined size for marker symbols...
QList< QgsSymbol * > QgsSymbolList
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props) const
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
#define QgsDebugMsgLevel(str, level)
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 labelGreaterThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
std::unique_ptr< QgsSymbol > mSymbol
QgsCategoryList mCategories
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
void updateFromSymbolAndProperty(const QgsMarkerSymbol *symbol, const QgsProperty &ddSize)
Updates the list of classes, source symbol and title label from given symbol and property.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static void convertSymbolSizeScale(QgsSymbol *symbol, QgsSymbol::ScaleMethod method, const QString &field)
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
QgsSymbol * sourceSymbol()
Returns the renderer's source symbol, which is the base symbol used for the each categories' symbol b...
A store for object properties.
void deleteAllCategories()
virtual void setTotalColorCount(int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
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 ...
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
bool renderState() const
Returns true if the category is currently enabled and should be rendered.
void setSymbol(QgsSymbol *s)
bool labelLessThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
void setRenderState(bool render)
Sets whether the category is currently enabled and should be rendered.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
Totally random color ramp.
Q_DECL_DEPRECATED QgsSymbol * symbolForValue(const QVariant &value) const
Returns the matching symbol corresponding to an attribute value.
QString dump() const override
Returns debug information about this renderer.
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
void setDataDefinedSizeLegend(QgsDataDefinedSizeLegend *settings)
Configures appearance of legend when renderer is configured to use data-defined size for marker symbo...
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
static void convertSymbolRotation(QgsSymbol *symbol, const QString &field)
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
void addCategory(const QgsRendererCategory &category)
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.
void setSourceColorRamp(QgsColorRamp *ramp)
Sets the source color ramp.
bool usingSymbolLevels() const
QgsColorRamp * sourceColorRamp()
Returns the source color ramp, from which each categories' color is derived.
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
QgsRendererCategory & operator=(QgsRendererCategory cat)
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
virtual QgsSymbol * clone() const =0
Gets a deep copy of this symbol.
std::unique_ptr< QgsColorRamp > mSourceColorRamp
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
int categoryIndexForValue(const QVariant &val)
Returns index of category with specified value (-1 if not found)
bool updateCategoryValue(int catIndex, const QVariant &value)
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 updateCategorySymbol(int catIndex, QgsSymbol *symbol)
bool valueLessThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
static QgsCategorizedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsCategorizedSymbolRenderer from an existing renderer.
QHash< QString, QgsSymbol * > mSymbolHash
hashtable for faster access to symbols
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
void updateSymbols(QgsSymbol *sym)
Update all the symbols but leave categories and colors.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QgsRendererCategory()=default
Constructor for QgsRendererCategory.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend...
std::unique_ptr< QgsExpression > mExpression
int mAttrNum
attribute index (derived from attribute name in startRender)
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
void setSourceSymbol(QgsSymbol *sym)
Sets the source symbol for the renderer, which is the base symbol used for the each categories' symbo...
void stopRender(QgsRenderContext &context)
Ends the rendering process.
void setLabel(const QString &label)
static QgsDataDefinedSizeLegend * readXml(const QDomElement &elem, const QgsReadWriteContext &context) SIP_FACTORY
Creates instance from given element and returns it (caller takes ownership). Returns null on error...
bool deleteCategory(int catIndex)
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
void setValue(const QVariant &value)
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
bool isActive() const
Returns whether the property is currently active.
std::unique_ptr< QgsDataDefinedSizeLegend > mDataDefinedSizeLegend
void setColor(const QColor &color)
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.