22#include <QRandomGenerator>
25using namespace Qt::StringLiterals;
35 return QObject::tr(
"Natural Breaks (Jenks)" );
45 auto c = std::make_unique< QgsClassificationJenks >();
56QList<double> QgsClassificationJenks::calculateBreaks(
double &minimum,
double &maximum,
57 const QList<double> &values,
int nclasses, QString &error )
70 if ( values.isEmpty() )
71 return QList<double>();
75 return QList<double>() << maximum;
78 if ( nclasses >= values.size() )
83 QVector<double> sample;
84 QVector<double> sorted;
87 if ( values.size() > mMaximumSize )
93 sample.resize( std::max( mMaximumSize,
static_cast<int>( values.size() ) / 10 ) );
95 QgsDebugMsgLevel( u
"natural breaks (jenks) sample size: %1"_s.arg( sample.size() ), 2 );
98 sample[ 0 ] = minimum;
99 sample[ 1 ] = maximum;
101 sorted = values.toVector();
102 std::sort( sorted.begin(), sorted.end() );
110 for (
int i = 1; i < sorted.size() - 2; i++ )
112 if ( ( i * ( mMaximumSize - 2 ) / ( sorted.size() - 2 ) ) > j )
115 sample[ j + 2 ] = sorted[ i ];
121 sample = values.toVector();
124 const int n = sample.size();
127 std::sort( sample.begin(), sample.end() );
129 QVector< QVector<int> > matrixOne( n + 1 );
130 QVector< QVector<double> > matrixTwo( n + 1 );
132 for (
int i = 0; i <= n; i++ )
134 matrixOne[i].resize( nclasses + 1 );
135 matrixTwo[i].resize( nclasses + 1 );
138 for (
int i = 1; i <= nclasses; i++ )
142 matrixTwo[0][i] = 0.0;
143 for (
int j = 2; j <= n; j++ )
145 matrixTwo[j][i] = std::numeric_limits<double>::max();
149 for (
int l = 2; l <= n; l++ )
157 for (
int m = 1; m <= l; m++ )
159 const int i3 = l - m + 1;
161 const double val = sample[ i3 - 1 ];
167 v = s2 - ( s1 * s1 ) /
static_cast< double >( w );
168 const int i4 = i3 - 1;
171 for (
int j = 2; j <= nclasses; j++ )
173 if ( matrixTwo[l][j] >= v + matrixTwo[i4][j - 1] )
175 matrixOne[l][j] = i4;
176 matrixTwo[l][j] = v + matrixTwo[i4][j - 1];
185 QVector<double> breaks( nclasses );
186 breaks[nclasses - 1] = sample[n - 1];
188 for (
int j = nclasses, k = n; j >= 2; j-- )
190 const int id = matrixOne[k][j] - 1;
191 breaks[j - 2] = sample[
id];
192 k = matrixOne[k][j] - 1;
195 return breaks.toList();
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QIcon icon() const override
The icon of the method.
QString name() const override
The readable and translate name of the method.
std::unique_ptr< QgsClassificationMethod > clone() const override
Returns a clone of the method.
QString id() const override
The id of the method as saved in the project, must be unique in registry.
QgsClassificationMethod(MethodProperties properties=NoFlag, int codeComplexity=1)
Creates a classification method.
void copyBase(QgsClassificationMethod *c) const
Copy the parameters (shall be used in clone implementation).
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
#define QgsDebugMsgLevel(str, level)