46#include <QDomDocument>
48#include <QRegularExpression>
58 mUuid = !
uuid.isEmpty() ?
uuid : QUuid::createUuid().toString();
137 if ( !
mSymbol.get() || props.value( QStringLiteral(
"attribute" ), QString() ).toString().isEmpty() )
140 QString attrName = props[ QStringLiteral(
"attribute" )].toString();
144 toSld( doc, element, attrName, context );
149 if ( !
mSymbol.get() || classAttribute.isEmpty() )
152 QString attrName = classAttribute;
163 else if ( attrExpression.
isField() )
166 qgis::down_cast<const QgsExpressionNodeColumnRef *>( attrExpression.
rootNode() )->name()
170 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
172 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
173 nameElem.appendChild( doc.createTextNode(
mLabel ) );
174 ruleElem.appendChild( nameElem );
176 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
177 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
178 QString descrStr = QStringLiteral(
"%1 is '%2'" ).arg( attrName,
mValue.toString() );
179 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
180 descrElem.appendChild( titleElem );
181 ruleElem.appendChild( descrElem );
185 if (
mValue.userType() == QMetaType::Type::QVariantList )
187 const QVariantList list =
mValue.toList();
188 if ( list.size() == 1 )
194 QStringList valuesList;
195 valuesList.reserve( list.size() );
196 for (
const QVariant &v : list )
200 filterFunc = QStringLiteral(
"%1 IN (%2)" ).arg( attrName,
201 valuesList.join(
',' ) );
206 filterFunc = QStringLiteral(
"ELSE" );
217 QVariantMap props = oldProps;
220 mSymbol->toSld( doc, ruleElem, context );
229 element.appendChild( ruleElem );
246 QgsDebugError( QStringLiteral(
"invalid symbol in a category! ignoring..." ) );
255 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
258 if (
QgsSymbol *catSymbol = catIt->symbol() )
276 const QVariant val = cat.value();
277 if ( val.userType() == QMetaType::Type::QVariantList )
279 const QVariantList list = val.toList();
280 for (
const QVariant &v : list )
282 mSymbolHash.insert( v.toString(), ( cat.renderState() ||
mCounting ) ? cat.symbol() :
nullptr );
287 mSymbolHash.insert( val.toString(), ( cat.renderState() ||
mCounting ) ? cat.symbol() :
nullptr );
305 foundMatchingSymbol =
false;
313 QgsDebugError( QStringLiteral(
"there are no hashed symbols!!!" ) );
322 foundMatchingSymbol =
true;
352 QVariant value = valueForFeature( feature, context );
354 bool foundCategory =
false;
358 if ( !foundCategory )
396 if ( catIndex < 0 || catIndex >=
mCategories.size() )
404 if ( catIndex < 0 || catIndex >=
mCategories.size() )
412 if ( catIndex < 0 || catIndex >=
mCategories.size() )
420 if ( catIndex < 0 || catIndex >=
mCategories.size() )
430 QgsDebugError( QStringLiteral(
"invalid symbol in a category! ignoring..." ) );
439 if ( catIndex < 0 || catIndex >=
mCategories.size() )
468 if ( order == Qt::AscendingOrder )
480 return QString::localeAwareCompare( c1.
label(), c2.
label() ) < 0;
485 return QString::localeAwareCompare( c1.
label(), c2.
label() ) > 0;
490 if ( order == Qt::AscendingOrder )
519 cat.symbol()->startRender( context, fields );
529 cat.symbol()->stopRender( context );
536 QSet<QString> attributes;
548 QgsCategoryList::const_iterator catIt =
mCategories.constBegin();
575 QString s = QStringLiteral(
"CATEGORIZED: idx %1\n" ).arg(
mAttrName );
600 toSld( doc, element, context );
606 QVariantMap newProps = oldProps;
607 newProps[ QStringLiteral(
"attribute" )] =
mAttrName;
614 if ( !it->toSld( doc, element,
mAttrName, context ) )
624 bool isExpression = ( attrNum == -1 );
626 bool hasDefault =
false;
627 bool defaultActive =
false;
628 bool allActive =
true;
629 bool noneActive =
true;
633 QString activeValues;
634 QString inactiveValues;
641 defaultActive = cat.renderState();
644 noneActive = noneActive && !cat.renderState();
645 allActive = allActive && cat.renderState();
647 const bool isList = cat.value().userType() == QMetaType::Type::QVariantList;
650 if ( !cat.renderState() )
656 const QVariantList list = cat.value().toList();
657 for (
const QVariant &v : list )
659 if ( !inactiveValues.isEmpty() )
660 inactiveValues.append(
',' );
667 if ( !inactiveValues.isEmpty() )
668 inactiveValues.append(
',' );
670 inactiveValues.append( value );
680 const QVariantList list = cat.value().toList();
681 for (
const QVariant &v : list )
683 if ( !activeValues.isEmpty() )
684 activeValues.append(
',' );
691 if ( !activeValues.isEmpty() )
692 activeValues.append(
',' );
694 activeValues.append( value );
700 QString attr = isExpression ?
mAttrName : QStringLiteral(
"\"%1\"" ).arg(
mAttrName );
702 if ( allActive && hasDefault )
706 else if ( noneActive )
708 return QStringLiteral(
"FALSE" );
710 else if ( defaultActive )
712 return QStringLiteral(
"(%1) NOT IN (%2) OR (%1) IS NULL" ).arg( attr, inactiveValues );
716 return QStringLiteral(
"(%1) IN (%2)" ).arg( attr, activeValues );
727 lst.append( cat.symbol() );
753 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
754 if ( symbolsElem.isNull() )
757 QDomElement catsElem = element.firstChildElement( QStringLiteral(
"categories" ) );
758 if ( catsElem.isNull() )
765 const auto valueFromString = [](
const QString & value,
const QString & valueType ) -> QVariant
767 if ( valueType == QLatin1String(
"double" ) )
770 const auto val { value.toDouble( &ok ) };
776 else if ( valueType == QLatin1String(
"ulong" ) )
779 const auto val { value.toULongLong( &ok ) };
785 else if ( valueType == QLatin1String(
"long" ) )
788 const auto val { value.toLongLong( &ok ) };
794 else if ( valueType == QLatin1String(
"bool" ) )
796 if ( value.toLower() == QLatin1String(
"false" ) )
798 if ( value.toLower() == QLatin1String(
"true" ) )
801 else if ( valueType == QLatin1String(
"NULL" ) )
809 QDomElement catElem = catsElem.firstChildElement();
811 QSet<QString> usedUuids;
812 while ( !catElem.isNull() )
814 if ( catElem.tagName() == QLatin1String(
"category" ) )
817 if ( catElem.hasAttribute( QStringLiteral(
"value" ) ) )
819 value = valueFromString( catElem.attribute( QStringLiteral(
"value" ) ), catElem.attribute( QStringLiteral(
"type" ), QString() ) ) ;
824 QDomElement valElem = catElem.firstChildElement();
825 while ( !valElem.isNull() )
827 if ( valElem.tagName() == QLatin1String(
"val" ) )
829 values << valueFromString( valElem.attribute( QStringLiteral(
"value" ) ), valElem.attribute( QStringLiteral(
"type" ), QString() ) );
831 valElem = valElem.nextSiblingElement();
833 if ( !values.isEmpty() )
836 QString symbolName = catElem.attribute( QStringLiteral(
"symbol" ) );
837 QString label = catElem.attribute( QStringLiteral(
"label" ) );
838 bool render = catElem.attribute( QStringLiteral(
"render" ) ) != QLatin1String(
"false" );
839 QString uuid = catElem.attribute( QStringLiteral(
"uuid" ), QString::number( i++ ) );
840 while ( usedUuids.contains( uuid ) )
842 uuid = QUuid::createUuid().toString();
844 if ( symbolMap.contains( symbolName ) )
846 QgsSymbol *symbol = symbolMap.take( symbolName );
851 catElem = catElem.nextSiblingElement();
854 QString attrName = element.attribute( QStringLiteral(
"attr" ) );
862 QDomElement sourceSymbolElem = element.firstChildElement( QStringLiteral(
"source-symbol" ) );
863 if ( !sourceSymbolElem.isNull() )
866 if ( sourceSymbolMap.contains( QStringLiteral(
"0" ) ) )
874 QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
875 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
880 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"rotation" ) );
881 if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
893 QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral(
"sizescale" ) );
894 if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
900 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
906 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
910 QDomElement ddsLegendSizeElem = element.firstChildElement( QStringLiteral(
"data-defined-size-legend" ) );
911 if ( !ddsLegendSizeElem.isNull() )
924 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"categorizedSymbol" ) );
925 rendererElem.setAttribute( QStringLiteral(
"attr" ),
mAttrName );
929 const auto stringForType = [](
const QMetaType::Type
type ) -> QString
931 if (
type == QMetaType::Type::QChar ||
type == QMetaType::Type::Int ||
type == QMetaType::Type::LongLong )
933 return QStringLiteral(
"long" );
935 else if (
type == QMetaType::Type::UInt ||
type == QMetaType::Type::ULongLong )
937 return QStringLiteral(
"ulong" );
939 else if (
type == QMetaType::Type::Double )
941 return QStringLiteral(
"double" ) ;
943 else if (
type == QMetaType::Type::Bool )
945 return QStringLiteral(
"bool" );
949 return QStringLiteral(
"string" );
958 QDomElement catsElem = doc.createElement( QStringLiteral(
"categories" ) );
959 QgsCategoryList::const_iterator it =
mCategories.constBegin();
963 QString symbolName = QString::number( i );
966 QDomElement catElem = doc.createElement( QStringLiteral(
"category" ) );
967 if ( cat.
value().userType() == QMetaType::Type::QVariantList )
969 const QVariantList list = cat.
value().toList();
970 for (
const QVariant &v : list )
972 QDomElement valueElem = doc.createElement( QStringLiteral(
"val" ) );
973 valueElem.setAttribute( QStringLiteral(
"value" ), v.toString() );
974 valueElem.setAttribute( QStringLiteral(
"type" ), stringForType(
static_cast<QMetaType::Type
>( v.userType() ) ) );
975 catElem.appendChild( valueElem );
983 catElem.setAttribute( QStringLiteral(
"value" ),
"NULL" );
984 catElem.setAttribute( QStringLiteral(
"type" ),
"NULL" );
988 catElem.setAttribute( QStringLiteral(
"value" ), cat.
value().toString() );
989 catElem.setAttribute( QStringLiteral(
"type" ), stringForType(
static_cast<QMetaType::Type
>( cat.
value().userType() ) ) );
992 catElem.setAttribute( QStringLiteral(
"symbol" ), symbolName );
993 catElem.setAttribute( QStringLiteral(
"label" ), cat.
label() );
994 catElem.setAttribute( QStringLiteral(
"render" ), cat.
renderState() ?
"true" :
"false" );
995 catElem.setAttribute( QStringLiteral(
"uuid" ), cat.
uuid() );
996 catsElem.appendChild( catElem );
999 rendererElem.appendChild( catsElem );
1003 rendererElem.appendChild( symbolsElem );
1010 sourceSymbols.insert( QStringLiteral(
"0" ),
mSourceSymbol.get() );
1012 rendererElem.appendChild( sourceSymbolElem );
1019 rendererElem.appendChild( colorRampElem );
1022 QDomElement rotationElem = doc.createElement( QStringLiteral(
"rotation" ) );
1023 rendererElem.appendChild( rotationElem );
1025 QDomElement sizeScaleElem = doc.createElement( QStringLiteral(
"sizescale" ) );
1026 rendererElem.appendChild( sizeScaleElem );
1030 QDomElement ddsLegendElem = doc.createElement( QStringLiteral(
"data-defined-size-legend" ) );
1032 rendererElem.appendChild( ddsLegendElem );
1037 return rendererElem;
1054 auto _displayString = [ ](
const QVariant & v,
int precision ) -> QString
1062 const bool isNumeric {v.userType() == QMetaType::Type::Double || v.userType() == QMetaType::Type::Int || v.userType() == QMetaType::Type::UInt || v.userType() == QMetaType::Type::LongLong || v.userType() == QMetaType::Type::ULongLong};
1065 if ( v.userType() == QMetaType::Type::Double )
1072 return v.toString();
1075 if ( QLocale().decimalPoint() !=
'.' ||
1076 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
1078 if ( precision > 0 )
1080 if ( -1 < v.toDouble() && v.toDouble() < 1 )
1082 return QLocale().toString( v.toDouble(),
'g', precision );
1086 return QLocale().toString( v.toDouble(),
'f', precision );
1093 const QString s( v.toString() );
1094 const int dotPosition( s.indexOf(
'.' ) );
1096 if ( dotPosition < 0 && s.indexOf(
'e' ) < 0 )
1099 return QLocale().toString( v.toDouble(),
'f', precision );
1103 if ( dotPosition < 0 ) precision = 0;
1104 else precision = s.length() - dotPosition - 1;
1106 if ( -1 < v.toDouble() && v.toDouble() < 1 )
1108 return QLocale().toString( v.toDouble(),
'g', precision );
1112 return QLocale().toString( v.toDouble(),
'f', precision );
1118 else if ( precision > 0 )
1120 if ( -1 < v.toDouble() && v.toDouble() < 1 )
1122 return QString::number( v.toDouble(),
'g', precision );
1126 return QString::number( v.toDouble(),
'f', precision );
1131 else if ( isNumeric &&
1132 !( QLocale().numberOptions() & QLocale::NumberOption::OmitGroupSeparator ) )
1135 const qlonglong converted( v.toLongLong( &ok ) );
1137 return QLocale().toString( converted );
1139 else if ( v.userType() == QMetaType::Type::QByteArray )
1141 return QObject::tr(
"BLOB" );
1145 return v.toString();
1148 if ( v.userType() == QMetaType::Type::QStringList || v.userType() == QMetaType::Type::QVariantList )
1154 const QVariantList list = v.toList();
1155 for (
const QVariant &var : list )
1157 if ( !result.isEmpty() )
1159 result.append(
';' );
1161 result.append( _displayString( var, precision ) );
1167 return _displayString( v, precision );
1183 if ( sSize != ddSize )
1186 return baseLegendSymbolItems();
1203 lst += baseLegendSymbolItems();
1208 return baseLegendSymbolItems();
1213 const QVariant value = valueForFeature( feature, context );
1218 if ( cat.value().userType() == QMetaType::Type::QVariantList )
1220 const QVariantList list = cat.value().toList();
1221 for (
const QVariant &v : list )
1240 match = value == cat.value();
1247 return QSet< QString >() << cat.uuid();
1249 return QSet< QString >();
1253 return QSet< QString >();
1276 const bool isNumeric = layer && fieldIndex >= 0 ? layer->
fields().
at( fieldIndex ).
isNumeric() :
false;
1277 const QMetaType::Type fieldType = layer && fieldIndex >= 0 ? layer->
fields().
at( fieldIndex ).
type() : QMetaType::Type::UnknownType;
1282 if ( cat.
value().userType() == QMetaType::Type::QVariantList )
1284 const QVariantList list = cat.
value().toList();
1286 parts.reserve( list.size() );
1287 for (
const QVariant &v : list )
1292 return QStringLiteral(
"%1 IN (%2)" ).arg( attributeComponent, parts.join( QLatin1String(
", " ) ) );
1297 QVariant value = cat.
value();
1298 if ( isNumeric && value.toString().isEmpty() )
1304 return QStringLiteral(
"%1 IS NULL" ).arg( attributeComponent );
1305 else if ( fieldType == QMetaType::Type::UnknownType )
1358 double value = count / num;
1370 symbol->
setColor( cat.symbol()->color() );
1386 if ( category.uuid() == key )
1388 return category.renderState();
1428 std::unique_ptr< QgsCategorizedSymbolRenderer > r;
1429 if ( renderer->
type() == QLatin1String(
"categorizedSymbol" ) )
1433 else if ( renderer->
type() == QLatin1String(
"graduatedSymbol" ) )
1436 if ( graduatedSymbolRenderer )
1438 r = std::make_unique<QgsCategorizedSymbolRenderer>( QString(),
QgsCategoryList() );
1445 r->setClassAttribute( graduatedSymbolRenderer->
classAttribute() );
1448 else if ( renderer->
type() == QLatin1String(
"RuleRenderer" ) )
1451 if ( ruleBasedSymbolRenderer )
1453 r = std::make_unique<QgsCategorizedSymbolRenderer>( QString(),
QgsCategoryList() );
1455 const QList< QgsRuleBasedRenderer::Rule * > rules =
const_cast< QgsRuleBasedRenderer *
>( ruleBasedSymbolRenderer )->rootRule()->children();
1456 bool canConvert =
true;
1458 bool isFirst =
true;
1465 if ( rule->isElse() || rule->minimumScale() != 0 || rule->maximumScale() != 0 || !rule->symbol() || !rule->children().isEmpty() )
1483 const QString left = binOp->opLeft()->dump();
1484 if ( !isFirst && left != attribute )
1499 cat.
setSymbol( rule->symbol()->clone() );
1500 cat.
setLabel( rule->label().isEmpty() ? literal->
value().toString() : rule->label() );
1526 r = std::make_unique< QgsCategorizedSymbolRenderer >( attribute,
categories );
1534 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
1537 if ( pointDistanceRenderer )
1540 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
1543 if ( invertedPolygonRenderer )
1546 else if ( renderer->
type() == QLatin1String(
"embeddedSymbol" ) && layer )
1561 r = std::make_unique<QgsCategorizedSymbolRenderer>( QStringLiteral(
"$id" ),
categories );
1569 r = std::make_unique< QgsCategorizedSymbolRenderer >( QString(),
QgsCategoryList() );
1577 r->setSourceSymbol( newSymbol );
1603 const QSet< QString > allSymbolNames( unmatchedSymbols.begin(), unmatchedSymbols.end() );
1605 const thread_local QRegularExpression tolerantMatchRe( QStringLiteral(
"[^\\w\\d ]" ), QRegularExpression::UseUnicodePropertiesOption );
1607 for (
int catIdx = 0; catIdx <
mCategories.count(); ++catIdx )
1609 const QVariant value =
mCategories.at( catIdx ).value();
1610 const QString val = value.toString().trimmed();
1611 std::unique_ptr< QgsSymbol > symbol( style->
symbol( val ) );
1613 if ( symbol && symbol->type() ==
type )
1616 unmatchedSymbols.removeAll( val );
1621 if ( !caseSensitive || useTolerantMatch )
1623 QString testVal = val;
1624 if ( useTolerantMatch )
1625 testVal.replace( tolerantMatchRe, QString() );
1627 bool foundMatch =
false;
1628 for (
const QString &name : allSymbolNames )
1630 QString testName = name.trimmed();
1631 if ( useTolerantMatch )
1632 testName.replace( tolerantMatchRe, QString() );
1634 if ( testName == testVal || ( !caseSensitive && testName.trimmed().compare( testVal, Qt::CaseInsensitive ) == 0 ) )
1637 std::unique_ptr< QgsSymbol > symbol( style->
symbol( name ) );
1638 if ( symbol && symbol->type() ==
type )
1641 unmatchedSymbols.removeAll( name );
1652 unmatchedCategories << value;
1661 QVariantList vals = values;
1665 if ( layer && !attributeName.isNull() )
1668 for (
const QVariant &value : vals )
1674 const int fieldIdx = fields.
lookupField( attributeName );
1676 if ( fieldIdx != -1 )
1678 const QgsField field = fields.
at( fieldIdx );
1681 categoryName = formatter->
representValue( layer, fieldIdx, setup.
config(), QVariant(), value );
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
@ EmbeddedSymbols
Retrieve any embedded feature symbology.
QFlags< FeatureRendererFlag > FeatureRendererFlags
Flags controlling behavior of vector feature renderers.
@ AffectsLabeling
If present, indicates that the renderer will participate in the map labeling problem.
@ AffectsLabeling
If present, indicates that the symbol will participate in the map labeling problem.
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QgsFieldFormatterRegistry * fieldFormatterRegistry()
Gets the registry of available field formatters.
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
Sorts the existing categories by their value.
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...
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
void updateSymbols(QgsSymbol *sym)
Update all the symbols but leave categories and colors.
bool updateCategoryRenderState(int catIndex, bool render)
Changes the render state for the category with the specified index.
void setSourceColorRamp(QgsColorRamp *ramp)
Sets the source color ramp.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
QgsSymbol * sourceSymbol()
Returns the renderer's source symbol, which is the base symbol used for the each categories' symbol b...
const QgsCategoryList & categories() const
Returns a list of all categories recognized by the renderer.
QString legendKeyToExpression(const QString &key, QgsVectorLayer *layer, bool &ok) const override
Attempts to convert the specified legend rule key to a QGIS expression matching the features displaye...
int matchToSymbols(QgsStyle *style, Qgis::SymbolType type, QVariantList &unmatchedCategories, QStringList &unmatchedSymbols, bool caseSensitive=true, bool useTolerantMatch=false)
Replaces category symbols with the symbols from a style that have a matching name and symbol type.
std::unique_ptr< QgsColorRamp > mSourceColorRamp
Q_DECL_DEPRECATED QgsSymbol * symbolForValue(const QVariant &value) const
Returns the matching symbol corresponding to an attribute value.
std::unique_ptr< QgsSymbol > mSourceSymbol
static QgsCategorizedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer, QgsVectorLayer *layer=nullptr)
Creates a new QgsCategorizedSymbolRenderer from an existing renderer.
void updateColorRamp(QgsColorRamp *ramp)
Update the color ramp used and all symbols colors.
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend when using data-defined size for marker symbols.
static QgsCategoryList createCategories(const QVariantList &values, const QgsSymbol *symbol, QgsVectorLayer *layer=nullptr, const QString &fieldName=QString())
Create categories for a list of values.
QHash< QString, QgsSymbol * > mSymbolHash
hashtable for faster access to symbols
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
void setSourceSymbol(QgsSymbol *sym)
Sets the source symbol for the renderer, which is the base symbol used for the each categories' symbo...
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
int categoryIndexForValue(const QVariant &val)
Returns the index for the category with the specified value (or -1 if not found).
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
Creates a categorized renderer from an XML element.
bool updateCategorySymbol(int catIndex, QgsSymbol *symbol)
Changes the symbol for the category with the specified index.
QgsCategoryList mCategories
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
std::unique_ptr< QgsExpression > mExpression
std::unique_ptr< QgsDataDefinedSizeLegend > mDataDefinedSizeLegend
bool legendSymbolItemChecked(const QString &key) override
Returns true if the legend symbology item with the specified key is checked.
bool legendSymbolItemsCheckable() const override
Returns true if symbology items in legend are checkable.
void addCategory(const QgsRendererCategory &category)
Adds a new category to the renderer.
QgsCategorizedSymbolRenderer(const QString &attrName=QString(), const QgsCategoryList &categories=QgsCategoryList())
Constructor for QgsCategorizedSymbolRenderer.
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
Sorts the existing categories by their label.
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
int mAttrNum
attribute index (derived from attribute name in startRender)
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
void moveCategory(int from, int to)
Moves an existing category at index position from to index position to.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
Stores renderer properties to an XML element.
bool deleteCategory(int catIndex)
Deletes the category with the specified index from the renderer.
Qgis::FeatureRendererFlags flags() const override
Returns flags associated with the renderer.
Q_DECL_DEPRECATED QgsSymbol * skipRender()
void checkLegendSymbolItem(const QString &key, bool state=true) override
Sets whether the legend symbology item with the specified ley should be checked.
QString dump() const override
Returns debug information about this renderer.
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
QgsColorRamp * sourceColorRamp()
Returns the source color ramp, from which each categories' color is derived.
bool updateCategoryValue(int catIndex, const QVariant &value)
Changes the value for the category with the specified index.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.1 specs.
QgsCategorizedSymbolRenderer * clone() const override
Create a deep copy of this renderer.
void deleteAllCategories()
Deletes all existing categories from the renderer.
void setDataDefinedSizeLegend(QgsDataDefinedSizeLegend *settings)
Configures appearance of legend when renderer is configured to use data-defined size for marker symbo...
bool updateCategoryLabel(int catIndex, const QString &label)
Changes the label for the category with the specified index.
static QString displayString(const QVariant &value, int precision=-1)
Returns a localized representation of value with the given precision, if precision is -1 then precisi...
~QgsCategorizedSymbolRenderer() override
int categoryIndexForLabel(const QString &val)
Returns the index of the category with the specified label (or -1 if the label was not found,...
Abstract base class for color ramps.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend.
static QgsDataDefinedSizeLegend * readXml(const QDomElement &elem, const QgsReadWriteContext &context) SIP_FACTORY
Creates instance from given element and returns it (caller takes ownership). Returns nullptr on error...
void updateFromSymbolAndProperty(const QgsMarkerSymbol *symbol, const QgsProperty &ddSize)
Updates the list of classes, source symbol and title label from given symbol and property.
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
A vector feature renderer which uses embedded feature symbology to render per-feature symbols.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
A binary expression operator, which operates on two values.
An expression node for literal values.
QVariant value() const
The value of the literal.
Handles parsing and evaluation of expressions (formerly called "search strings").
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required.
static QString quoteFieldExpression(const QString &expression, const QgsVectorLayer *layer)
Validate if the expression is a field in the layer and ensure it is quoted.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
bool isField() const
Checks whether an expression consists only of a single field reference.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes).
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
QgsFeatureRenderer(const QString &type)
virtual void stopRender(QgsRenderContext &context)
Must be called when a render cycle has finished, to allow the renderer to clean up.
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
static void convertSymbolRotation(QgsSymbol *symbol, const QString &field)
Converts old rotation expressions to symbol level data defined angles.
void saveRendererData(QDomDocument &doc, QDomElement &element, const QgsReadWriteContext &context)
Saves generic renderer data into the specified element.
virtual const QgsFeatureRenderer * embeddedRenderer() const
Returns the current embedded renderer (subrenderer) for this feature renderer.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
static void convertSymbolSizeScale(QgsSymbol *symbol, Qgis::ScaleMethod method, const QString &field)
Converts old sizeScale expressions to symbol level data defined sizes.
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
const QgsSymbol * embeddedSymbol() const
Returns the feature's embedded symbology, or nullptr if the feature has no embedded symbol.
Encapsulate a field in an attribute table or data source.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Q_INVOKABLE int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
A vector feature renderer which uses numeric attributes to classify features into different ranges.
QgsSymbol * sourceSymbol()
Returns the renderer's source symbol, which is the base symbol used for the each classes' symbol befo...
QgsColorRamp * sourceColorRamp()
Returns the source color ramp, from which each classes' color is derived.
QString classAttribute() const
Returns the attribute name (or expression) used for the classification.
A polygon-only feature renderer used to display features inverted.
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
A store for object properties.
bool isActive() const
Returns whether the property is currently active.
A color ramp consisting of random colors, constrained within component ranges.
virtual void setTotalColorCount(int colorCount)
Sets the desired total number of unique colors for the resultant ramp.
A container for the context for various read/write operations on objects.
Contains information about the context of a rendering operation.
double rendererScale() const
Returns the renderer map scale.
QgsExpressionContext & expressionContext()
Gets the expression context.
Represents an individual category (class) from a QgsCategorizedSymbolRenderer.
void setRenderState(bool render)
Sets whether the category is currently enabled and should be rendered.
std::unique_ptr< QgsSymbol > mSymbol
QgsSymbol * symbol() const
Returns the symbol which will be used to render this category.
void setSymbol(QgsSymbol *s)
Sets the symbol which will be used to render this category.
QString uuid() const
Returns the unique identifier for this category.
QgsRendererCategory()=default
bool renderState() const
Returns true if the category is currently enabled and should be rendered.
QString dump() const
Returns a string representing the categories settings, used for debugging purposes only.
void setLabel(const QString &label)
Sets the label for this category, which is used to represent the category within legends and the laye...
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, QVariantMap props) const
Converts the category to a matching SLD rule, within the specified DOM document and element.
void setValue(const QVariant &value)
Sets the value corresponding to this category.
QVariant value() const
Returns the value corresponding to this category.
QString label() const
Returns the label for this category, which is used to represent the category within legends and the l...
QgsRendererCategory & operator=(QgsRendererCategory cat)
Represents an individual rule for a rule-based renderer.
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
QVariantMap extraProperties() const
Returns the open ended set of properties that can drive/inform the SLD encoding.
A color ramp entity for QgsStyle databases.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
A symbol entity for QgsStyle databases.
A database of saved style entities, including symbols, color ramps, text formats and others.
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
QStringList symbolNames() const
Returns a list of names of symbols.
static void sortVariantList(QList< QVariant > &list, Qt::SortOrder order)
Sorts the passed list in requested order.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QVariantMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static std::unique_ptr< QgsColorRamp > loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static Q_DECL_DEPRECATED bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates an OGC function element.
static bool hasSldSymbolizer(const QDomElement &element)
Returns true if a DOM element contains an SLD Symbolizer element.
static void clearSymbolLayerMasks(QgsSymbol *symbol)
Remove recursively masks from all symbol symbol layers.
static Qgis::ScaleMethod decodeScaleMethod(const QString &str)
Decodes a symbol scale method from a string.
static QDomElement saveColorRamp(const QString &name, const QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static void clearSymbolMap(QgsSymbolMap &symbols)
static void resetSymbolLayerIds(QgsSymbol *symbol)
Regenerate recursively unique id from all symbol symbol layers.
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 ...
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.
Abstract base class for all rendered symbols.
void setColor(const QColor &color) const
Sets the color for the symbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
Represents a vector layer which manages a vector based dataset.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
bool labelGreaterThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
bool valueLessThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
bool valueGreaterThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
bool labelLessThan(const QgsRendererCategory &c1, const QgsRendererCategory &c2)
QList< QgsRendererCategory > QgsCategoryList
QList< QgsLegendSymbolItem > QgsLegendSymbolList
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
#define RENDERER_TAG_NAME
QMap< QString, QgsSymbol * > QgsSymbolMap
QList< QgsSymbol * > QgsSymbolList
Contains information relating to the style entity currently being visited.