Branch data Line data Source code
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 : : 20 : 5 : QgsClassificationQuantile::QgsClassificationQuantile() 21 : 5 : : QgsClassificationMethod() 22 : 10 : { 23 : 5 : } 24 : : 25 : 0 : QString QgsClassificationQuantile::name() const 26 : : { 27 : 0 : return QObject::tr( "Equal Count (Quantile)" ); 28 : : } 29 : : 30 : 10 : QString QgsClassificationQuantile::id() const 31 : : { 32 : 20 : return QStringLiteral( "Quantile" ); 33 : : } 34 : : 35 : 0 : QgsClassificationMethod *QgsClassificationQuantile::clone() const 36 : : { 37 : 0 : QgsClassificationQuantile *c = new QgsClassificationQuantile(); 38 : 0 : copyBase( c ); 39 : 0 : return c; 40 : 0 : } 41 : : 42 : 0 : QIcon QgsClassificationQuantile::icon() const 43 : : { 44 : 0 : return QgsApplication::getThemeIcon( "classification_methods/mClassificationEqualCount.svg" ); 45 : 0 : } 46 : : 47 : : 48 : 0 : QList<double> QgsClassificationQuantile::calculateBreaks( double &minimum, double &maximum, 49 : : const QList<double> &values, int nclasses ) 50 : : { 51 : 0 : Q_UNUSED( minimum ) 52 : 0 : 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 : 0 : QList<double> _values = values; 64 : 0 : std::sort( _values.begin(), _values.end() ); 65 : : 66 : 0 : QList<double> breaks; 67 : : 68 : : // If there are no values to process: bail out 69 : 0 : if ( _values.isEmpty() ) 70 : 0 : return QList<double>(); 71 : : 72 : 0 : int n = _values.count(); 73 : 0 : double Xq = n > 0 ? _values[0] : 0.0; 74 : : 75 : 0 : breaks.reserve( nclasses ); 76 : 0 : for ( int i = 1; i < nclasses; i++ ) 77 : : { 78 : 0 : if ( n > 1 ) 79 : : { 80 : 0 : double q = i / static_cast< double >( nclasses ); 81 : 0 : double a = q * ( n - 1 ); 82 : 0 : int aa = static_cast< int >( a ); 83 : : 84 : 0 : double r = a - aa; 85 : 0 : Xq = ( 1 - r ) * _values[aa] + r * _values[aa + 1]; 86 : 0 : } 87 : 0 : breaks.append( Xq ); 88 : 0 : } 89 : : 90 : 0 : breaks.append( _values[ n - 1 ] ); 91 : : 92 : 0 : return breaks; 93 : 0 : } 94 : :