QGIS API Documentation  3.12.1-BucureČ™ti (121cc00ff0)
qgsclassificationlogarithmic.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsclassificationlogarithmic.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 
19 #include "qgssymbollayerutils.h"
20 #include "qgsapplication.h"
21 #include "qgsprocessingcontext.h"
22 
23 
25  : QgsClassificationMethod( NoFlag, 0 )
26 {
27  QgsProcessingParameterEnum *param = new QgsProcessingParameterEnum( QStringLiteral( "ZERO_NEG_VALUES_HANDLE" ), QObject::tr( "Handling of 0 or negative values" ), QStringList() << QObject::tr( "no handling (faster)" ) << QObject::tr( "discard (slower)" ) << QObject::tr( "prepend range (slower)" ), false, 0 );
28  addParameter( param );
29 }
30 
31 
33 {
35  copyBase( c );
36  return c;
37 }
38 
40 {
41  return QObject::tr( "Logarithmic scale" );
42 }
43 
45 {
46  return QStringLiteral( "Logarithmic" );
47 }
48 
50 {
51  return QgsApplication::getThemeIcon( "classification_methods/mClassificationLogarithmic.svg" );
52 }
53 
54 QList<double> QgsClassificationLogarithmic::calculateBreaks( double &minimum, double &maximum, const QList<double> &values, int nclasses )
55 {
56  QgsProcessingContext context;
57  const QgsProcessingParameterDefinition *def = parameterDefinition( QStringLiteral( "ZERO_NEG_VALUES_HANDLE" ) );
59 
60  double positiveMinimum = std::numeric_limits<double>::max();
61  if ( nvh != NegativeValueHandling::NoHandling && minimum <= 0 )
62  {
63  Q_ASSERT( values.count() );
64  if ( maximum > 0 )
65  {
66  for ( int i = 0; i < values.count(); i++ )
67  {
68  if ( values.at( i ) > 0 )
69  positiveMinimum = std::min( positiveMinimum, values.at( i ) );
70  }
71  }
72  if ( positiveMinimum == std::numeric_limits<double>::max() )
73  {
74  // there is no usable values
75  if ( nvh == NegativeValueHandling::PrependBreak )
76  return QList<double>( {0} );
77  else
78  return QList<double>();
79  }
80  }
81 
82  QList<double> breaks;
83 
84  if ( positiveMinimum != std::numeric_limits<double>::max() )
85  {
86  if ( nvh == NegativeValueHandling::PrependBreak )
87  breaks << std::floor( std::log10( positiveMinimum ) );
88  else if ( nvh == NegativeValueHandling::Discard )
89  minimum = positiveMinimum; // the minimum gets updated
90  }
91  else
92  {
93  positiveMinimum = minimum;
94  }
95 
96  // get the min/max in log10 scale
97  double logMin = std::floor( std::log10( positiveMinimum ) );
98  double logMax = std::ceil( std::log10( maximum ) );
99 
100  // calculate pretty breaks
101  breaks.append( QgsSymbolLayerUtils::prettyBreaks( logMin, logMax, nclasses ) );
102 
103  // create the value
104  for ( int i = 0; i < breaks.count(); i++ )
105  breaks[i] = std::pow( 10, breaks.at( i ) );
106 
107  return breaks;
108 }
109 
110 QString QgsClassificationLogarithmic::valueToLabel( double value ) const
111 {
112  if ( value <= 0 )
113  return QString( QStringLiteral( "%1" ) ).arg( value );
114  else
115  return QString( QStringLiteral( "10^%1" ) ).arg( std::log10( value ) );
116 }
117 
118 QString QgsClassificationLogarithmic::labelForRange( double lowerValue, double upperValue, QgsClassificationMethod::ClassPosition position ) const
119 {
120  QString lowerLabel;
121  const QString upperLabel = valueToLabel( upperValue );
122 
123  switch ( position )
124  {
125  case LowerBound:
126  lowerLabel = formatNumber( lowerValue ); // avoid to have float exponent for the minimum value
127  break;
128  case Inner:
129  case UpperBound:
130  lowerLabel = valueToLabel( lowerValue );
131  break;
132  }
133 
134  return labelFormat().arg( lowerLabel ).arg( upperLabel );
135 }
136 
138 {
139  QgsProcessingContext context;
140  const QgsProcessingParameterDefinition *def = parameterDefinition( QStringLiteral( "ZERO_NEG_VALUES_HANDLE" ) );
142 
143  return nvh != NegativeValueHandling::NoHandling;
144 }
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
QString formatNumber(double value) const
Format the number according to label properties.
bool valuesRequired() const override
Returns if the method requires values to calculate the classes If not, bounds are sufficient...
NegativeValueHandling
Handling of negative and 0 values in the method.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &parameterName) const
Returns the parameter from its name.
QString id() const override
The id of the method as saved in the project, must be unique in registry.
QIcon icon() const override
The icon of the method.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
The class is not at a bound.
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
The class is at the upper bound.
void addParameter(QgsProcessingParameterDefinition *definition)
Add a parameter to the method.
QString labelForRange(double lowerValue, double upperValue, ClassPosition position) const override
Returns the label for a range.
The class is at the lower bound.
An enum based parameter for processing algorithms, allowing for selection from predefined values...
void copyBase(QgsClassificationMethod *c) const
Copy the parameters (shall be used in clone implementation)
QString labelFormat() const
Returns the format of the label for the classes.
QgsClassificationMethod * clone() const override
Returns a clone of the method.
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about &#39;classes&#39; equally spaced round values which cover the range of values fr...
QString name() const override
The readable and translate name of the method.
Base class for the definition of processing parameters.
QVariantMap parameterValues() const
Returns the values of the processing parameters.
ClassPosition
Defines the class position.
Contains information about the context in which a processing algorithm is executed.
QgsClassificationMethod is an abstract class for implementations of classification methods...
Implementation of a logarithmic scale method.