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.