QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsclassificationstandarddeviation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsclassificationstandarddeviation.h
3  ---------------------
4  begin : September 2019
5  copyright : (C) 2019 by Denis Rouzaud
6  email : [email protected]
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 #include <QObject>
17 
20 #include "qgsapplication.h"
21 
22 const QString QgsClassificationStandardDeviation::METHOD_ID = QStringLiteral( "StdDev" );
23 
24 
26  : QgsClassificationMethod( SymmetricModeAvailable )
27 {
28 
29 }
30 
32 {
33  return QObject::tr( "Standard Deviation" );
34 }
35 
37 {
38  return METHOD_ID;
39 }
40 
42 {
44  copyBase( c );
45  c->mStdDev = mStdDev;
46  return c;
47 }
48 
50 {
51  return QgsApplication::getThemeIcon( "classification_methods/mClassificationStandardDeviation.svg" );
52 }
53 
54 
55 QList<double> QgsClassificationStandardDeviation::calculateBreaks( double &minimum, double &maximum,
56  const QList<double> &values, int nclasses )
57 {
58  // C++ implementation of the standard deviation class interval algorithm
59  // as implemented in the 'classInt' package available for the R statistical
60  // prgramming language.
61 
62  // Returns breaks based on 'prettyBreaks' of the centred and scaled
63  // values of 'values', and may have a number of classes different from 'classes'.
64 
65  // If there are no values to process: bail out
66  if ( values.isEmpty() )
67  return QList<double>();
68 
69  double mean = 0.0;
70  mStdDev = 0.0;
71  int n = values.count();
72 
73  for ( int i = 0; i < n; i++ )
74  {
75  mean += values[i];
76  }
77  mean = mean / static_cast< double >( n );
78 
79  double sd = 0.0;
80  for ( int i = 0; i < n; i++ )
81  {
82  sd = values[i] - mean;
83  mStdDev += sd * sd;
84  }
85  mStdDev = std::sqrt( mStdDev / n );
86 
87  // if not symmetric, the symmetry point is the mean
88  mEffectiveSymmetryPoint = symmetricModeEnabled() ? symmetryPoint() : mean;
89 
90  QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( ( minimum - mEffectiveSymmetryPoint ) / mStdDev, ( maximum - mEffectiveSymmetryPoint ) / mStdDev, nclasses );
91  makeBreaksSymmetric( breaks, 0.0, symmetryAstride() ); //0.0 because breaks where computed on a centered distribution
92 
93  for ( int i = 0; i < breaks.count(); i++ )
94  breaks[i] = ( breaks[i] * mStdDev ) + mEffectiveSymmetryPoint;
95 
96  return breaks;
97 }
98 
99 QString QgsClassificationStandardDeviation::labelForRange( const double lowerValue, const double upperValue, QgsClassificationMethod::ClassPosition position ) const
100 {
101  const QString lowerLabel = valueToLabel( lowerValue );
102  const QString upperLabel = valueToLabel( upperValue );
103 
104  switch ( position )
105  {
106  case LowerBound:
107  return QStringLiteral( "< %1" ).arg( upperLabel );
108  case Inner:
109  {
110  QString label( labelFormat() );
111  label.replace( QLatin1String( "%1" ), lowerLabel ).replace( QLatin1String( "%2" ), upperLabel );
112  return label;
113  }
114  case UpperBound:
115  return QStringLiteral( "≥ %1" ).arg( lowerLabel );
116  }
117  return QString();
118 }
119 
120 
121 QString QgsClassificationStandardDeviation::valueToLabel( const double value ) const
122 {
123  double normalized = ( value - mEffectiveSymmetryPoint ) / mStdDev;
124  return QObject::tr( " %1 Std Dev" ).arg( QString::number( normalized, 'f', 2 ) );
125 }
126 
127 
128 void QgsClassificationStandardDeviation::writeXml( QDomElement &element, const QgsReadWriteContext &context ) const
129 {
130  Q_UNUSED( context )
131 
132  element.setAttribute( QStringLiteral( "std_dev" ), QString::number( mStdDev, 'f', 16 ) );
133  element.setAttribute( QStringLiteral( "effective_symmetry_point" ), QString::number( mEffectiveSymmetryPoint, 'f', 16 ) );
134 }
135 
136 void QgsClassificationStandardDeviation::readXml( const QDomElement &element, const QgsReadWriteContext &context )
137 {
138  Q_UNUSED( context )
139 
140  mStdDev = element.attribute( QStringLiteral( "std_dev" ), QStringLiteral( "1.0" ) ).toDouble();
141  mEffectiveSymmetryPoint = element.attribute( QStringLiteral( "effective_symmetry_point" ), QStringLiteral( "0.0" ) ).toDouble();
142 }
QgsClassificationStandardDeviation::readXml
void readXml(const QDomElement &element, const QgsReadWriteContext &context) override
Reads extra information to apply it to the method.
Definition: qgsclassificationstandarddeviation.cpp:136
QgsClassificationMethod
QgsClassificationMethod is an abstract class for implementations of classification methods.
Definition: qgsclassificationmethod.h:88
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:626
qgsclassificationstandarddeviation.h
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:35
QgsClassificationMethod::UpperBound
@ UpperBound
The class is at the upper bound.
Definition: qgsclassificationmethod.h:124
QgsClassificationMethod::symmetryAstride
bool symmetryAstride() const
Returns if the symmetric mode is astride if true, it will remove the symmetry point break so that the...
Definition: qgsclassificationmethod.h:194
QgsClassificationStandardDeviation::METHOD_ID
static const QString METHOD_ID
Definition: qgsclassificationstandarddeviation.h:41
QgsClassificationStandardDeviation::clone
QgsClassificationMethod * clone() const override
Returns a clone of the method.
Definition: qgsclassificationstandarddeviation.cpp:41
QgsClassificationStandardDeviation::writeXml
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const override
Writes extra information about the method.
Definition: qgsclassificationstandarddeviation.cpp:128
qgsapplication.h
QgsClassificationStandardDeviation::QgsClassificationStandardDeviation
QgsClassificationStandardDeviation()
Definition: qgsclassificationstandarddeviation.cpp:25
QgsClassificationMethod::symmetryPoint
double symmetryPoint() const
Returns the symmetry point for symmetric mode.
Definition: qgsclassificationmethod.h:188
QgsClassificationMethod::LowerBound
@ LowerBound
The class is at the lower bound.
Definition: qgsclassificationmethod.h:122
QgsClassificationMethod::symmetricModeEnabled
bool symmetricModeEnabled() const
Returns if the symmetric mode is enabled.
Definition: qgsclassificationmethod.h:183
QgsClassificationStandardDeviation::id
QString id() const override
The id of the method as saved in the project, must be unique in registry.
Definition: qgsclassificationstandarddeviation.cpp:36
QgsClassificationStandardDeviation::name
QString name() const override
The readable and translate name of the method.
Definition: qgsclassificationstandarddeviation.cpp:31
QgsClassificationStandardDeviation::icon
QIcon icon() const override
The icon of the method.
Definition: qgsclassificationstandarddeviation.cpp:49
QgsSymbolLayerUtils::prettyBreaks
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
Definition: qgssymbollayerutils.cpp:4266
QgsClassificationMethod::copyBase
void copyBase(QgsClassificationMethod *c) const
Copy the parameters (shall be used in clone implementation)
Definition: qgsclassificationmethod.cpp:52
QgsClassificationMethod::Inner
@ Inner
The class is not at a bound.
Definition: qgsclassificationmethod.h:123
QgsClassificationMethod::labelFormat
QString labelFormat() const
Returns the format of the label for the classes.
Definition: qgsclassificationmethod.h:207
QgsClassificationMethod::makeBreaksSymmetric
static void makeBreaksSymmetric(QList< double > &breaks, double symmetryPoint, bool astride)
Remove the breaks that are above the existing opposite sign classes to keep colors symmetrically bala...
Definition: qgsclassificationmethod.cpp:298
c
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
Definition: porting_processing.dox:1
QgsClassificationMethod::ClassPosition
ClassPosition
Defines the class position.
Definition: qgsclassificationmethod.h:121
QgsClassificationStandardDeviation
QgsClassificationCustom is an implementation of QgsClassificationMethod based on standard deviation.
Definition: qgsclassificationstandarddeviation.h:29
qgsgraduatedsymbolrenderer.h
QgsClassificationStandardDeviation::labelForRange
QString labelForRange(double lowerValue, double upperValue, ClassPosition position) const override
Returns the label for a range.
Definition: qgsclassificationstandarddeviation.cpp:99