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 );
134 QString filterFunc = QStringLiteral(
"%1 = '%2'" )
135 .arg( attrName.replace(
'\"', QLatin1String(
"\"\"" ) ),
136 mValue.toString().replace(
'\'', QLatin1String(
"''" ) ) );
142 mSymbol->toSld( doc, ruleElem, props );
149 , mAttrName( attrName )
158 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
188 foundMatchingSymbol =
false;
191 QHash<QString, QgsSymbol *>::const_iterator it =
mSymbolHash.constFind( value.isNull() ? QLatin1String(
"" ) : value.toString() );
205 foundMatchingSymbol =
true;
235 QVariant value = valueForFeature( feature, context );
237 bool foundCategory =
false;
241 if ( !foundCategory )
279 if ( catIndex < 0 || catIndex >=
mCategories.size() )
287 if ( catIndex < 0 || catIndex >=
mCategories.size() )
295 if ( catIndex < 0 || catIndex >=
mCategories.size() )
303 if ( catIndex < 0 || catIndex >=
mCategories.size() )
313 QgsDebugMsg(
"invalid symbol in a category! ignoring..." );
322 if ( catIndex < 0 || catIndex >=
mCategories.size() )
351 if ( order == Qt::AscendingOrder )
363 return QString::localeAwareCompare( c1.
label(), c2.
label() ) < 0;
373 if ( order == Qt::AscendingOrder )
419 QSet<QString> attributes;
427 QgsExpression testExpr( mAttrName );
428 if ( !testExpr.hasParserError() )
429 attributes.unite( testExpr.referencedColumns() );
431 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
445 QString s = QStringLiteral(
"CATEGORIZED: idx %1\n" ).arg(
mAttrName );
470 newProps[ QStringLiteral(
"attribute" )] =
mAttrName;
475 it->toSld( doc, element, newProps );
482 bool isExpression = ( attrNum == -1 );
484 bool hasDefault =
false;
485 bool defaultActive =
false;
486 bool allActive =
true;
487 bool noneActive =
true;
491 QString activeValues;
492 QString inactiveValues;
496 if ( cat.
value() ==
"" )
505 QVariant::Type valType = isExpression ? cat.
value().type() : fields.
at( attrNum ).
type();
506 QString value = QgsExpression::quotedValue( cat.
value(), valType );
510 if ( cat.
value() !=
"" )
512 if ( !inactiveValues.isEmpty() )
513 inactiveValues.append(
',' );
515 inactiveValues.append( value );
520 if ( cat.
value() !=
"" )
522 if ( !activeValues.isEmpty() )
523 activeValues.append(
',' );
525 activeValues.append( value );
530 QString attr = isExpression ?
mAttrName : QStringLiteral(
"\"%1\"" ).arg(
mAttrName );
532 if ( allActive && hasDefault )
536 else if ( noneActive )
538 return QStringLiteral(
"FALSE" );
540 else if ( defaultActive )
542 return QStringLiteral(
"(%1) NOT IN (%2) OR (%1) IS NULL" ).arg( attr, inactiveValues );
546 return QStringLiteral(
"(%1) IN (%2)" ).arg( attr, activeValues );
557 lst.append( cat.
symbol() );
564 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
565 if ( symbolsElem.isNull() )
568 QDomElement catsElem = element.firstChildElement( QStringLiteral(
"categories" ) );
569 if ( catsElem.isNull() )
575 QDomElement catElem = catsElem.firstChildElement();
576 while ( !catElem.isNull() )
578 if ( catElem.tagName() == QLatin1String(
"category" ) )
580 QVariant value = QVariant( catElem.attribute( QStringLiteral(
"value" ) ) );
581 QString symbolName = catElem.attribute( QStringLiteral(
"symbol" ) );
582 QString label = catElem.attribute( QStringLiteral(
"label" ) );
583 bool render = catElem.attribute( QStringLiteral(
"render" ) ) != QLatin1String(
"false" );
584 if ( symbolMap.contains( symbolName ) )
586 QgsSymbol *symbol = symbolMap.take( symbolName );
590 catElem = catElem.nextSiblingElement();
593 QString attrName = element.attribute( QStringLiteral(
"attr" ) );
601 QDomElement sourceSymbolElem = element.firstChildElement( QStringLiteral(
"source-symbol" ) );
602 if ( !sourceSymbolElem.isNull() )
605 if ( sourceSymbolMap.contains( QStringLiteral(
"0" ) ) )
613 QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
614 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
619 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"rotation" ) );
620 if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
632 QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral(
"sizescale" ) );
633 if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
639 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
645 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
649 QDomElement ddsLegendSizeElem = element.firstChildElement( QStringLiteral(
"data-defined-size-legend" ) );
650 if ( !ddsLegendSizeElem.isNull() )
663 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"categorizedSymbol" ) );
664 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
665 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
666 rendererElem.setAttribute( QStringLiteral(
"attr" ),
mAttrName );
673 QDomElement catsElem = doc.createElement( QStringLiteral(
"categories" ) );
674 QgsCategoryList::const_iterator it =
mCategories.constBegin();
678 QString symbolName = QString::number( i );
679 symbols.insert( symbolName, cat.
symbol() );
681 QDomElement catElem = doc.createElement( QStringLiteral(
"category" ) );
682 catElem.setAttribute( QStringLiteral(
"value" ), cat.
value().toString() );
683 catElem.setAttribute( QStringLiteral(
"symbol" ), symbolName );
684 catElem.setAttribute( QStringLiteral(
"label" ), cat.
label() );
685 catElem.setAttribute( QStringLiteral(
"render" ), cat.
renderState() ?
"true" :
"false" );
686 catsElem.appendChild( catElem );
689 rendererElem.appendChild( catsElem );
693 rendererElem.appendChild( symbolsElem );
701 sourceSymbols.insert( QStringLiteral(
"0" ),
mSourceSymbol.get() );
703 rendererElem.appendChild( sourceSymbolElem );
710 rendererElem.appendChild( colorRampElem );
713 QDomElement rotationElem = doc.createElement( QStringLiteral(
"rotation" ) );
714 rendererElem.appendChild( rotationElem );
716 QDomElement sizeScaleElem = doc.createElement( QStringLiteral(
"sizescale" ) );
717 rendererElem.appendChild( sizeScaleElem );
724 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
726 rendererElem.appendChild( orderBy );
728 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
732 QDomElement ddsLegendElem = doc.createElement( QStringLiteral(
"data-defined-size-legend" ) );
734 rendererElem.appendChild( ddsLegendElem );
764 if ( sSize != ddSize )
767 return baseLegendSymbolItems();
784 lst += baseLegendSymbolItems();
789 return baseLegendSymbolItems();
794 QString value = valueForFeature( feature, context ).toString();
799 if ( value == cat.
value() )
802 return QSet< QString >() << QString::number( i );
804 return QSet< QString >();
809 return QSet< QString >();
847 double value = count / num;
874 int index = key.toInt( &ok );
875 if ( ok && index >= 0 && index <
mCategories.size() )
884 int index = key.toInt( &ok );
894 int index = key.toInt( &ok );
902 if ( renderer->
type() == QLatin1String(
"categorizedSymbol" ) )
906 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
909 if ( pointDistanceRenderer )
912 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
915 if ( invertedPolygonRenderer )
927 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.
QgsSymbol * originalSymbolForFeature(QgsFeature &feature, QgsRenderContext &context) override
Return symbol for feature.
Q_DECL_DEPRECATED QgsSymbol * skipRender()
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.
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
Get 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.
Q_DECL_DEPRECATED QgsSymbol * symbolForValue(const QVariant &value)
Returns the matching symbol corresponding to an attribute value.
QgsPaintEffect * mPaintEffect
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)
return 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
Get 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
virtual void setTotalColorCount(const int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
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
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.
QSet< QString > legendKeysForFeature(QgsFeature &feature, QgsRenderContext &context) override
Return legend keys matching a specified feature.
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()
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.
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.
QgsSymbol * symbolForFeature(QgsFeature &feature, QgsRenderContext &context) override
To be overridden.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Return 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.
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
Get 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)
return 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
QgsSymbolList symbols(QgsRenderContext &context) override
Returns list of symbols used by the renderer.
bool updateCategorySymbol(int catIndex, QgsSymbol *symbol)
bool valueLessThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
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.
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
Return 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.