25 #include <QDomDocument>
26 #include <QDomElement>
33 : mLowerValue( lowerValue )
34 , mUpperValue( upperValue )
41 : mLowerValue( range.mLowerValue )
42 , mUpperValue( range.mUpperValue )
43 , mLabel( range.mLabel )
105 mAttrName( attrName ),
108 mSourceSymbol( NULL ),
109 mSourceColorRamp( NULL ),
110 mRotationFieldIdx( -1 ),
111 mSizeScaleFieldIdx( -1 )
125 for ( QgsRangeList::iterator it =
mRanges.begin(); it !=
mRanges.end(); ++it )
127 if ( it->lowerValue() <= value && it->upperValue() >= value )
137 QgsAttributeMap::const_iterator ita = attrMap.find(
mAttrNum );
138 if ( ita == attrMap.end() )
146 if ( symbol == NULL )
154 double sizeScale = 1;
170 markerSymbol->
setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
176 lineSymbol->
setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
189 QgsRangeList::iterator it =
mRanges.begin();
190 for ( ; it !=
mRanges.end(); ++it )
192 it->symbol()->startRender( context );
207 QgsRangeList::iterator it =
mRanges.begin();
208 for ( ; it !=
mRanges.end(); ++it )
209 it->symbol()->stopRender( context );
212 #if QT_VERSION < 0x40600
213 QMap<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 =
mTempSymbols.begin();
215 QHash<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 =
mTempSymbols.begin();
219 it2.value()->stopRender( context );
238 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
240 mRanges[rangeIndex].setSymbol( symbol );
246 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
248 mRanges[rangeIndex].setLabel( label );
254 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
256 mRanges[rangeIndex].setUpperValue( value );
262 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
264 mRanges[rangeIndex].setLowerValue( value );
270 QString s = QString(
"GRADUATED: attr %1\n" ).arg(
mAttrName );
271 for (
int i = 0; i <
mRanges.count(); i++ )
293 for (
int i = 0; i <
mRanges.count(); i++ )
294 lst.append(
mRanges[i].symbol() );
306 double step = ( maximum - minimum ) / classes;
308 QList<double> breaks;
309 double value = minimum;
310 for (
int i = 0; i < classes; i++ )
313 breaks.append( value );
332 QList<double> breaks;
334 int n = values.count();
335 double Xq = n > 0 ? values[0] : 0.0;
337 for (
int i = 1; i < classes; i++ )
341 double q = i / ( double ) classes;
342 double a = q * ( n - 1 );
343 int aa = ( int )( a );
346 Xq = ( 1 - r ) * values[aa] + r * values[aa+1];
351 breaks.append( values[ n-1 ] );
368 QList<double> breaks;
371 breaks.append( maximum );
375 int minimumCount = ( int ) classes / 3;
376 double shrink = 0.75;
377 double highBias = 1.5;
378 double adjustBias = 0.5 + 1.5 * highBias;
379 int divisions = classes;
384 double dx = maximum - minimum;
386 if ( dx == 0 && maximum == 0 )
394 cell = qMax( qAbs( minimum ), qAbs( maximum ) );
395 if ( adjustBias >= 1.5 * h + 0.5 )
397 U = 1 + ( 1.0 / ( 1 + h ) );
401 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
403 small = dx < ( cell * U * qMax( 1, divisions ) * 1e-07 * 3.0 );
410 cell = 9 + cell / 10;
411 cell = cell * shrink;
413 if ( minimumCount > 1 )
415 cell = cell / minimumCount;
423 cell = cell / divisions;
426 if ( cell < 20 * 1e-07 )
431 double base = pow( 10.0, floor( log10( cell ) ) );
433 if (( 2 * base ) - cell < h *( cell - unit ) )
436 if (( 5 * base ) - cell < adjustBias *( cell - unit ) )
439 if (( 10.0 * base ) - cell < h *( cell - unit ) )
446 int start = floor( minimum / unit + 1e-07 );
447 int end = ceil( maximum / unit - 1e-07 );
450 while ( start * unit > minimum + ( 1e-07 * unit ) )
454 while ( end * unit < maximum - ( 1e-07 * unit ) )
458 QgsDebugMsg( QString(
"pretty classes: %1" ).arg( end ) );
462 int k = floor( 0.5 + end - start );
463 if ( k < minimumCount )
465 k = minimumCount - k;
469 start = start - k / 2 + k % 2;
473 start = start - k / 2;
474 end = end + k / 2 + k % 2;
476 divisions = minimumCount;
482 double minimumBreak = start * unit;
483 double maximumBreak = end * unit;
484 int count = ceil( maximumBreak - minimumBreak ) / unit;
486 for (
int i = 1; i < count + 1; i++ )
488 breaks.append( minimumBreak + i * unit );
491 if ( breaks.first() < minimum )
495 if ( breaks.last() > maximum )
497 breaks[breaks.count()-1] = maximum;
515 int n = values.count();
516 double minimum = values[0];
517 double maximum = values[0];
519 for (
int i = 0; i < n; i++ )
522 minimum = qMin( values[i], minimum );
523 maximum = qMax( values[i], maximum );
525 mean = mean / ( double ) n;
528 for (
int i = 0; i < n; i++ )
530 sd = values[i] - mean;
533 stdDev = sqrt( stdDev / n );
535 QList<double> breaks =
_calcPrettyBreaks(( minimum - mean ) / stdDev, ( maximum - mean ) / stdDev, classes );
536 for (
int i = 0; i < breaks.count(); i++ )
538 labels.append((
int ) breaks[i] );
539 breaks[i] = ( breaks[i] * stdDev ) + mean;
546 double minimum,
double maximum,
547 int maximumSize = 1000 )
561 return QList<double>() << maximum;
564 if ( classes >= values.size() )
569 QVector<double> sample;
572 if ( values.size() > maximumSize )
580 sample.resize( qMax( maximumSize, values.size() / 10 ) );
582 QgsDebugMsg( QString(
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ) );
583 QgsDebugMsg( QString(
"values:%1" ).arg( values.size() ) );
585 sample[ 0 ] = minimum;
586 sample[ 1 ] = maximum;;
587 for (
int i = 2; i < sample.size(); i++ )
591 int j = floor( r / RAND_MAX * ( values.size() - 1 ) );
592 sample[ i ] = values[ j ];
597 sample = values.toVector();
600 int n = sample.size();
605 QVector< QVector<int> > matrixOne( n + 1 );
606 QVector< QVector<double> > matrixTwo( n + 1 );
608 for (
int i = 0; i <= n; i++ )
610 matrixOne[i].resize( classes + 1 );
611 matrixTwo[i].resize( classes + 1 );
614 for (
int i = 1; i <= classes; i++ )
618 matrixTwo[0][i] = 0.0;
619 for (
int j = 2; j <= n; j++ )
625 for (
int l = 2; l <= n; l++ )
633 for (
int m = 1; m <= l; m++ )
637 double val = sample[ i3 - 1 ];
643 v = s2 - ( s1 * s1 ) / (
double ) w;
647 for (
int j = 2; j <= classes; j++ )
649 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
651 matrixOne[l][j] = i4;
652 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
661 QVector<double> breaks( classes );
662 breaks[classes-1] = sample[n-1];
664 for (
int j = classes, k = n; j >= 2; j-- )
666 int id = matrixOne[k][j] - 1;
667 breaks[j - 2] = sample[id];
668 k = matrixOne[k][j] - 1;
671 return breaks.toList();
685 double minimum = vlayer->
minimumValue( attrNum ).toDouble();
686 double maximum = vlayer->
maximumValue( attrNum ).toDouble();
687 QgsDebugMsg( QString(
"min %1 // max %2" ).arg( minimum ).arg( maximum ) );
689 QList<double> breaks;
695 else if ( mode ==
Pretty )
702 QList<double> values;
705 lst.append( attrNum );
714 else if ( mode ==
Jenks )
718 else if ( mode ==
StdDev )
729 double lower, upper = minimum;
734 for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
742 label =
"< " + QString::number( labels[i],
'i', 0 ) +
" Std Dev";
744 else if ( i == labels.count() - 1 )
746 label =
">= " + QString::number( labels[i-1],
'i', 0 ) +
" Std Dev";
750 label = QString::number( labels[i-1],
'i', 0 ) +
" Std Dev" +
" - " + QString::number( labels[i],
'i', 0 ) +
" Std Dev";
755 label = QString::number( lower,
'f', 4 ) +
" - " + QString::number( upper,
'f', 4 );
759 newSymbol->
setColor( ramp->
color((
double ) i / ( breaks.count() - 1 ) ) );
773 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
774 if ( symbolsElem.isNull() )
777 QDomElement rangesElem = element.firstChildElement(
"ranges" );
778 if ( rangesElem.isNull() )
784 QDomElement rangeElem = rangesElem.firstChildElement();
785 while ( !rangeElem.isNull() )
787 if ( rangeElem.tagName() ==
"range" )
789 double lowerValue = rangeElem.attribute(
"lower" ).toDouble();
790 double upperValue = rangeElem.attribute(
"upper" ).toDouble();
791 QString symbolName = rangeElem.attribute(
"symbol" );
792 QString label = rangeElem.attribute(
"label" );
793 if ( symbolMap.contains( symbolName ) )
795 QgsSymbolV2* symbol = symbolMap.take( symbolName );
799 rangeElem = rangeElem.nextSiblingElement();
802 QString attrName = element.attribute(
"attr" );
810 QDomElement sourceSymbolElem = element.firstChildElement(
"source-symbol" );
811 if ( !sourceSymbolElem.isNull() )
814 if ( sourceSymbolMap.contains(
"0" ) )
822 QDomElement sourceColorRampElem = element.firstChildElement(
"colorramp" );
823 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute(
"name" ) ==
"[source]" )
829 QDomElement modeElem = element.firstChildElement(
"mode" );
830 if ( !modeElem.isNull() )
832 QString modeString = modeElem.attribute(
"name" );
833 if ( modeString ==
"equal" )
835 else if ( modeString ==
"quantile" )
837 else if ( modeString ==
"jenks" )
839 else if ( modeString ==
"stddev" )
841 else if ( modeString ==
"pretty" )
845 QDomElement rotationElem = element.firstChildElement(
"rotation" );
846 if ( !rotationElem.isNull() )
849 QDomElement sizeScaleElem = element.firstChildElement(
"sizescale" );
850 if ( !sizeScaleElem.isNull() )
860 rendererElem.setAttribute(
"type",
"graduatedSymbol" );
862 rendererElem.setAttribute(
"attr",
mAttrName );
867 QDomElement rangesElem = doc.createElement(
"ranges" );
868 QgsRangeList::const_iterator it =
mRanges.constBegin();
869 for ( ; it !=
mRanges.end(); it++ )
872 QString symbolName = QString::number( i );
873 symbols.insert( symbolName, range.
symbol() );
875 QDomElement rangeElem = doc.createElement(
"range" );
876 rangeElem.setAttribute(
"lower", range.
lowerValue() );
877 rangeElem.setAttribute(
"upper", range.
upperValue() );
878 rangeElem.setAttribute(
"symbol", symbolName );
879 rangeElem.setAttribute(
"label", range.
label() );
880 rangesElem.appendChild( rangeElem );
884 rendererElem.appendChild( rangesElem );
888 rendererElem.appendChild( symbolsElem );
896 rendererElem.appendChild( sourceSymbolElem );
903 rendererElem.appendChild( colorRampElem );
909 modeString =
"equal";
911 modeString =
"quantile";
913 modeString =
"jenks";
915 modeString =
"stddev";
917 modeString =
"pretty";
918 if ( !modeString.isEmpty() )
920 QDomElement modeElem = doc.createElement(
"mode" );
921 modeElem.setAttribute(
"name", modeString );
922 rendererElem.appendChild( modeElem );
925 QDomElement rotationElem = doc.createElement(
"rotation" );
927 rendererElem.appendChild( rotationElem );
929 QDomElement sizeScaleElem = doc.createElement(
"sizescale" );
931 rendererElem.appendChild( sizeScaleElem );
939 bool showClassifiers = settings.value(
"/qgis/showLegendClassifiers",
false ).toBool();
942 if ( showClassifiers )
947 int count =
ranges().count();
948 for (
int i = 0; i < count; i++ )
952 lst << qMakePair( range.
label(), pix );
960 bool showClassifiers = settings.value(
"/qgis/showLegendClassifiers",
false ).toBool();
963 if ( showClassifiers )
968 QgsRangeList::const_iterator rangeIt =
mRanges.constBegin();
969 for ( ; rangeIt !=
mRanges.constEnd(); ++rangeIt )
971 lst << qMakePair( rangeIt->label(), rangeIt->symbol() );
999 QString label =
"0.0 - 0.0";