37 #include <QDomDocument> 38 #include <QDomElement> 45 : mLowerValue( lowerValue )
46 , mUpperValue( upperValue )
142 if ( !
mSymbol || props.value( QStringLiteral(
"attribute" ), QString() ).isEmpty() )
145 QString attrName = props[ QStringLiteral(
"attribute" )];
147 QDomElement ruleElem = doc.createElement( QStringLiteral(
"se:Rule" ) );
148 element.appendChild( ruleElem );
150 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
151 nameElem.appendChild( doc.createTextNode(
mLabel ) );
152 ruleElem.appendChild( nameElem );
154 QDomElement descrElem = doc.createElement( QStringLiteral(
"se:Description" ) );
155 QDomElement titleElem = doc.createElement( QStringLiteral(
"se:Title" ) );
157 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
158 descrElem.appendChild( titleElem );
159 ruleElem.appendChild( descrElem );
162 QString filterFunc = QStringLiteral(
"\"%1\" %2 %3 AND \"%1\" <= %4" )
163 .arg( attrName.replace(
'\"', QLatin1String(
"\"\"" ) ),
164 firstRange ? QStringLiteral(
">=" ) : QStringLiteral(
">" ),
169 mSymbol->toSld( doc, ruleElem, props );
178 : mFormat( QStringLiteral(
"%1 - %2" ) )
179 , mReTrailingZeroes(
"[.,]?0*$" )
180 , mReNegativeZero(
"^\\-0(?:[.,]0*)?$" )
204 return !( *
this == other );
214 while ( precision < 0 )
231 QString valueStr = QLocale().toString( value,
'f',
mPrecision );
235 valueStr = valueStr.mid( 1 );
240 QString valueStr = QLocale().toString( value *
mNumberScale,
'f', 0 );
241 if ( valueStr == QLatin1String(
"-0" ) )
243 if ( valueStr != QLatin1String(
"0" ) )
255 return legend.replace( QLatin1String(
"%1" ), lowerStr ).replace( QLatin1String(
"%2" ), upperStr );
260 mFormat = element.attribute( QStringLiteral(
"format" ),
261 element.attribute( QStringLiteral(
"prefix" ), QStringLiteral(
" " ) ) +
"%1" +
262 element.attribute( QStringLiteral(
"separator" ), QStringLiteral(
" - " ) ) +
"%2" +
263 element.attribute( QStringLiteral(
"suffix" ), QStringLiteral(
" " ) )
265 setPrecision( element.attribute( QStringLiteral(
"decimalplaces" ), QStringLiteral(
"4" ) ).toInt() );
266 mTrimTrailingZeroes = element.attribute( QStringLiteral(
"trimtrailingzeroes" ), QStringLiteral(
"false" ) ) == QLatin1String(
"true" );
271 element.setAttribute( QStringLiteral(
"format" ),
mFormat );
272 element.setAttribute( QStringLiteral(
"decimalplaces" ),
mPrecision );
273 element.setAttribute( QStringLiteral(
"trimtrailingzeroes" ),
mTrimTrailingZeroes ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
280 , mAttrName( attrName )
322 return QString::number( i );
341 if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
355 QVariant value = valueForFeature( feature, context );
358 if ( value.isNull() )
404 QSet<QString> attributes;
416 QgsRangeList::const_iterator range_it =
mRanges.constBegin();
417 for ( ; range_it !=
mRanges.constEnd(); ++range_it )
443 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
445 mRanges[rangeIndex].setSymbol( symbol );
451 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
453 mRanges[rangeIndex].setLabel( label );
459 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
470 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
481 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
483 mRanges[rangeIndex].setRenderState( value );
489 QString s = QStringLiteral(
"GRADUATED: attr %1\n" ).arg(
mAttrName );
490 for (
int i = 0; i <
mRanges.count(); i++ )
521 newProps[ QStringLiteral(
"attribute" )] =
mAttrName;
526 for ( QgsRangeList::const_iterator it =
mRanges.constBegin(); it !=
mRanges.constEnd(); ++it )
528 it->toSld( doc, element, newProps, first );
537 lst.reserve(
mRanges.count() );
540 lst.append( range.
symbol() );
552 if ( breaks.size() > 1 )
554 std::sort( breaks.begin(), breaks.end() );
556 double distBelowSymmetricValue = std::fabs( breaks[0] - symmetryPoint );
557 double distAboveSymmetricValue = std::fabs( breaks[ breaks.size() - 2 ] -
symmetryPoint ) ;
558 double absMin = std::min( distAboveSymmetricValue, distBelowSymmetricValue );
561 for (
int i = 0; i <= breaks.size() - 2; ++i )
564 if ( std::fabs( breaks.at( i ) -
symmetryPoint ) >= ( absMin - std::fabs( breaks[0] - breaks[1] ) / 100. ) )
566 breaks.removeAt( i );
573 breaks.removeAt( breaks.indexOf( symmetryPoint ) );
582 QList<double> breaks;
583 if ( !useSymmetricMode )
585 double step = ( maximum - minimum ) / classes;
587 double value = minimum;
588 breaks.reserve( classes );
589 for (
int i = 0; i < classes; i++ )
592 breaks.append( value );
596 breaks[classes - 1] = maximum;
598 else if ( useSymmetricMode )
600 double distBelowSymmetricValue = std::abs( minimum - symmetryPoint );
601 double distAboveSymmetricValue = std::abs( maximum - symmetryPoint ) ;
605 if ( classes % 2 == 0 )
610 if ( classes % 2 == 1 )
613 double step = 2 * std::min( distBelowSymmetricValue, distAboveSymmetricValue ) / classes;
615 breaks.reserve( classes );
616 double value = ( distBelowSymmetricValue < distAboveSymmetricValue ) ? minimum : maximum - classes * step;
618 for (
int i = 0; i < classes; i++ )
621 breaks.append( value );
623 breaks[classes - 1] = maximum;
628 static QList<double> _calcQuantileBreaks( QList<double> values,
int classes )
639 std::sort( values.begin(), values.end() );
641 QList<double> breaks;
644 if ( values.isEmpty() )
647 int n = values.count();
648 double Xq = n > 0 ? values[0] : 0.0;
650 breaks.reserve( classes );
651 for (
int i = 1; i < classes; i++ )
655 double q = i /
static_cast< double >( classes );
656 double a = q * ( n - 1 );
657 int aa =
static_cast< int >( a );
660 Xq = ( 1 - r ) * values[aa] + r * values[aa + 1];
665 breaks.append( values[ n - 1 ] );
681 if ( values.isEmpty() )
682 return QList<double>();
686 int n = values.count();
687 double minimum = values[0];
688 double maximum = values[0];
690 for (
int i = 0; i < n; i++ )
693 minimum = std::min( values[i], minimum );
694 maximum = std::max( values[i], maximum );
696 mean = mean /
static_cast< double >( n );
699 for (
int i = 0; i < n; i++ )
701 sd = values[i] - mean;
704 stdDev = std::sqrt( stdDev / n );
712 for (
int i = 0; i < breaks.count(); i++ )
714 labels.append( breaks[i] );
720 static QList<double> _calcJenksBreaks( QList<double> values,
int classes,
721 double minimum,
double maximum,
722 int maximumSize = 3000 )
734 if ( values.isEmpty() )
735 return QList<double>();
739 return QList<double>() << maximum;
742 if ( classes >= values.size() )
747 QVector<double> sample;
750 if ( values.size() > maximumSize )
756 sample.resize( std::max( maximumSize, values.size() / 10 ) );
758 QgsDebugMsg( QStringLiteral(
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ) );
759 QgsDebugMsg( QStringLiteral(
"values:%1" ).arg( values.size() ) );
761 sample[ 0 ] = minimum;
762 sample[ 1 ] = maximum;
763 for (
int i = 2; i < sample.size(); i++ )
767 int j = std::floor( r / RAND_MAX * ( values.size() - 1 ) );
768 sample[ i ] = values[ j ];
773 sample = values.toVector();
776 int n = sample.size();
779 std::sort( sample.begin(), sample.end() );
781 QVector< QVector<int> > matrixOne( n + 1 );
782 QVector< QVector<double> > matrixTwo( n + 1 );
784 for (
int i = 0; i <= n; i++ )
786 matrixOne[i].resize( classes + 1 );
787 matrixTwo[i].resize( classes + 1 );
790 for (
int i = 1; i <= classes; i++ )
794 matrixTwo[0][i] = 0.0;
795 for (
int j = 2; j <= n; j++ )
797 matrixTwo[j][i] = std::numeric_limits<double>::max();
801 for (
int l = 2; l <= n; l++ )
809 for (
int m = 1; m <= l; m++ )
813 double val = sample[ i3 - 1 ];
819 v = s2 - ( s1 * s1 ) / static_cast< double >( w );
823 for (
int j = 2; j <= classes; j++ )
825 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
827 matrixOne[l][j] = i4;
828 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
837 QVector<double> breaks( classes );
838 breaks[classes - 1] = sample[n - 1];
840 for (
int j = classes, k = n; j >= 2; j-- )
842 int id = matrixOne[k][j] - 1;
843 breaks[j - 2] = sample[id];
844 k = matrixOne[k][j] - 1;
847 return breaks.toList();
850 static QStringList _breaksAsStrings(
const QList<double> &breaks )
852 QStringList breaksAsStrings;
853 for (
int i = 0; i < breaks.count() - 1; i++ )
855 breaksAsStrings << QString::number( breaks.at( i ),
'f', 2 );
857 return breaksAsStrings;
862 const QString &attrName,
884 r->
updateClasses( vlayer, mode, classes, useSymmetricMode, symmetryPoint, astride );
905 QList<double> values;
906 bool valuesLoaded =
false;
916 if ( !ok || values.isEmpty() )
919 auto result = std::minmax_element( values.begin(), values.end() );
920 minimum = *result.first;
921 maximum = *result.second;
930 QgsDebugMsg( QStringLiteral(
"min %1 // max %2" ).arg( minimum ).arg( maximum ) );
931 QList<double> breaks;
932 QList<double> labels;
947 if ( useSymmetricMode )
963 breaks = _calcQuantileBreaks( values, nclasses );
964 else if ( mode ==
Jenks )
965 breaks = _calcJenksBreaks( values, nclasses, minimum, maximum );
966 else if ( mode ==
StdDev )
967 breaks = _calcStdDevBreaks( values, nclasses, labels,
mUseSymmetricMode, symmetryPoint, astride );
976 double lower, upper = minimum;
982 for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
992 label =
"< " + QString::number( labels[i],
'f', 2 ) +
" Std Dev";
994 else if ( i == labels.count() - 1 )
996 label =
">= " + QString::number( labels[i - 1],
'f', 2 ) +
" Std Dev";
1000 label = QString::number( labels[i - 1],
'f', 2 ) +
" Std Dev" +
" - " + QString::number( labels[i],
'f', 2 ) +
" Std Dev";
1016 QDomElement symbolsElem = element.firstChildElement( QStringLiteral(
"symbols" ) );
1017 if ( symbolsElem.isNull() )
1020 QDomElement rangesElem = element.firstChildElement( QStringLiteral(
"ranges" ) );
1021 if ( rangesElem.isNull() )
1027 QDomElement rangeElem = rangesElem.firstChildElement();
1028 while ( !rangeElem.isNull() )
1030 if ( rangeElem.tagName() == QLatin1String(
"range" ) )
1032 double lowerValue = rangeElem.attribute( QStringLiteral(
"lower" ) ).toDouble();
1033 double upperValue = rangeElem.attribute( QStringLiteral(
"upper" ) ).toDouble();
1034 QString symbolName = rangeElem.attribute( QStringLiteral(
"symbol" ) );
1035 QString label = rangeElem.attribute( QStringLiteral(
"label" ) );
1036 bool render = rangeElem.attribute( QStringLiteral(
"render" ), QStringLiteral(
"true" ) ) != QLatin1String(
"false" );
1037 if ( symbolMap.contains( symbolName ) )
1039 QgsSymbol *symbol = symbolMap.take( symbolName );
1040 ranges.append(
QgsRendererRange( lowerValue, upperValue, symbol, label, render ) );
1043 rangeElem = rangeElem.nextSiblingElement();
1046 QString attrName = element.attribute( QStringLiteral(
"attr" ) );
1050 QString attrMethod = element.attribute( QStringLiteral(
"graduatedMethod" ) );
1051 if ( !attrMethod.isEmpty() )
1064 QDomElement sourceSymbolElem = element.firstChildElement( QStringLiteral(
"source-symbol" ) );
1065 if ( !sourceSymbolElem.isNull() )
1068 if ( sourceSymbolMap.contains( QStringLiteral(
"0" ) ) )
1076 QDomElement sourceColorRampElem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
1077 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
1083 QDomElement modeElem = element.firstChildElement( QStringLiteral(
"mode" ) );
1084 if ( !modeElem.isNull() )
1086 QString modeString = modeElem.attribute( QStringLiteral(
"name" ) );
1087 if ( modeString == QLatin1String(
"equal" ) )
1089 else if ( modeString == QLatin1String(
"quantile" ) )
1091 else if ( modeString == QLatin1String(
"jenks" ) )
1093 else if ( modeString == QLatin1String(
"stddev" ) )
1095 else if ( modeString == QLatin1String(
"pretty" ) )
1100 QDomElement symmetricModeElem = element.firstChildElement( QStringLiteral(
"symmetricMode" ) );
1101 if ( !symmetricModeElem.isNull() )
1103 QString symmetricEnabled = symmetricModeElem.attribute( QStringLiteral(
"enabled" ) );
1106 QString symmetricPointString = symmetricModeElem.attribute( QStringLiteral(
"symmetryPoint" ) );
1108 QString breaksForPretty = symmetricModeElem.attribute( QStringLiteral(
"valueForCboPrettyBreaks" ) );
1111 QString astrideEnabled = symmetricModeElem.attribute( QStringLiteral(
"astride" ) );
1114 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"rotation" ) );
1115 if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
1126 QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral(
"sizescale" ) );
1127 if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral(
"field" ) ).isEmpty() )
1133 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
1139 sizeScaleElem.attribute( QStringLiteral(
"field" ) ) );
1143 QDomElement labelFormatElem = element.firstChildElement( QStringLiteral(
"labelformat" ) );
1144 if ( ! labelFormatElem.isNull() )
1151 QDomElement ddsLegendSizeElem = element.firstChildElement( QStringLiteral(
"data-defined-size-legend" ) );
1152 if ( !ddsLegendSizeElem.isNull() )
1163 rendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"graduatedSymbol" ) );
1164 rendererElem.setAttribute( QStringLiteral(
"symbollevels" ), (
mUsingSymbolLevels ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1165 rendererElem.setAttribute( QStringLiteral(
"forceraster" ), (
mForceRaster ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1166 rendererElem.setAttribute( QStringLiteral(
"attr" ),
mAttrName );
1172 QDomElement rangesElem = doc.createElement( QStringLiteral(
"ranges" ) );
1173 QgsRangeList::const_iterator it =
mRanges.constBegin();
1174 for ( ; it !=
mRanges.constEnd(); ++it )
1177 QString symbolName = QString::number( i );
1178 symbols.insert( symbolName, range.
symbol() );
1180 QDomElement rangeElem = doc.createElement( QStringLiteral(
"range" ) );
1181 rangeElem.setAttribute( QStringLiteral(
"lower" ), QString::number( range.
lowerValue(),
'f', 15 ) );
1182 rangeElem.setAttribute( QStringLiteral(
"upper" ), QString::number( range.
upperValue(),
'f', 15 ) );
1183 rangeElem.setAttribute( QStringLiteral(
"symbol" ), symbolName );
1184 rangeElem.setAttribute( QStringLiteral(
"label" ), range.
label() );
1185 rangeElem.setAttribute( QStringLiteral(
"render" ), range.
renderState() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1186 rangesElem.appendChild( rangeElem );
1190 rendererElem.appendChild( rangesElem );
1194 rendererElem.appendChild( symbolsElem );
1200 sourceSymbols.insert( QStringLiteral(
"0" ),
mSourceSymbol.get() );
1202 rendererElem.appendChild( sourceSymbolElem );
1209 rendererElem.appendChild( colorRampElem );
1217 modeString = QStringLiteral(
"equal" );
1220 modeString = QStringLiteral(
"quantile" );
1223 modeString = QStringLiteral(
"jenks" );
1226 modeString = QStringLiteral(
"stddev" );
1229 modeString = QStringLiteral(
"pretty" );
1234 if ( !modeString.isEmpty() )
1236 QDomElement modeElem = doc.createElement( QStringLiteral(
"mode" ) );
1237 modeElem.setAttribute( QStringLiteral(
"name" ), modeString );
1238 rendererElem.appendChild( modeElem );
1242 QDomElement symmetricModeElem = doc.createElement( QStringLiteral(
"symmetricMode" ) );
1243 symmetricModeElem.setAttribute( QStringLiteral(
"enabled" ),
mUseSymmetricMode ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1244 symmetricModeElem.setAttribute( QStringLiteral(
"symmetryPoint" ),
mSymmetryPoint );
1245 symmetricModeElem.setAttribute( QStringLiteral(
"astride" ),
mAstride ? QStringLiteral(
"true" ) : QStringLiteral(
"false" ) );
1252 breaks.append(
'/' );
1256 symmetricModeElem.setAttribute( QStringLiteral(
"valueForCboPrettyBreaks" ), breaks );
1259 rendererElem.appendChild( symmetricModeElem );
1261 QDomElement rotationElem = doc.createElement( QStringLiteral(
"rotation" ) );
1262 rendererElem.appendChild( rotationElem );
1264 QDomElement sizeScaleElem = doc.createElement( QStringLiteral(
"sizescale" ) );
1265 rendererElem.appendChild( sizeScaleElem );
1267 QDomElement labelFormatElem = doc.createElement( QStringLiteral(
"labelformat" ) );
1269 rendererElem.appendChild( labelFormatElem );
1276 QDomElement
orderBy = doc.createElement( QStringLiteral(
"orderby" ) );
1278 rendererElem.appendChild( orderBy );
1280 rendererElem.setAttribute( QStringLiteral(
"enableorderby" ), (
mOrderByEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) ) );
1284 QDomElement ddsLegendElem = doc.createElement( QStringLiteral(
"data-defined-size-legend" ) );
1286 rendererElem.appendChild( ddsLegendElem );
1289 return rendererElem;
1315 if ( sSize && sSize != ddSize )
1318 return baseLegendSymbolItems();
1335 lst += baseLegendSymbolItems();
1340 return baseLegendSymbolItems();
1345 QVariant value = valueForFeature( feature, context );
1348 if ( value.isNull() )
1349 return QSet< QString >();
1353 if ( !key.isNull() )
1354 return QSet< QString >() << key;
1356 return QSet< QString >();
1383 double min = std::numeric_limits<double>::max();
1384 for (
int i = 0; i <
mRanges.count(); i++ )
1388 sz = static_cast< QgsMarkerSymbol * >(
mRanges[i].symbol() )->size();
1390 sz = static_cast< QgsLineSymbol * >(
mRanges[i].symbol() )->width();
1391 min = std::min( sz, min );
1398 double max = std::numeric_limits<double>::min();
1399 for (
int i = 0; i <
mRanges.count(); i++ )
1403 sz = static_cast< QgsMarkerSymbol * >(
mRanges[i].symbol() )->size();
1405 sz = static_cast< QgsLineSymbol * >(
mRanges[i].symbol() )->width();
1406 max = std::max( sz, max );
1413 for (
int i = 0; i <
mRanges.count(); i++ )
1415 std::unique_ptr<QgsSymbol> symbol(
mRanges.at( i ).symbol() ?
mRanges.at( i ).symbol()->clone() : nullptr );
1416 const double size =
mRanges.count() > 1
1417 ? minSize + i * ( maxSize - minSize ) / (
mRanges.count() - 1 )
1418 : .5 * ( maxSize + minSize );
1420 static_cast< QgsMarkerSymbol * >( symbol.get() )->setSize( size );
1422 static_cast< QgsLineSymbol * >( symbol.get() )->setWidth( size );
1443 colorValue = (
mRanges.count() > 1 ?
static_cast< double >( i ) / (
mRanges.count() - 1 ) : 0 );
1461 std::unique_ptr<QgsSymbol> symbol( sym->
clone() );
1469 static_cast<QgsMarkerSymbol *>( symbol.get() )->setSize(
1470 static_cast<QgsMarkerSymbol *>( range.
symbol() )->size() );
1472 static_cast<QgsLineSymbol *>( symbol.get() )->setWidth(
1473 static_cast<QgsLineSymbol *>( range.
symbol() )->width() );
1489 int index = key.toInt( &ok );
1490 if ( ok && index >= 0 && index <
mRanges.size() )
1491 return mRanges.at( index ).renderState();
1499 int index = key.toInt( &ok );
1507 int index = key.toInt( &ok );
1517 QString label = QStringLiteral(
"0.0 - 0.0" );
1530 QMutableListIterator< QgsRendererRange > it(
mRanges );
1531 while ( it.hasNext() )
1546 it.setValue( range );
1548 it.insert( newRange );
1553 if ( updateSymbols )
1586 for ( QgsRangeList::iterator it =
mRanges.begin(); it !=
mRanges.end(); ++it )
1598 double minClassRange = 0.0;
1604 if ( minClassRange == 0.0 || range < minClassRange )
1605 minClassRange = range;
1607 if ( minClassRange <= 0.0 )
1614 double nextDpMinRange = 0.0000000099;
1615 while ( ndp > 0 && nextDpMinRange < minClassRange )
1618 nextDpMinRange *= 10.0;
1626 if ( from < 0 || from >=
mRanges.size() || to < 0 || to >=
mRanges.size() )
1643 if ( order == Qt::AscendingOrder )
1656 std::sort( sortedRanges.begin(), sortedRanges.end(),
valueLessThan );
1658 QgsRangeList::const_iterator it = sortedRanges.constBegin();
1659 if ( it == sortedRanges.constEnd() )
1662 if ( ( *it ).upperValue() < ( *it ).lowerValue() )
1665 double prevMax = ( *it ).upperValue();
1668 for ( ; it != sortedRanges.constEnd(); ++it )
1670 if ( ( *it ).upperValue() < ( *it ).lowerValue() )
1673 if ( ( *it ).lowerValue() < prevMax )
1676 prevMax = ( *it ).upperValue();
1684 std::sort( sortedRanges.begin(), sortedRanges.end(),
valueLessThan );
1686 QgsRangeList::const_iterator it = sortedRanges.constBegin();
1687 if ( it == sortedRanges.constEnd() )
1690 double prevMax = ( *it ).upperValue();
1693 for ( ; it != sortedRanges.constEnd(); ++it )
1698 prevMax = ( *it ).upperValue();
1705 return QString::localeAwareCompare( r1.
label(), r2.
label() ) < 0;
1715 if ( order == Qt::AscendingOrder )
1728 if ( renderer->
type() == QLatin1String(
"graduatedSymbol" ) )
1732 else if ( renderer->
type() == QLatin1String(
"pointDisplacement" ) || renderer->
type() == QLatin1String(
"pointCluster" ) )
1735 if ( pointDistanceRenderer )
1738 else if ( renderer->
type() == QLatin1String(
"invertedPolygonRenderer" ) )
1741 if ( invertedPolygonRenderer )
1753 if ( !symbols.isEmpty() )
1780 return "GraduatedColor";
1782 return "GraduatedSize";
An abstract base class for distance based point renderers (e.g., clusterer and displacement renderers...
Class for parsing and evaluation of expressions (formerly called "search strings").
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 CORE_EXPORT save(QDomElement &elem) const
Serialize to XML.
void stopRender(QgsRenderContext &context) override
Must be called when a render cycle has finished, to allow the renderer to clean up.
void toSld(QDomDocument &doc, QDomElement &element, QgsStringMap props, bool firstRange=false) const
Creates a DOM element representing the range in SLD format.
double minSymbolSize() const
Returns the min symbol size when graduated by size.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
std::unique_ptr< QgsSymbol > mSourceSymbol
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
double maxSymbolSize() const
Returns the max symbol size when graduated by size.
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
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.
bool isActive() const
Returns whether the property is currently active.
double rendererScale() const
Returns the renderer map scale.
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.
QSet< QString > referencedColumns() const
Gets list of columns referenced by the expression.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Abstract base class for color ramps.
bool usingSymbolLevels() const
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...
bool astride() const
Returns if we want to have a central class astride the pivot value.
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.
Container of fields for a vector layer.
void setRenderState(bool render)
#define RENDERER_TAG_NAME
void setUsingSymbolLevels(bool usingSymbolLevels)
double lowerValue() const
static void clearSymbolMap(QgsSymbolMap &symbols)
QgsRendererRange & operator=(QgsRendererRange range)
void setAstride(bool astride)
Set if we want a central class astride the pivot value.
QgsSymbol * symbol() const
QgsPaintEffect * mPaintEffect
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 useSymmetricMode() const
Returns if we want to classify symmetric around a given value.
static const char * graduatedMethodStr(GraduatedMethod method)
std::unique_ptr< QgsExpression > mExpression
void setUpperValue(double upperValue)
void addClass(QgsSymbol *symbol)
QMap< QString, QString > QgsStringMap
QgsDataDefinedSizeLegend * dataDefinedSizeLegend() const
Returns configuration of appearance of legend when using data-defined size for marker symbols...
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.
void checkLegendSymbolItem(const QString &key, bool state=true) override
item in symbology was checked
void sortByValue(Qt::SortOrder order=Qt::AscendingOrder)
double upperValue() const
void setUseSymmetricMode(bool useSymmetricMode)
Set if we want to classify symmetric around a given value.
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.
double symmetryPoint() const
Returns the pivot value for symmetric classification.
void setLowerValue(double lowerValue)
bool labelGreaterThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
QgsLegendSymbolList legendSymbolList() const
Generates legend symbol items according to the configuration.
bool needsGeometry() const
Returns true if the expression uses feature geometry for some computation.
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.
QgsSymbol * symbolForValue(double value) const
Gets the symbol which is used to represent 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.
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.
QVariant minimumValue(int index) const FINAL
Returns the minimum value for an attribute column or an invalid variant in case of error...
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
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.
const QgsRangeList & ranges() const
A store for object properties.
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...
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.
const QgsRendererRangeLabelFormat & labelFormat() const
Returns the label format used to generate default classification labels.
QgsSymbol * originalSymbolForFeature(const QgsFeature &feature, QgsRenderContext &context) const override
Returns symbol for feature.
QgsExpressionContext & expressionContext()
Gets the expression context.
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
bool operator<(const QgsRendererRange &other) const
const QgsFeatureRenderer * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
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.
QString legendKeyForValue(double value) const
Returns the matching legend key for a value.
QgsRendererRangeLabelFormat mLabelFormat
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
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)
QgsGraduatedSymbolRenderer(const QString &attrName=QString(), const QgsRangeList &ranges=QgsRangeList())
bool rangesOverlap() const
Tests whether classes assigned to the renderer have ranges which overlap.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)
Must be called when a new render cycle is started.
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.
GraduatedMethod graduatedMethod() const
Returns the method used for graduation (either size or color)
void setDataDefinedSizeLegend(QgsDataDefinedSizeLegend *settings)
Configures appearance of legend when renderer is configured to use data-defined size for marker symbo...
void copyRendererData(QgsFeatureRenderer *destRenderer) const
Clones generic renderer data to another renderer.
QString dump() const override
Returns debug information about this renderer.
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.
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
QStringList listForCboPrettyBreaks() const
Returns the list of breaks used in the prettybreaks mode.
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)
QgsFeatureRequest::OrderBy orderBy() const
Gets the order in which features shall be processed by this renderer.
bool valueGreaterThan(const QgsRendererRange &r1, const QgsRendererRange &r2)
QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
bool updateRangeLabel(int rangeIndex, const QString &label)
bool legendSymbolItemChecked(const QString &key) override
items of symbology items in legend is checked
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...
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
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.
QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns a list of attributes required to render this feature.
QColor color() const
Returns the symbol's color.
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.
bool rangesHaveGaps() const
Tests whether classes assigned to the renderer have gaps between the ranges.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend...
std::unique_ptr< QgsDataDefinedSizeLegend > mDataDefinedSizeLegend
void stopRender(QgsRenderContext &context)
Ends the rendering process.
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)
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.