28 return QObject::tr(
"Natural Breaks (Jenks)" );
33 return QStringLiteral(
"Jenks" );
49 QList<double> QgsClassificationJenks::calculateBreaks(
double &minimum,
double &maximum,
50 const QList<double> &values,
int nclasses )
62 if ( values.isEmpty() )
63 return QList<double>();
67 return QList<double>() << maximum;
70 if ( nclasses >= values.size() )
75 QVector<double> sample;
78 if ( values.size() > mMaximumSize )
84 sample.resize( std::max( mMaximumSize, values.size() / 10 ) );
86 QgsDebugMsgLevel( QStringLiteral(
"natural breaks (jenks) sample size: %1" ).arg( sample.size() ), 2 );
89 sample[ 0 ] = minimum;
90 sample[ 1 ] = maximum;
91 for (
int i = 2; i < sample.size(); i++ )
95 int j = std::floor( r / RAND_MAX * ( values.size() - 1 ) );
96 sample[ i ] = values[ j ];
101 sample = values.toVector();
104 int n = sample.size();
107 std::sort( sample.begin(), sample.end() );
109 QVector< QVector<int> > matrixOne( n + 1 );
110 QVector< QVector<double> > matrixTwo( n + 1 );
112 for (
int i = 0; i <= n; i++ )
114 matrixOne[i].resize( nclasses + 1 );
115 matrixTwo[i].resize( nclasses + 1 );
118 for (
int i = 1; i <= nclasses; i++ )
122 matrixTwo[0][i] = 0.0;
123 for (
int j = 2; j <= n; j++ )
125 matrixTwo[j][i] = std::numeric_limits<double>::max();
129 for (
int l = 2; l <= n; l++ )
137 for (
int m = 1; m <= l; m++ )
141 double val = sample[ i3 - 1 ];
147 v = s2 - ( s1 * s1 ) /
static_cast< double >( w );
151 for (
int j = 2; j <= nclasses; j++ )
153 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
155 matrixOne[l][j] = i4;
156 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
165 QVector<double> breaks( nclasses );
166 breaks[nclasses - 1] = sample[n - 1];
168 for (
int j = nclasses, k = n; j >= 2; j-- )
170 int id = matrixOne[k][j] - 1;
171 breaks[j - 2] = sample[
id];
172 k = matrixOne[k][j] - 1;
175 return breaks.toList();