QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
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
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
17
18#include "qgsapplication.h"
20#include "qgssymbollayerutils.h"
21
22#include <QObject>
23#include <QString>
24
25using namespace Qt::StringLiterals;
26
29{
31 u"ZERO_NEG_VALUES_HANDLE"_s,
32 QObject::tr( "Handling of 0 or negative values" ),
33 QStringList() << QObject::tr( "no handling (faster)" ) << QObject::tr( "discard (slower)" ) << QObject::tr( "prepend range (slower)" ),
34 false,
35 0
36 );
37 addParameter( param );
38}
39
40
41std::unique_ptr<QgsClassificationMethod> QgsClassificationLogarithmic::clone() const
42{
43 auto c = std::make_unique< QgsClassificationLogarithmic >();
44 copyBase( c.get() );
45 return c;
46}
47
49{
50 return QObject::tr( "Logarithmic Scale" );
51}
52
54{
55 return u"Logarithmic"_s;
56}
57
59{
60 return QgsApplication::getThemeIcon( "classification_methods/mClassificationLogarithmic.svg" );
61}
62
63QList<double> QgsClassificationLogarithmic::calculateBreaks( double &minimum, double &maximum, const QList<double> &values, int nclasses, QString &error )
64{
65 Q_UNUSED( error )
66 const QgsProcessingContext context;
67 const QgsProcessingParameterDefinition *def = parameterDefinition( u"ZERO_NEG_VALUES_HANDLE"_s );
69
70 double positiveMinimum = std::numeric_limits<double>::max();
71 if ( nvh != NegativeValueHandling::NoHandling && minimum <= 0 )
72 {
73 Q_ASSERT( values.count() );
74 if ( maximum > 0 )
75 {
76 for ( int i = 0; i < values.count(); i++ )
77 {
78 if ( values.at( i ) > 0 )
79 positiveMinimum = std::min( positiveMinimum, values.at( i ) );
80 }
81 }
82 if ( positiveMinimum == std::numeric_limits<double>::max() )
83 {
84 // there is no usable values
86 return QList<double>( { 0 } );
87 else
88 return QList<double>();
89 }
90 }
91
92 QList<double> breaks;
93
94 if ( positiveMinimum != std::numeric_limits<double>::max() )
95 {
97 breaks << std::floor( std::log10( positiveMinimum ) );
98 else if ( nvh == NegativeValueHandling::Discard )
99 minimum = positiveMinimum; // the minimum gets updated
100 }
101 else
102 {
103 positiveMinimum = minimum;
104 }
105
106 // get the min/max in log10 scale
107 const double actualLogMin { std::log10( positiveMinimum ) };
108 double logMin = std::floor( actualLogMin );
109 const double logMax = std::ceil( std::log10( maximum ) );
110
111 // calculate pretty breaks
112 QList<double> prettyBreaks { QgsSymbolLayerUtils::prettyBreaks( logMin, logMax, nclasses ) };
113
114 // If case the first class greater than the actual log min increase the minimum log
115 while ( !prettyBreaks.isEmpty() && prettyBreaks.first() < actualLogMin )
116 {
117 logMin += 1.0;
118 prettyBreaks = QgsSymbolLayerUtils::prettyBreaks( logMin, logMax, nclasses );
119 }
120
121 breaks.append( prettyBreaks );
122
123 // create the value
124 for ( int i = 0; i < breaks.count(); i++ )
125 {
126 breaks[i] = std::pow( 10, breaks.at( i ) );
127 }
128
129 return breaks;
130}
131
132QString QgsClassificationLogarithmic::valueToLabel( double value ) const
133{
134 if ( value <= 0 )
135 {
136 return QLocale().toString( value );
137 }
138 else
139 {
140 if ( std::isnan( value ) )
141 {
142 return QObject::tr( "invalid (0 or negative values in the data)" );
143 }
144 else
145 {
146 return QString( u"10^%L1"_s ).arg( std::log10( value ) );
147 }
148 }
149}
150
151QString QgsClassificationLogarithmic::labelForRange( double lowerValue, double upperValue, QgsClassificationMethod::ClassPosition position ) const
152{
153 QString lowerLabel;
154 const QString upperLabel = valueToLabel( upperValue );
155
156 switch ( position )
157 {
158 case LowerBound:
159 lowerLabel = formatNumber( lowerValue ); // avoid to have float exponent for the minimum value
160 break;
161 case Inner:
162 case UpperBound:
163 lowerLabel = valueToLabel( lowerValue );
164 break;
165 }
166
167 return labelFormat().arg( lowerLabel, upperLabel );
168}
169
171{
172 const QgsProcessingContext context;
173 const QgsProcessingParameterDefinition *def = parameterDefinition( u"ZERO_NEG_VALUES_HANDLE"_s );
175
177}
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
std::unique_ptr< QgsClassificationMethod > clone() const override
Returns a clone of the method.
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.
@ PrependBreak
Prepend an extra break to include negative values - this will require all values.
@ Discard
Negative values are discarded - this will require all values.
QString labelForRange(double lowerValue, double upperValue, ClassPosition position) const override
Returns the label for a range.
QString id() const override
The id of the method as saved in the project, must be unique in registry.
QString name() const override
The readable and translate name of the method.
QIcon icon() const override
The icon of the method.
QVariantMap parameterValues() const
Returns the values of the processing parameters.
ClassPosition
Defines the class position.
@ LowerBound
The class is at the lower bound.
@ UpperBound
The class is at the upper bound.
@ Inner
The class is not at a bound.
void addParameter(QgsProcessingParameterDefinition *definition)
Add a parameter to the method.
QString labelFormat() const
Returns the format of the label for the classes.
QgsClassificationMethod(MethodProperties properties=NoFlag, int codeComplexity=1)
Creates a classification method.
const QgsProcessingParameterDefinition * parameterDefinition(const QString &parameterName) const
Returns the parameter from its name.
QString formatNumber(double value) const
Format the number according to label properties.
void copyBase(QgsClassificationMethod *c) const
Copy the parameters (shall be used in clone implementation).
Contains information about the context in which a processing algorithm is executed.
Base class for the definition of processing parameters.
An enum based parameter for processing algorithms, allowing for selection from predefined values.
static int parameterAsEnum(const QgsProcessingParameterDefinition *definition, const QVariantMap &parameters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a enum value.
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...
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