38 #include <QDomDocument> 39 #include <QDomElement> 46 : mLowerValue( lowerValue )
47 , mUpperValue( upperValue )
143 if ( !
mSymbol || props.value( QStringLiteral(
"attribute" ), QString() ).isEmpty() )
146 QString attrName = props[ QStringLiteral(
"attribute" )];
148 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
149 element.appendChild( ruleElem );
151 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
152 nameElem.appendChild( doc.createTextNode(
mLabel ) );
153 ruleElem.appendChild( nameElem );
155 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
156 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
158 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
159 descrElem.appendChild( titleElem );
160 ruleElem.appendChild( descrElem );
163 QString filterFunc = QStringLiteral(
"\"%1\" %2 %3 AND \"%1\" <= %4" )
164 .arg( attrName.replace(
'\"', QLatin1String(
"\"\"" ) ),
165 firstRange ? QStringLiteral(
">=" ) : QStringLiteral(
">" ),
170 mSymbol->toSld( doc, ruleElem, props );
179 : mFormat( QStringLiteral(
" %1 - %2 " ) )
180 , mReTrailingZeroes(
"[.,]?0*$" )
181 , mReNegativeZero(
"^\\-0(?:[.,]0*)?$" )
205 return !( *
this == other );
215 while ( precision < 0 )
232 QString valueStr = QLocale().toString( value,
'f',
mPrecision );
236 valueStr = valueStr.mid( 1 );
241 QString valueStr = QLocale().toString( value *
mNumberScale,
'f', 0 );
242 if ( valueStr == QLatin1String(
"-0" ) )
244 if ( valueStr != QLatin1String(
"0" ) )
256 return legend.replace( QLatin1String(
"%1" ), lowerStr ).replace( QLatin1String(
"%2" ), upperStr );
261 mFormat = element.attribute( QStringLiteral(
"format" ),
262 element.attribute( QStringLiteral(
"prefix" ), QStringLiteral(
" " ) ) +
"%1" +
263 element.attribute( QStringLiteral(
"separator" ), QStringLiteral(
" - " ) ) +
"%2" +
264 element.attribute( QStringLiteral(
"suffix" ), QStringLiteral(
" " ) )
266 setPrecision( element.attribute( QStringLiteral(
"decimalplaces" ), QStringLiteral(
"4" ) ).toInt() );
267 mTrimTrailingZeroes = element.attribute( QStringLiteral(
"trimtrailingzeroes" ), QStringLiteral(
"false" ) ) == QLatin1String(
"true" );
272 element.setAttribute( QStringLiteral(
"format" ),
mFormat );
273 element.setAttribute( QStringLiteral(
"decimalplaces" ),
mPrecision );
274 element.setAttribute( QStringLiteral(
"trimtrailingzeroes" ),
mTrimTrailingZeroes ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
281 , mAttrName( attrName )
323 return QString::number( i );
342 if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
356 QVariant value = valueForFeature( feature, context );
359 if ( value.isNull() )
405 QSet<QString> attributes;
417 QgsRangeList::const_iterator range_it =
mRanges.constBegin();
418 for ( ; range_it !=
mRanges.constEnd(); ++range_it )
444 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
446 mRanges[rangeIndex].setSymbol( symbol );
452 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
454 mRanges[rangeIndex].setLabel( label );
460 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
471 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
482 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
484 mRanges[rangeIndex].setRenderState( value );
490 QString s = QStringLiteral(
"GRADUATED: attr %1\n" ).arg(
mAttrName );
491 for (
int i = 0; i <
mRanges.count(); i++ )
522 newProps[ QStringLiteral(
"attribute" )] =
mAttrName;
527 for ( QgsRangeList::const_iterator it =
mRanges.constBegin(); it !=
mRanges.constEnd(); ++it )
529 it->toSld( doc, element, newProps, first );
538 lst.reserve(
mRanges.count() );
541 lst.append( range.
symbol() );
553 if ( breaks.size() > 1 )
555 std::sort( breaks.begin(), breaks.end() );
557 double distBelowSymmetricValue = std::fabs( breaks[0] - symmetryPoint );
558 double distAboveSymmetricValue = std::fabs( breaks[ breaks.size() - 2 ] -
symmetryPoint ) ;
559 double absMin = std::min( distAboveSymmetricValue, distBelowSymmetricValue );
562 for (
int i = 0; i <= breaks.size() - 2; ++i )
565 if ( std::fabs( breaks.at( i ) -
symmetryPoint ) >= ( absMin - std::fabs( breaks[0] - breaks[1] ) / 100. ) )
567 breaks.removeAt( i );
574 breaks.removeAt( breaks.indexOf( symmetryPoint ) );
583 QList<double> breaks;
584 if ( !useSymmetricMode )
586 double step = ( maximum - minimum ) / classes;
588 double value = minimum;
589 breaks.reserve( classes );
590 for (
int i = 0; i < classes; i++ )
593 breaks.append( value );
597 breaks[classes - 1] = maximum;
599 else if ( useSymmetricMode )
601 double distBelowSymmetricValue = std::abs( minimum - symmetryPoint );
602 double distAboveSymmetricValue = std::abs( maximum - symmetryPoint ) ;
606 if ( classes % 2 == 0 )
611 if ( classes % 2 == 1 )
614 double step = 2 * std::min( distBelowSymmetricValue, distAboveSymmetricValue ) / classes;
616 breaks.reserve( classes );
617 double value = ( distBelowSymmetricValue < distAboveSymmetricValue ) ? minimum : maximum - classes * step;
619 for (
int i = 0; i < classes; i++ )
622 breaks.append( value );
624 breaks[classes - 1] = maximum;
629 static QList<double> _calcQuantileBreaks( QList<double> values,
int classes )
640 std::sort( values.begin(), values.end() );
642 QList<double> breaks;
645 if ( values.isEmpty() )
648 int n = values.count();
649 double Xq = n > 0 ? values[0] : 0.0;
651 breaks.reserve( classes );
652 for (
int i = 1; i < classes; i++ )
656 double q = i /
static_cast< double >( classes );
657 double a = q * ( n - 1 );
658 int aa =
static_cast< int >( a );
661 Xq = ( 1 - r ) * values[aa] + r * values[aa + 1];
666 breaks.append( values[ n - 1 ] );
682 if ( values.isEmpty() )
683 return QList<double>();
687 int n = values.count();
688 double minimum = values[0];
689 double maximum = values[0];
691 for (
int i = 0; i < n; i++ )
694 minimum = std::min( values[i], minimum );
695 maximum = std::max( values[i], maximum );
697 mean = mean /
static_cast< double >( n );
700 for (
int i = 0; i < n; i++ )
702 sd = values[i] - mean;
705 stdDev = std::sqrt( stdDev / n );
713 for (
int i = 0; i < breaks.count(); i++ )
715 labels.append( breaks[i] );
721 static QList<double> _calcJenksBreaks( QList<double> values,
int classes,
722 double minimum,
double maximum,
723 int maximumSize = 3000 )
735 if ( values.isEmpty() )
736 return QList<double>();
740 return QList<double>() << maximum;
743 if ( classes >= values.size() )
748 QVector<double> sample;
751 if ( values.size() > maximumSize )
757 sample.resize( std::max( maximumSize, values.size() / 10 ) );
759 QgsDebugMsg( QStringLiteral(
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ) );
760 QgsDebugMsg( QStringLiteral(
"values:%1" ).arg( values.size() ) );
762 sample[ 0 ] = minimum;
763 sample[ 1 ] = maximum;
764 for (
int i = 2; i < sample.size(); i++ )
768 int j = std::floor( r / RAND_MAX * ( values.size() - 1 ) );
769 sample[ i ] = values[ j ];
774 sample = values.toVector();
777 int n = sample.size();
780 std::sort( sample.begin(), sample.end() );
782 QVector< QVector<int> > matrixOne( n + 1 );
783 QVector< QVector<double> > matrixTwo( n + 1 );
785 for (
int i = 0; i <= n; i++ )
787 matrixOne[i].resize( classes + 1 );
788 matrixTwo[i].resize( classes + 1 );
791 for (
int i = 1; i <= classes; i++ )
795 matrixTwo[0][i] = 0.0;
796 for (
int j = 2; j <= n; j++ )
798 matrixTwo[j][i] = std::numeric_limits<double>::max();
802 for (
int l = 2; l <= n; l++ )
810 for (
int m = 1; m <= l; m++ )
814 double val = sample[ i3 - 1 ];
820 v = s2 - ( s1 * s1 ) / static_cast< double >( w );
824 for (
int j = 2; j <= classes; j++ )
826 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
828 matrixOne[l][j] = i4;
829 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
838 QVector<double> breaks( classes );
839 breaks[classes - 1] = sample[n - 1];
841 for (
int j = classes, k = n; j >= 2; j-- )
843 int id = matrixOne[k][j] - 1;
844 breaks[j - 2] = sample[id];
845 k = matrixOne[k][j] - 1;
848 return breaks.toList();
851 static QStringList _breaksAsStrings(
const QList<double> &breaks )
853 QStringList breaksAsStrings;
854 for (
int i = 0; i < breaks.count() - 1; i++ )
856 breaksAsStrings << QString::number( breaks.at( i ),
'f', 2 );
858 return breaksAsStrings;
863 const QString &attrName,
885 r->
updateClasses( vlayer, mode, classes, useSymmetricMode, symmetryPoint, astride );
906 QList<double> values;
907 bool valuesLoaded =
false;
917 if ( !ok || values.isEmpty() )
920 auto result = std::minmax_element( values.begin(), values.end() );
921 minimum = *result.first;
922 maximum = *result.second;
931 QgsDebugMsg( QStringLiteral(
"min %1 // max %2" ).arg( minimum ).arg( maximum ) );
932 QList<double> breaks;
933 QList<double> labels;
948 if ( useSymmetricMode )
964 breaks = _calcQuantileBreaks( values, nclasses );
965 else if ( mode ==
Jenks )
966 breaks = _calcJenksBreaks( values, nclasses, minimum, maximum );
967 else if ( mode ==
StdDev )
968 breaks = _calcStdDevBreaks( values, nclasses, labels,
mUseSymmetricMode, symmetryPoint, astride );
977 double lower, upper = minimum;
983 for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
993 label =
"< " + QString::number( labels[i],
'f', 2 ) +
" Std Dev";
995 else if ( i == labels.count() - 1 )
997 label =
">= " + QString::number( labels[i - 1],
'f', 2 ) +
" Std Dev";
1001 label = QString::number( labels[i - 1],
'f', 2 ) +
" Std Dev" +
" - " + QString::number( labels[i],
'f', 2 ) +
" Std Dev";
1017 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
1018 if ( symbolsElem.isNull() )
1021 QDomElement rangesElem = element.firstChildElement( QStringLiteral(
"ranges" ) );
1022 if ( rangesElem.isNull() )
1028 QDomElement rangeElem = rangesElem.firstChildElement();
1029 while ( !rangeElem.isNull() )
1031 if ( rangeElem.tagName() == QLatin1String(
"range" ) )
1033 double lowerValue = rangeElem.attribute( QStringLiteral(
"lower" ) ).toDouble();
1034 double upperValue = rangeElem.attribute( QStringLiteral(
"upper" ) ).toDouble();
1035 QString symbolName = rangeElem.attribute( QStringLiteral(
"symbol" ) );
1036 QString label = rangeElem.attribute( QStringLiteral(
"label" ) );
1037 bool render = rangeElem.attribute( QStringLiteral(
"render" ), QStringLiteral(
"true" ) ) != QLatin1String(
"false" );
1038 if ( symbolMap.contains( symbolName ) )
1040 QgsSymbol *symbol = symbolMap.take( symbolName );
1041 ranges.append(
QgsRendererRange( lowerValue, upperValue, symbol, label, render ) );
1044 rangeElem = rangeElem.nextSiblingElement();
1047 QString attrName = element.attribute( QStringLiteral(
"attr" ) );
1051 QString attrMethod = element.attribute( QStringLiteral(
"graduatedMethod" ) );
1052 if ( !attrMethod.isEmpty() )
1065 QDomElement sourceSymbolElem = element.firstChildElement( QStringLiteral(
"source-symbol" ) );
1066 if ( !sourceSymbolElem.isNull() )
1069 if ( sourceSymbolMap.contains( QStringLiteral(
"0" ) ) )
1077 QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
1078 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
1084 QDomElement modeElem = element.firstChildElement( QStringLiteral(
"mode" ) );
1085 if ( !modeElem.isNull() )
1087 QString modeString = modeElem.attribute( QStringLiteral(
"name" ) );
1088 if ( modeString == QLatin1String(
"equal" ) )
1090 else if ( modeString == QLatin1String(
"quantile" ) )
1092 else if ( modeString == QLatin1String(
"jenks" ) )
1094 else if ( modeString == QLatin1String(
"stddev" ) )
1096 else if ( modeString == QLatin1String(
"pretty" ) )
1101 QDomElement symmetricModeElem = element.firstChildElement( QStringLiteral(
"symmetricMode" ) );
1102 if ( !symmetricModeElem.isNull() )
1104 QString symmetricEnabled = symmetricModeElem.attribute( QStringLiteral(
"enabled" ) );
1107 QString symmetricPointString = symmetricModeElem.attribute( QStringLiteral(
"symmetryPoint" ) );
1109 QString breaksForPretty = symmetricModeElem.attribute( QStringLiteral(
"valueForCboPrettyBreaks" ) );
1112 QString astrideEnabled = symmetricModeElem.attribute( QStringLiteral(
"astride" ) );
1115 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"rotation" ) );
1116 if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
1127 QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral(
"sizescale" ) );
1128 if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
1134 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
1140 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
1144 QDomElement labelFormatElem = element.firstChildElement( QStringLiteral(
"labelformat" ) );
1145 if ( ! labelFormatElem.isNull() )
1152 QDomElement ddsLegendSizeElem = element.firstChildElement( QStringLiteral(
"data-defined-size-legend" ) );
1153 if ( !ddsLegendSizeElem.isNull() )
1164 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"graduatedSymbol" ) );
1165 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1166 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1167 rendererElem.setAttribute( QStringLiteral(
"attr" ),
mAttrName );
1173 QDomElement rangesElem = doc.createElement( QStringLiteral(
"ranges" ) );
1174 QgsRangeList::const_iterator it =
mRanges.constBegin();
1175 for ( ; it !=
mRanges.constEnd(); ++it )
1178 QString symbolName = QString::number( i );
1179 symbols.insert( symbolName, range.
symbol() );
1181 QDomElement rangeElem = doc.createElement( QStringLiteral(
"range" ) );
1182 rangeElem.setAttribute( QStringLiteral(
"lower" ), QString::number( range.
lowerValue(),
'f', 15 ) );
1183 rangeElem.setAttribute( QStringLiteral(
"upper" ), QString::number( range.
upperValue(),
'f', 15 ) );
1184 rangeElem.setAttribute( QStringLiteral(
"symbol" ), symbolName );
1185 rangeElem.setAttribute( QStringLiteral(
"label" ), range.
label() );
1186 rangeElem.setAttribute( QStringLiteral(
"render" ), range.
renderState() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1187 rangesElem.appendChild( rangeElem );
1191 rendererElem.appendChild( rangesElem );
1195 rendererElem.appendChild( symbolsElem );
1201 sourceSymbols.insert( QStringLiteral(
"0" ),
mSourceSymbol.get() );
1203 rendererElem.appendChild( sourceSymbolElem );
1210 rendererElem.appendChild( colorRampElem );
1218 modeString = QStringLiteral(
"equal" );
1221 modeString = QStringLiteral(
"quantile" );
1224 modeString = QStringLiteral(
"jenks" );
1227 modeString = QStringLiteral(
"stddev" );
1230 modeString = QStringLiteral(
"pretty" );
1235 if ( !modeString.isEmpty() )
1237 QDomElement modeElem = doc.createElement( QStringLiteral(
"mode" ) );
1238 modeElem.setAttribute( QStringLiteral(
"name" ), modeString );
1239 rendererElem.appendChild( modeElem );
1243 QDomElement symmetricModeElem = doc.createElement( QStringLiteral(
"symmetricMode" ) );
1244 symmetricModeElem.setAttribute( QStringLiteral(
"enabled" ),
mUseSymmetricMode ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1245 symmetricModeElem.setAttribute( QStringLiteral(
"symmetryPoint" ),
mSymmetryPoint );
1246 symmetricModeElem.setAttribute( QStringLiteral(
"astride" ),
mAstride ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1253 breaks.append(
'/' );
1257 symmetricModeElem.setAttribute( QStringLiteral(
"valueForCboPrettyBreaks" ), breaks );
1260 rendererElem.appendChild( symmetricModeElem );
1262 QDomElement rotationElem = doc.createElement( QStringLiteral(
"rotation" ) );
1263 rendererElem.appendChild( rotationElem );
1265 QDomElement sizeScaleElem = doc.createElement( QStringLiteral(
"sizescale" ) );
1266 rendererElem.appendChild( sizeScaleElem );
1268 QDomElement labelFormatElem = doc.createElement( QStringLiteral(
"labelformat" ) );
1270 rendererElem.appendChild( labelFormatElem );
1277 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
1279 rendererElem.appendChild( orderBy );
1281 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1285 QDomElement ddsLegendElem = doc.createElement( QStringLiteral(
"data-defined-size-legend" ) );
1287 rendererElem.appendChild( ddsLegendElem );
1290 return rendererElem;
1316 if ( sSize && sSize != ddSize )
1319 return baseLegendSymbolItems();
1336 lst += baseLegendSymbolItems();
1341 return baseLegendSymbolItems();
1346 QVariant value = valueForFeature( feature, context );
1349 if ( value.isNull() )
1350 return QSet< QString >();
1354 if ( !key.isNull() )
1355 return QSet< QString >() << key;
1357 return QSet< QString >();
1384 double min = std::numeric_limits<double>::max();
1385 for (
int i = 0; i <
mRanges.count(); i++ )
1389 sz = static_cast< QgsMarkerSymbol * >(
mRanges[i].symbol() )->size();
1391 sz = static_cast< QgsLineSymbol * >(
mRanges[i].symbol() )->width();
1392 min = std::min( sz, min );
1399 double max = std::numeric_limits<double>::min();
1400 for (
int i = 0; i <
mRanges.count(); i++ )
1404 sz = static_cast< QgsMarkerSymbol * >(
mRanges[i].symbol() )->size();
1406 sz = static_cast< QgsLineSymbol * >(
mRanges[i].symbol() )->width();
1407 max = std::max( sz, max );
1414 for (
int i = 0; i <
mRanges.count(); i++ )
1416 std::unique_ptr<QgsSymbol> symbol(
mRanges.at( i ).symbol() ?
mRanges.at( i ).symbol()->clone() : nullptr );
1417 const double size =
mRanges.count() > 1
1418 ? minSize + i * ( maxSize - minSize ) / (
mRanges.count() - 1 )
1419 : .5 * ( maxSize + minSize );
1421 static_cast< QgsMarkerSymbol * >( symbol.get() )->setSize( size );
1423 static_cast< QgsLineSymbol * >( symbol.get() )->setWidth( size );
1444 colorValue = (
mRanges.count() > 1 ?
static_cast< double >( i ) / (
mRanges.count() - 1 ) : 0 );
1462 std::unique_ptr<QgsSymbol> symbol( sym->
clone() );
1470 static_cast<QgsMarkerSymbol *>( symbol.get() )->setSize(
1471 static_cast<QgsMarkerSymbol *>( range.
symbol() )->size() );
1473 static_cast<QgsLineSymbol *>( symbol.get() )->setWidth(
1474 static_cast<QgsLineSymbol *>( range.
symbol() )->width() );
1490 int index = key.toInt( &ok );
1491 if ( ok && index >= 0 && index <
mRanges.size() )
1492 return mRanges.at( index ).renderState();
1500 int index = key.toInt( &ok );
1508 int index = key.toInt( &ok );
1518 QString label = QStringLiteral(
"0.0 - 0.0" );
1531 QMutableListIterator< QgsRendererRange > it(
mRanges );
1532 while ( it.hasNext() )
1547 it.setValue( range );
1549 it.insert( newRange );
1554 if ( updateSymbols )
1587 for ( QgsRangeList::iterator it =
mRanges.begin(); it !=
mRanges.end(); ++it )
1599 double minClassRange = 0.0;
1605 if ( minClassRange == 0.0 || range < minClassRange )
1606 minClassRange = range;
1608 if ( minClassRange <= 0.0 )
1615 double nextDpMinRange = 0.0000000099;
1616 while ( ndp > 0 && nextDpMinRange < minClassRange )
1619 nextDpMinRange *= 10.0;
1627 if ( from < 0 || from >=
mRanges.size() || to < 0 || to >=
mRanges.size() )
1644 if ( order == Qt::AscendingOrder )
1657 std::sort( sortedRanges.begin(), sortedRanges.end(),
valueLessThan );
1659 QgsRangeList::const_iterator it = sortedRanges.constBegin();
1660 if ( it == sortedRanges.constEnd() )
1663 if ( ( *it ).upperValue() < ( *it ).lowerValue() )
1666 double prevMax = ( *it ).upperValue();
1669 for ( ; it != sortedRanges.constEnd(); ++it )
1671 if ( ( *it ).upperValue() < ( *it ).lowerValue() )
1674 if ( ( *it ).lowerValue() < prevMax )
1677 prevMax = ( *it ).upperValue();
1685 std::sort( sortedRanges.begin(), sortedRanges.end(),
valueLessThan );
1687 QgsRangeList::const_iterator it = sortedRanges.constBegin();
1688 if ( it == sortedRanges.constEnd() )
1691 double prevMax = ( *it ).upperValue();
1694 for ( ; it != sortedRanges.constEnd(); ++it )
1699 prevMax = ( *it ).upperValue();
1706 return QString::localeAwareCompare( r1.
label(), r2.
label() ) < 0;
1716 if ( order == Qt::AscendingOrder )
1729 if ( renderer->
type() == QLatin1String(
"graduatedSymbol" ) )
1733 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
1736 if ( pointDistanceRenderer )
1739 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
1742 if ( invertedPolygonRenderer )
1754 if ( !symbols.isEmpty() )
1781 return "GraduatedColor";
1783 return "GraduatedSize";
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Class for parsing and evaluation of expressions (formerly called "search strings").
const QgsRendererRangeLabelFormat & labelFormat() const
Returns the label format used to generate default classification labels.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
static QgsGraduatedSymbolRenderer * convertFromRenderer(const QgsFeatureRenderer *renderer)
creates a QgsGraduatedSymbolRenderer from an existing renderer.
The class is used as a container of context for various read/write operations on other objects...
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
double rendererScale() const
Returns the renderer map scale.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
std::unique_ptr< QgsSymbol > mSourceSymbol
QList< QgsLegendSymbolItem > QgsLegendSymbolList
bool filterNeedsGeometry() const override
Returns true if this renderer requires the geometry to apply the filter.
QgsFeatureRequest::OrderBy mOrderBy
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
bool labelLessThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
static QgsFeatureRenderer * create(QDomElement &element, const QgsReadWriteContext &context)
create renderer from XML element
Abstract base class for all rendered symbols.
bool updateRangeUpperValue(int rangeIndex, double value)
QList< QgsRendererRange > QgsRangeList
bool rangesOverlap() const
Tests whether classes assigned to the renderer have ranges which overlap.
void setLabel(const QString &label)
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
void setSymmetryPoint(double symmetryPoint)
Set the pivot point.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
Abstract base class for color ramps.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
QStringList mListForCboPrettyBreaks
void addBreak(double breakValue, bool updateSymbols=true)
Add a breakpoint by splitting existing classes so that the specified value becomes a break between tw...
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
void setGraduatedMethod(GraduatedMethod method)
set the method used for graduation (either size or color)
void updateClasses(QgsVectorLayer *vlayer, Mode mode, int nclasses, bool useSymmetricMode=false, double symmetryPoint=0.0, bool astride=false)
Recalculate classes for a layer.
void startRender(QgsRenderContext &context, const QgsFields &fields) override
Must be called when a new render cycle is started.
QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Container of fields for a vector layer.
void setRenderState(bool render)
#define RENDERER_TAG_NAME
void setUsingSymbolLevels(bool usingSymbolLevels)
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
static void clearSymbolMap(QgsSymbolMap &symbols)
QgsRendererRange & operator=(QgsRendererRange range)
void setAstride(bool astride)
Set if we want a central class astride the pivot value.
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...
void setSymbolSizes(double minSize, double maxSize)
set varying symbol size for classes
bool operator<(const QgsRendererRange &other) const
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
static const char * graduatedMethodStr(GraduatedMethod method)
std::unique_ptr< QgsExpression > mExpression
void setUpperValue(double upperValue)
void addClass(QgsSymbol *symbol)
QMap< QString, QString > QgsStringMap
QgsSymbol * symbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
To be overridden.
A marker symbol type, for rendering Point and MultiPoint geometries.
void startRender(QgsRenderContext &context, const QgsFields &fields=QgsFields())
Begins the rendering process for the symbol.
void setLegendSymbolItem(const QString &key, QgsSymbol *symbol) override
Sets the symbol to be used for a legend symbol item.
bool rangesHaveGaps() const
Tests whether classes assigned to the renderer have gaps between the ranges.
void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
void setUseSymmetricMode(bool useSymmetricMode)
Set if we want to classify symmetric around a given value.
double lowerValue() const
QSet< QString > legendKeysForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns legend keys matching a specified feature.
bool updateRangeSymbol(int rangeIndex, QgsSymbol *symbol)
GraduatedMethod mGraduatedMethod
QList< QgsSymbol * > QgsSymbolList
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
void updateColorRamp(QgsColorRamp *ramp=nullptr)
Update the color ramp used.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
void setListForCboPrettyBreaks(const QStringList &listForCboPrettyBreaks)
Set the list of breaks used in the prettybreaks mode, which is needed to recover this list in saved c...
QgsInvertedPolygonRenderer is a polygon-only feature renderer used to display features inverted...
bool updateRangeLowerValue(int rangeIndex, double value)
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.
void setLowerValue(double lowerValue)
bool labelGreaterThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsColorRamp * sourceColorRamp()
Returns the source color ramp, from which each classes' color is derived.
bool astride() const
Returns if we want to have a central class astride the pivot value.
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.
QColor color() const
Returns the symbol's color.
static void convertSymbolSizeScale(QgsSymbol *symbol, QgsSymbol::ScaleMethod method, const QString &field)
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
QgsSymbol * symbol() const
QVariant minimumValue(int index) const FINAL
Returns the minimum value for an attribute column or an invalid variant in case of error...
static QgsGraduatedSymbolRenderer * createRenderer(QgsVectorLayer *vlayer, const QString &attrName, int classes, Mode mode, QgsSymbol *symbol, QgsColorRamp *ramp, const QgsRendererRangeLabelFormat &legendFormat=QgsRendererRangeLabelFormat(), bool useSymmetricMode=false, double symmetryPoint=0.0, QStringList listForCboPrettyBreaks=QStringList(), bool astride=false)
Creates a new graduated renderer.
A store for object properties.
double symmetryPoint() const
Returns the pivot value for symmetric classification.
bool valueLessThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
~QgsGraduatedSymbolRenderer() override
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 swap(QgsRendererRange &other)
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend when using data-defined size for marker symbols...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns a list of attributes required by this renderer.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
void moveClass(int from, int to)
Moves the category at index position from to index position to.
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
QgsExpressionContext & expressionContext()
Gets the expression context.
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
QgsRendererRange()=default
Constructor for QgsRendererRange.
void calculateLabelPrecision(bool updateRanges=true)
Reset the label decimal places to a numberbased on the minimum class interval.
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
static void convertSymbolRotation(QgsSymbol *symbol, const QString &field)
bool legendSymbolItemsCheckable() const override
items of symbology items in legend should be checkable
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
double minSymbolSize() const
Returns the min symbol size when graduated by size.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
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.
QgsRendererRangeLabelFormat mLabelFormat
bool usingSymbolLevels() const
QgsSymbolList symbols(QgsRenderContext &context) const override
Returns list of symbols used by the renderer.
QgsLegendSymbolList legendSymbolItems() const override
Returns a list of symbology items for the legend.
void sortByLabel(Qt::SortOrder order=Qt::AscendingOrder)
void setSymbol(QgsSymbol *s)
GraduatedMethod graduatedMethod() const
Returns the method used for graduation (either size or color)
QgsGraduatedSymbolRenderer(const QString &attrName=QString(), const QgsRangeList &ranges=QgsRangeList())
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
double maxSymbolSize() const
Returns the max symbol size when graduated by size.
bool prepare(const QgsExpressionContext *context)
Gets the expression ready for evaluation - find out column indexes.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
bool useSymmetricMode() const
Returns if we want to classify symmetric around a given value.
void setDataDefinedSizeLegend(QgsDataDefinedSizeLegend *settings)
Configures appearance of legend when renderer is configured to use data-defined size for marker symbo...
void CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
QString dump() const override
Returns debug information about this renderer.
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props, bool firstRange=false) const
Creates a DOM element representing the range in SLD format.
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
QgsGraduatedSymbolRenderer * clone() const override
Create a deep copy of this renderer.
double upperValue() const
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
std::unique_ptr< QgsSymbol > mSymbol
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
static QList< double > calcEqualIntervalBreaks(double minimum, double maximum, int classes, bool useSymmetricMode, double symmetryPoint, bool astride)
Compute the equal interval classification.
bool updateRangeRenderState(int rangeIndex, bool render)
bool valueGreaterThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
bool updateRangeLabel(int rangeIndex, const QString &label)
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
QDomElement save(QDomDocument &doc, const QgsReadWriteContext &context) override
store renderer info to XML element
static void makeBreaksSymmetric(QList< double > &breaks, double symmetryPoint, bool astride)
Remove the breaks that are above the existing opposite sign classes to keep colors symmetrically bala...
int mAttrNum
attribute index (derived from attribute name in startRender)
int ANALYSIS_EXPORT lower(int n, int i)
Lower function.
std::unique_ptr< QgsColorRamp > mSourceColorRamp
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
QString legendKeyForValue(double value) const
Returns the matching legend key for a value.
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error...
Represents a vector layer which manages a vector based data sets.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend...
QgsSymbol * symbolForValue(double value) const
Gets the symbol which is used to represent value.
std::unique_ptr< QgsDataDefinedSizeLegend > mDataDefinedSizeLegend
void stopRender(QgsRenderContext &context)
Ends the rendering process.
const QgsRangeList & ranges() const
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...
void setSourceColorRamp(QgsColorRamp *ramp)
Sets the source color ramp.
void updateSymbols(QgsSymbol *sym)
Update all the symbols but leave breaks and colors.
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
QgsSymbol * sourceSymbol()
Returns the renderer's source symbol, which is the base symbol used for the each classes' symbol befo...
void setSourceSymbol(QgsSymbol *sym)
Sets the source symbol for the renderer, which is the base symbol used for the each classes' symbol b...
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
void deleteClass(int idx)
bool isActive() const
Returns whether the property is currently active.
void setLabelFormat(const QgsRendererRangeLabelFormat &labelFormat, bool updateRanges=false)
Set the label format used to generate default classification labels.
void setColor(const QColor &color)
Sets the color for the symbol.
QStringList listForCboPrettyBreaks() const
Returns the list of breaks used in the prettybreaks mode.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.