26 #include <QDomDocument>
27 #include <QDomElement>
34 : mLowerValue( 0 ), mUpperValue( 0 ), mSymbol( 0 ), mLabel()
39 : mLowerValue( lowerValue )
40 , mUpperValue( upperValue )
47 : mLowerValue( range.mLowerValue )
48 , mUpperValue( range.mUpperValue )
49 , mLabel( range.mLabel )
122 if ( !
mSymbol || props.value(
"attribute",
"" ).isEmpty() )
125 QString attrName = props[
"attribute" ];
127 QDomElement ruleElem = doc.createElement(
"se:Rule" );
128 element.appendChild( ruleElem );
130 QDomElement nameElem = doc.createElement(
"se:Name" );
131 nameElem.appendChild( doc.createTextNode(
mLabel ) );
132 ruleElem.appendChild( nameElem );
134 QDomElement descrElem = doc.createElement(
"se:Description" );
135 QDomElement titleElem = doc.createElement(
"se:Title" );
137 titleElem.appendChild( doc.createTextNode( !
mLabel.isEmpty() ?
mLabel : descrStr ) );
138 descrElem.appendChild( titleElem );
139 ruleElem.appendChild( descrElem );
142 QString filterFunc = QString(
"%1 > %2 AND %1 <= %3" )
143 .arg( attrName.replace(
"\"",
"\"\"" ) )
154 mAttrName( attrName ),
157 mSourceSymbol( NULL ),
158 mSourceColorRamp( NULL ),
160 mRotationFieldIdx( -1 ),
161 mSizeScaleFieldIdx( -1 )
175 for ( QgsRangeList::iterator it =
mRanges.begin(); it !=
mRanges.end(); ++it )
177 if ( it->lowerValue() <= value && it->upperValue() >= value )
187 if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
199 if ( symbol == NULL )
207 double sizeScale = 1;
223 markerSymbol->
setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->
size() );
230 lineSymbol->
setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
243 QgsRangeList::iterator it =
mRanges.begin();
244 for ( ; it !=
mRanges.end(); ++it )
246 it->symbol()->startRender( context, vlayer );
261 QgsRangeList::iterator it =
mRanges.begin();
262 for ( ; it !=
mRanges.end(); ++it )
263 it->symbol()->stopRender( context );
266 #if QT_VERSION < 0x40600
267 QMap<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 =
mTempSymbols.begin();
269 QHash<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 =
mTempSymbols.begin();
273 it2.value()->stopRender( context );
281 QSet<QString> attributes;
293 QgsRangeList::const_iterator range_it =
mRanges.constBegin();
294 for ( ; range_it !=
mRanges.constEnd(); ++range_it )
296 symbol = range_it->symbol();
302 return attributes.toList();
307 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
309 mRanges[rangeIndex].setSymbol( symbol );
315 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
317 mRanges[rangeIndex].setLabel( label );
323 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
325 mRanges[rangeIndex].setUpperValue( value );
331 if ( rangeIndex < 0 || rangeIndex >=
mRanges.size() )
333 mRanges[rangeIndex].setLowerValue( value );
339 QString s = QString(
"GRADUATED: attr %1\n" ).arg(
mAttrName );
340 for (
int i = 0; i <
mRanges.count(); i++ )
365 props[
"angle" ] = QString(
mRotationField ).append(
"\"" ).prepend(
"\"" );
367 props[
"scale" ] = QString(
mSizeScaleField ).append(
"\"" ).prepend(
"\"" );
370 for ( QgsRangeList::const_iterator it =
mRanges.constBegin(); it !=
mRanges.constEnd(); it++ )
373 it->toSld( doc, element, catProps );
380 for (
int i = 0; i <
mRanges.count(); i++ )
381 lst.append(
mRanges[i].symbol() );
393 double step = ( maximum - minimum ) / classes;
395 QList<double> breaks;
396 double value = minimum;
397 for (
int i = 0; i < classes; i++ )
400 breaks.append( value );
405 breaks[classes-1] = maximum;
424 QList<double> breaks;
426 int n = values.count();
427 double Xq = n > 0 ? values[0] : 0.0;
429 for (
int i = 1; i < classes; i++ )
433 double q = i / ( double ) classes;
434 double a = q * ( n - 1 );
435 int aa = ( int )( a );
438 Xq = ( 1 - r ) * values[aa] + r * values[aa+1];
443 breaks.append( values[ n-1 ] );
460 QList<double> breaks;
463 breaks.append( maximum );
467 int minimumCount = ( int ) classes / 3;
468 double shrink = 0.75;
469 double highBias = 1.5;
470 double adjustBias = 0.5 + 1.5 * highBias;
471 int divisions = classes;
476 double dx = maximum - minimum;
478 if ( dx == 0 && maximum == 0 )
486 cell = qMax( qAbs( minimum ), qAbs( maximum ) );
487 if ( adjustBias >= 1.5 * h + 0.5 )
489 U = 1 + ( 1.0 / ( 1 + h ) );
493 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
495 small = dx < ( cell * U * qMax( 1, divisions ) * 1e-07 * 3.0 );
502 cell = 9 + cell / 10;
503 cell = cell * shrink;
505 if ( minimumCount > 1 )
507 cell = cell / minimumCount;
515 cell = cell / divisions;
518 if ( cell < 20 * 1e-07 )
523 double base = pow( 10.0, floor( log10( cell ) ) );
525 if (( 2 * base ) - cell < h *( cell - unit ) )
528 if (( 5 * base ) - cell < adjustBias *( cell - unit ) )
531 if (( 10.0 * base ) - cell < h *( cell - unit ) )
538 int start = floor( minimum / unit + 1e-07 );
539 int end = ceil( maximum / unit - 1e-07 );
542 while ( start * unit > minimum + ( 1e-07 * unit ) )
546 while ( end * unit < maximum - ( 1e-07 * unit ) )
550 QgsDebugMsg( QString(
"pretty classes: %1" ).arg( end ) );
554 int k = floor( 0.5 + end - start );
555 if ( k < minimumCount )
557 k = minimumCount - k;
561 start = start - k / 2 + k % 2;
565 start = start - k / 2;
566 end = end + k / 2 + k % 2;
568 divisions = minimumCount;
574 double minimumBreak = start * unit;
576 int count = end - start;
578 for (
int i = 1; i < count + 1; i++ )
580 breaks.append( minimumBreak + i * unit );
583 if ( breaks.isEmpty() )
586 if ( breaks.first() < minimum )
590 if ( breaks.last() > maximum )
592 breaks[breaks.count()-1] = maximum;
611 int n = values.count();
612 double minimum = values[0];
613 double maximum = values[0];
615 for (
int i = 0; i < n; i++ )
618 minimum = qMin( values[i], minimum );
619 maximum = qMax( values[i], maximum );
621 mean = mean / ( double ) n;
624 for (
int i = 0; i < n; i++ )
626 sd = values[i] - mean;
629 stdDev = sqrt( stdDev / n );
631 QList<double> breaks =
_calcPrettyBreaks(( minimum - mean ) / stdDev, ( maximum - mean ) / stdDev, classes );
632 for (
int i = 0; i < breaks.count(); i++ )
634 labels.append((
int ) breaks[i] );
635 breaks[i] = ( breaks[i] * stdDev ) + mean;
642 double minimum,
double maximum,
643 int maximumSize = 1000 )
657 return QList<double>() << maximum;
660 if ( classes >= values.size() )
665 QVector<double> sample;
668 if ( values.size() > maximumSize )
676 sample.resize( qMax( maximumSize, values.size() / 10 ) );
678 QgsDebugMsg( QString(
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ) );
679 QgsDebugMsg( QString(
"values:%1" ).arg( values.size() ) );
681 sample[ 0 ] = minimum;
682 sample[ 1 ] = maximum;;
683 for (
int i = 2; i < sample.size(); i++ )
687 int j = floor( r / RAND_MAX * ( values.size() - 1 ) );
688 sample[ i ] = values[ j ];
693 sample = values.toVector();
696 int n = sample.size();
701 QVector< QVector<int> > matrixOne( n + 1 );
702 QVector< QVector<double> > matrixTwo( n + 1 );
704 for (
int i = 0; i <= n; i++ )
706 matrixOne[i].resize( classes + 1 );
707 matrixTwo[i].resize( classes + 1 );
710 for (
int i = 1; i <= classes; i++ )
714 matrixTwo[0][i] = 0.0;
715 for (
int j = 2; j <= n; j++ )
721 for (
int l = 2; l <= n; l++ )
729 for (
int m = 1; m <= l; m++ )
733 double val = sample[ i3 - 1 ];
739 v = s2 - ( s1 * s1 ) / (
double ) w;
743 for (
int j = 2; j <= classes; j++ )
745 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
747 matrixOne[l][j] = i4;
748 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
757 QVector<double> breaks( classes );
758 breaks[classes-1] = sample[n-1];
760 for (
int j = classes, k = n; j >= 2; j-- )
762 int id = matrixOne[k][j] - 1;
763 breaks[j - 2] = sample[id];
764 k = matrixOne[k][j] - 1;
767 return breaks.toList();
784 double minimum = vlayer->
minimumValue( attrNum ).toDouble();
785 double maximum = vlayer->
maximumValue( attrNum ).toDouble();
786 QgsDebugMsg( QString(
"min %1 // max %2" ).arg( minimum ).arg( maximum ) );
788 QList<double> breaks;
794 else if ( mode ==
Pretty )
801 QList<double> values;
804 lst.append( attrNum );
811 values.append( f.
attribute( attrNum ).toDouble() );
818 else if ( mode ==
Jenks )
822 else if ( mode ==
StdDev )
833 double lower, upper = minimum;
838 for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
846 label =
"< " + QString::number( labels[i],
'i', 0 ) +
" Std Dev";
848 else if ( i == labels.count() - 1 )
850 label =
">= " + QString::number( labels[i-1],
'i', 0 ) +
" Std Dev";
854 label = QString::number( labels[i-1],
'i', 0 ) +
" Std Dev" +
" - " + QString::number( labels[i],
'i', 0 ) +
" Std Dev";
859 label = QString::number( lower,
'f', 4 ) +
" - " + QString::number( upper,
'f', 4 );
863 double colorValue = ( breaks.count() > 1 ? ( double ) i / ( breaks.count() - 1 ) : 0 );
878 QDomElement symbolsElem = element.firstChildElement(
"symbols" );
879 if ( symbolsElem.isNull() )
882 QDomElement rangesElem = element.firstChildElement(
"ranges" );
883 if ( rangesElem.isNull() )
889 QDomElement rangeElem = rangesElem.firstChildElement();
890 while ( !rangeElem.isNull() )
892 if ( rangeElem.tagName() ==
"range" )
894 double lowerValue = rangeElem.attribute(
"lower" ).toDouble();
895 double upperValue = rangeElem.attribute(
"upper" ).toDouble();
896 QString symbolName = rangeElem.attribute(
"symbol" );
897 QString label = rangeElem.attribute(
"label" );
898 if ( symbolMap.contains( symbolName ) )
900 QgsSymbolV2* symbol = symbolMap.take( symbolName );
904 rangeElem = rangeElem.nextSiblingElement();
907 QString attrName = element.attribute(
"attr" );
915 QDomElement sourceSymbolElem = element.firstChildElement(
"source-symbol" );
916 if ( !sourceSymbolElem.isNull() )
919 if ( sourceSymbolMap.contains(
"0" ) )
927 QDomElement sourceColorRampElem = element.firstChildElement(
"colorramp" );
928 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute(
"name" ) ==
"[source]" )
934 QDomElement modeElem = element.firstChildElement(
"mode" );
935 if ( !modeElem.isNull() )
937 QString modeString = modeElem.attribute(
"name" );
938 if ( modeString ==
"equal" )
940 else if ( modeString ==
"quantile" )
942 else if ( modeString ==
"jenks" )
944 else if ( modeString ==
"stddev" )
946 else if ( modeString ==
"pretty" )
950 QDomElement rotationElem = element.firstChildElement(
"rotation" );
951 if ( !rotationElem.isNull() )
954 QDomElement sizeScaleElem = element.firstChildElement(
"sizescale" );
955 if ( !sizeScaleElem.isNull() )
968 rendererElem.setAttribute(
"type",
"graduatedSymbol" );
970 rendererElem.setAttribute(
"attr",
mAttrName );
975 QDomElement rangesElem = doc.createElement(
"ranges" );
976 QgsRangeList::const_iterator it =
mRanges.constBegin();
977 for ( ; it !=
mRanges.constEnd(); it++ )
980 QString symbolName = QString::number( i );
981 symbols.insert( symbolName, range.
symbol() );
983 QDomElement rangeElem = doc.createElement(
"range" );
984 rangeElem.setAttribute(
"lower", QString::number( range.
lowerValue(),
'f' ) );
985 rangeElem.setAttribute(
"upper", QString::number( range.
upperValue(),
'f' ) );
986 rangeElem.setAttribute(
"symbol", symbolName );
987 rangeElem.setAttribute(
"label", range.
label() );
988 rangesElem.appendChild( rangeElem );
992 rendererElem.appendChild( rangesElem );
996 rendererElem.appendChild( symbolsElem );
1004 rendererElem.appendChild( sourceSymbolElem );
1011 rendererElem.appendChild( colorRampElem );
1017 modeString =
"equal";
1019 modeString =
"quantile";
1021 modeString =
"jenks";
1023 modeString =
"stddev";
1025 modeString =
"pretty";
1026 if ( !modeString.isEmpty() )
1028 QDomElement modeElem = doc.createElement(
"mode" );
1029 modeElem.setAttribute(
"name", modeString );
1030 rendererElem.appendChild( modeElem );
1033 QDomElement rotationElem = doc.createElement(
"rotation" );
1035 rendererElem.appendChild( rotationElem );
1037 QDomElement sizeScaleElem = doc.createElement(
"sizescale" );
1040 rendererElem.appendChild( sizeScaleElem );
1042 return rendererElem;
1048 bool showClassifiers = settings.value(
"/qgis/showLegendClassifiers",
false ).toBool();
1051 if ( showClassifiers )
1056 int count =
ranges().count();
1057 for (
int i = 0; i < count; i++ )
1061 lst << qMakePair( range.
label(), pix );
1069 bool showClassifiers = settings.value(
"/qgis/showLegendClassifiers",
false ).toBool();
1072 if ( showClassifiers )
1088 lst << qMakePair( range.
label(), symbol );
1119 double colorValue = (
mRanges.count() > 1 ? ( double ) i / (
mRanges.count() - 1 ) : 0 );
1152 QString label =
"0.0 - 0.0";
1169 if ( from < 0 || from >=
mRanges.size() || to < 0 || to >=
mRanges.size() )
return;
1186 if ( order == Qt::AscendingOrder )
1198 return QString::localeAwareCompare( r1.
label(), r2.
label() ) < 0;
1208 if ( order == Qt::AscendingOrder )