1 /*************************************************************************** 2 qgsclassificationquantile.h 3 --------------------- 4 begin : September 2019 5 copyright : (C) 2019 by Denis Rouzaud 6 email : denis@opengis.ch 7 *************************************************************************** 8 * * 9 * This program is free software; you can redistribute it and/or modify * 10 * it under the terms of the GNU General Public License as published by * 11 * the Free Software Foundation; either version 2 of the License, or * 12 * (at your option) any later version. * 13 * * 14 ***************************************************************************/ 15 16 17 #include "qgsclassificationquantile.h" 18 #include "qgsapplication.h" 19 QgsClassificationQuantile()20QgsClassificationQuantile::QgsClassificationQuantile() 21 : QgsClassificationMethod() 22 { 23 } 24 name() const25QString QgsClassificationQuantile::name() const 26 { 27 return QObject::tr( "Equal Count (Quantile)" ); 28 } 29 id() const30QString QgsClassificationQuantile::id() const 31 { 32 return QStringLiteral( "Quantile" ); 33 } 34 clone() const35QgsClassificationMethod *QgsClassificationQuantile::clone() const 36 { 37 QgsClassificationQuantile *c = new QgsClassificationQuantile(); 38 copyBase( c ); 39 return c; 40 } 41 icon() const42QIcon QgsClassificationQuantile::icon() const 43 { 44 return QgsApplication::getThemeIcon( "classification_methods/mClassificationEqualCount.svg" ); 45 } 46 47 calculateBreaks(double & minimum,double & maximum,const QList<double> & values,int nclasses)48QList<double> QgsClassificationQuantile::calculateBreaks( double &minimum, double &maximum, 49 const QList<double> &values, int nclasses ) 50 { 51 Q_UNUSED( minimum ) 52 Q_UNUSED( maximum ) 53 54 // q-th quantile of a data set: 55 // value where q fraction of data is below and (1-q) fraction is above this value 56 // Xq = (1 - r) * X_NI1 + r * X_NI2 57 // NI1 = (int) (q * (n+1)) 58 // NI2 = NI1 + 1 59 // r = q * (n+1) - (int) (q * (n+1)) 60 // (indices of X: 1...n) 61 62 // sort the values first 63 QList<double> _values = values; 64 std::sort( _values.begin(), _values.end() ); 65 66 QList<double> breaks; 67 68 // If there are no values to process: bail out 69 if ( _values.isEmpty() ) 70 return QList<double>(); 71 72 const int n = _values.count(); 73 double Xq = n > 0 ? _values[0] : 0.0; 74 75 breaks.reserve( nclasses ); 76 for ( int i = 1; i < nclasses; i++ ) 77 { 78 if ( n > 1 ) 79 { 80 const double q = i / static_cast< double >( nclasses ); 81 const double a = q * ( n - 1 ); 82 const int aa = static_cast< int >( a ); 83 84 const double r = a - aa; 85 Xq = ( 1 - r ) * _values[aa] + r * _values[aa + 1]; 86 } 87 breaks.append( Xq ); 88 } 89 90 breaks.append( _values[ n - 1 ] ); 91 92 return breaks; 93 } 94 95