@@ -630,7 +630,7 @@ static QList<double> _calcPrettyBreaks( double minimum, double maximum, int clas
630
630
} // _calcPrettyBreaks
631
631
632
632
633
- static QList<double > _calcStdDevBreaks ( QList<double > values, int classes, QList<int > &labels )
633
+ static QList<double > _calcStdDevBreaks ( QList<double > values, int classes, QList<double > &labels )
634
634
{
635
635
636
636
// C++ implementation of the standard deviation class interval algorithm
@@ -669,7 +669,7 @@ static QList<double> _calcStdDevBreaks( QList<double> values, int classes, QList
669
669
QList<double > breaks = _calcPrettyBreaks (( minimum - mean ) / stdDev, ( maximum - mean ) / stdDev, classes );
670
670
for ( int i = 0 ; i < breaks.count (); i++ )
671
671
{
672
- labels.append (( int ) breaks[i] );
672
+ labels.append ( breaks[i] );
673
673
breaks[i] = ( breaks[i] * stdDev ) + mean;
674
674
}
675
675
@@ -820,10 +820,31 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
820
820
QString units,
821
821
int decimalPlaces )
822
822
{
823
- if ( classes < 1 )
824
- return NULL ;
823
+ QgsRangeList ranges;
824
+ QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2 ( attrName, ranges );
825
+ r->setSourceSymbol ( symbol->clone () );
826
+ r->setSourceColorRamp ( ramp->clone () );
827
+ r->setInvertedColorRamp ( inverted );
828
+ r->setMode ( mode );
829
+ r->setUnits ( units );
830
+ r->updateClasses (vlayer,mode,classes);
831
+ r->setDecimalPlaces ( decimalPlaces );
832
+
833
+ return r;
834
+ }
825
835
826
- int attrNum = vlayer->fieldNameIndex ( attrName );
836
+
837
+ void QgsGraduatedSymbolRendererV2::updateClasses ( QgsVectorLayer *vlayer, Mode mode, int nclasses )
838
+ {
839
+ // Custom classes are not recalculated
840
+ setMode (mode);
841
+ if ( mode == Custom ) return ;
842
+
843
+
844
+
845
+ if ( nclasses < 1 ) nclasses=1 ;
846
+
847
+ int attrNum = vlayer->fieldNameIndex ( mAttrName );
827
848
double minimum;
828
849
double maximum;
829
850
@@ -832,9 +853,9 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
832
853
if ( attrNum == -1 )
833
854
{
834
855
// try to use expression
835
- expression.reset ( new QgsExpression ( attrName ) );
856
+ expression.reset ( new QgsExpression ( mAttrName ) );
836
857
if ( expression->hasParserError () || !expression->prepare ( vlayer->pendingFields () ) )
837
- return 0 ; // should have a means to report errors
858
+ return ; // should have a means to report errors
838
859
839
860
QList<double > values;
840
861
QgsFeatureIterator fit = vlayer->getFeatures ();
@@ -855,14 +876,14 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
855
876
856
877
QgsDebugMsg ( QString ( " min %1 // max %2" ).arg ( minimum ).arg ( maximum ) );
857
878
QList<double > breaks;
858
- QList<int > labels;
879
+ QList<double > labels;
859
880
if ( mode == EqualInterval )
860
881
{
861
- breaks = _calcEqualIntervalBreaks ( minimum, maximum, classes );
882
+ breaks = _calcEqualIntervalBreaks ( minimum, maximum, nclasses );
862
883
}
863
884
else if ( mode == Pretty )
864
885
{
865
- breaks = _calcPrettyBreaks ( minimum, maximum, classes );
886
+ breaks = _calcPrettyBreaks ( minimum, maximum, nclasses );
866
887
}
867
888
else if ( mode == Quantile || mode == Jenks || mode == StdDev )
868
889
{
@@ -871,7 +892,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
871
892
QgsFeature f;
872
893
QStringList lst;
873
894
if ( expression.isNull () )
874
- lst.append ( attrName );
895
+ lst.append ( mAttrName );
875
896
else
876
897
lst = expression->referencedColumns ();
877
898
@@ -888,76 +909,65 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
888
909
// calculate the breaks
889
910
if ( mode == Quantile )
890
911
{
891
- breaks = _calcQuantileBreaks ( values, classes );
912
+ breaks = _calcQuantileBreaks ( values, nclasses );
892
913
}
893
914
else if ( mode == Jenks )
894
915
{
895
- breaks = _calcJenksBreaks ( values, classes , minimum, maximum );
916
+ breaks = _calcJenksBreaks ( values, nclasses , minimum, maximum );
896
917
}
897
918
else if ( mode == StdDev )
898
919
{
899
- breaks = _calcStdDevBreaks ( values, classes , labels );
920
+ breaks = _calcStdDevBreaks ( values, nclasses , labels );
900
921
}
901
922
}
902
923
else
903
924
{
904
925
Q_ASSERT ( false );
905
926
}
906
927
907
- QgsRangeList ranges;
928
+
908
929
double lower, upper = minimum;
909
930
QString label;
910
-
911
- QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2 ( attrName, ranges );
912
- r->setSourceSymbol ( symbol->clone () );
913
- r->setSourceColorRamp ( ramp->clone () );
914
- r->setInvertedColorRamp ( inverted );
915
- r->setMode ( mode );
916
- r->setUnits ( units );
917
- r->setDecimalPlaces ( decimalPlaces );
931
+ mRanges .clear ();
918
932
919
933
// "breaks" list contains all values at class breaks plus maximum as last break
934
+
920
935
int i = 0 ;
921
936
for ( QList<double >::iterator it = breaks.begin (); it != breaks.end (); ++it, ++i )
922
937
{
923
938
lower = upper; // upper border from last interval
924
939
upper = *it;
925
940
926
941
// Symbol based on range
927
- QgsSymbolV2* newSymbol = symbol->clone ();
928
- double colorValue;
929
- if ( inverted ) colorValue = ( breaks.count () > 1 ? ( double )( breaks.count () - i - 1 ) / ( breaks.count () - 1 ) : 0 );
930
- else colorValue = ( breaks.count () > 1 ? ( double ) i / ( breaks.count () - 1 ) : 0 );
931
- newSymbol->setColor ( ramp->color ( colorValue ) ); // color from (0 / cl-1) to (cl-1 / cl-1)
932
-
942
+ QgsSymbolV2* newSymbol = mSourceSymbol ->clone ();
933
943
QgsRendererRangeV2 range = QgsRendererRangeV2 ( lower, upper, newSymbol, " " );
934
944
935
945
// Label - either StdDev label or default label for a range
936
946
if ( mode == StdDev )
937
947
{
938
948
if ( i == 0 )
939
949
{
940
- label = " < " + QString::number ( labels[i], ' i ' , 0 ) + " Std Dev" ;
950
+ label = " < " + QString::number ( labels[i], ' f ' , 2 ) + " Std Dev" ;
941
951
}
942
952
else if ( i == labels.count () - 1 )
943
953
{
944
- label = " >= " + QString::number ( labels[i-1 ], ' i ' , 0 ) + " Std Dev" ;
954
+ label = " >= " + QString::number ( labels[i-1 ], ' f ' , 2 ) + " Std Dev" ;
945
955
}
946
956
else
947
957
{
948
- label = QString::number ( labels[i-1 ], ' i ' , 0 ) + " Std Dev" + " - " + QString::number ( labels[i], ' i ' , 0 ) + " Std Dev" ;
958
+ label = QString::number ( labels[i-1 ], ' f ' , 2 ) + " Std Dev" + " - " + QString::number ( labels[i], ' f ' , 2 ) + " Std Dev" ;
949
959
}
950
960
}
951
961
else
952
962
{
953
- label=r-> defaultRangeLabel (range);
963
+ label=defaultRangeLabel (range);
954
964
}
955
965
range.setLabel (label);
956
966
957
- r-> addClass ( range );
967
+ addClass ( range );
958
968
}
969
+ updateColorRamp (0 ,mInvertedColorRamp );
959
970
960
- return r;
961
971
}
962
972
963
973
@@ -1201,18 +1211,20 @@ void QgsGraduatedSymbolRendererV2::setSourceColorRamp( QgsVectorColorRampV2* ram
1201
1211
void QgsGraduatedSymbolRendererV2::updateColorRamp ( QgsVectorColorRampV2 *ramp, bool inverted )
1202
1212
{
1203
1213
int i = 0 ;
1214
+ if ( ramp ) this ->setSourceColorRamp ( ramp );
1215
+ this ->setInvertedColorRamp ( inverted );
1216
+
1204
1217
foreach ( QgsRendererRangeV2 range, mRanges )
1205
1218
{
1206
1219
QgsSymbolV2* symbol = range.symbol ()->clone ();
1207
1220
double colorValue;
1208
1221
if ( inverted ) colorValue = ( mRanges .count () > 1 ? ( double )( mRanges .count () - i - 1 ) / ( mRanges .count () - 1 ) : 0 );
1209
1222
else colorValue = ( mRanges .count () > 1 ? ( double ) i / ( mRanges .count () - 1 ) : 0 );
1210
- symbol->setColor ( ramp ->color ( colorValue ) );
1223
+ symbol->setColor ( mSourceColorRamp ->color ( colorValue ) );
1211
1224
updateRangeSymbol ( i, symbol );
1212
1225
++i;
1213
1226
}
1214
- this ->setSourceColorRamp ( ramp );
1215
- this ->setInvertedColorRamp ( inverted );
1227
+
1216
1228
}
1217
1229
1218
1230
void QgsGraduatedSymbolRendererV2::updateSymbols ( QgsSymbolV2 *sym )
@@ -1343,6 +1355,32 @@ void QgsGraduatedSymbolRendererV2::setDecimalPlaces( int decimalPlaces, bool upd
1343
1355
mDecimalPlaces =decimalPlaces;
1344
1356
}
1345
1357
1358
+ void QgsGraduatedSymbolRendererV2::calculateDecimalPlaces ( bool updateRanges )
1359
+ {
1360
+ // Find the minimum size of a class
1361
+ double minClassRange=0.0 ;
1362
+ for ( QgsRangeList::iterator it = mRanges .begin (); it != mRanges .end (); ++it )
1363
+ {
1364
+ double range = it->upperValue ()-it->lowerValue ();
1365
+ if ( range <= 0.0 ) continue ;
1366
+ if ( minClassRange == 0.0 || range < minClassRange ) minClassRange=range;
1367
+ }
1368
+ if ( minClassRange <= 0.0 ) return ;
1369
+
1370
+ // Now set the number of decimal places to ensure no more than 20% error in
1371
+ // representing this range (up to 10% at upper and lower end)
1372
+
1373
+ int ndp=10 ;
1374
+ double nextDpMinRange=0.0000000099 ;
1375
+ while ( ndp > 0 && nextDpMinRange < minClassRange )
1376
+ {
1377
+ ndp--;
1378
+ nextDpMinRange *= 10.0 ;
1379
+ }
1380
+
1381
+ setDecimalPlaces (ndp,updateRanges);
1382
+ }
1383
+
1346
1384
void QgsGraduatedSymbolRendererV2::moveClass ( int from, int to )
1347
1385
{
1348
1386
if ( from < 0 || from >= mRanges .size () || to < 0 || to >= mRanges .size () ) return ;
0 commit comments