Skip to content

Commit

Permalink
Merge pull request #33233 from 3nids/class_method_params
Browse files Browse the repository at this point in the history
Option to filter negative values in logarithmic classification method
  • Loading branch information
3nids committed Dec 5, 2019
2 parents 2b66b3d + bd447f4 commit d147a8d
Show file tree
Hide file tree
Showing 28 changed files with 457 additions and 195 deletions.
Expand Up @@ -31,6 +31,8 @@ which does not compute any break.
virtual QString id() const;


virtual bool valuesRequired() const;

static const QString METHOD_ID;

};
Expand Down
Expand Up @@ -32,6 +32,8 @@ for equal intervals
virtual QIcon icon() const;


virtual bool valuesRequired() const;

static const QString METHOD_ID;

};
Expand Down
Expand Up @@ -32,6 +32,8 @@ Implementation of a logarithmic scale method

virtual QString labelForRange( double lowerValue, double upperValue, ClassPosition position ) const;

virtual bool valuesRequired() const;


};

Expand Down
Expand Up @@ -155,13 +155,14 @@ Writes extra information about the method
Reads extra information to apply it to the method
%End


bool valuesRequired() const;
virtual bool valuesRequired() const;
%Docstring
Returns if the method requires values to calculate the classes
If not, bounds are sufficient
%End



int codeComplexity() const;
%Docstring
Code complexity as the exponent in Big O notation
Expand Down Expand Up @@ -289,6 +290,27 @@ Does not put a break on the symmetryPoint. This is done before.
Returns the label for a range
%End

const QgsProcessingParameterDefinition *parameterDefinition( const QString &parameterName ) const;
%Docstring
Returns the parameter from its name

.. versionadded:: 3.12
%End

QgsProcessingParameterDefinitions parameterDefinitions() const;
%Docstring
Returns the list of parameters

.. versionadded:: 3.12
%End

void setParameterValues( const QVariantMap &values );
%Docstring
Defines the values of the additional parameters

.. versionadded:: 3.12
%End



static const int MAX_PRECISION;
Expand All @@ -304,6 +326,25 @@ Copy the parameters (shall be used in clone implementation)
QString formatNumber( double value ) const;
%Docstring
Format the number according to label properties
%End

void addParameter( QgsProcessingParameterDefinition *definition /Transfer/ );
%Docstring
Add a parameter to the method.
The paramaeter is a processing parameter which will allow its configuration in the GUI.

.. note::

Only parameters having their widget implementation in C++ are supported. i.e. pure
Python parameters are not supported.

.. versionadded:: 3.12
%End

QVariantMap parameterValues() const;
%Docstring
Returns the values of the processing parameters.
One could use QgsProcessingParameters.parameterAsXxxx to retrieve the actual value of a parameter.
%End

};
Expand Down
Expand Up @@ -32,6 +32,8 @@ for pretty breaks
virtual QIcon icon() const;


virtual bool valuesRequired() const;

};

/************************************************************************
Expand Down
Empty file.
Expand Up @@ -10,6 +10,10 @@







class QgsGraduatedSymbolRendererWidget : QgsRendererWidget
{

Expand Down
4 changes: 2 additions & 2 deletions src/core/classification/qgsclassificationcustom.cpp
Expand Up @@ -19,7 +19,7 @@ const QString QgsClassificationCustom::METHOD_ID = QStringLiteral( "Custom" );


QgsClassificationCustom::QgsClassificationCustom()
: QgsClassificationMethod( ValuesNotRequired,
: QgsClassificationMethod( NoFlag,
0 /*codeComplexity*/ )
{
}
Expand All @@ -42,7 +42,7 @@ QString QgsClassificationCustom::id() const
return METHOD_ID;
}

QList<double> QgsClassificationCustom::calculateBreaks( double minimum, double maximum,
QList<double> QgsClassificationCustom::calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses )
{
Q_UNUSED( minimum )
Expand Down
4 changes: 3 additions & 1 deletion src/core/classification/qgsclassificationcustom.h
Expand Up @@ -34,10 +34,12 @@ class CORE_EXPORT QgsClassificationCustom : public QgsClassificationMethod
QString name() const override;
QString id() const override;

bool valuesRequired() const override {return false;}

static const QString METHOD_ID;

private:
QList<double> calculateBreaks( double minimum, double maximum,
QList<double> calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses ) override;
};

Expand Down
5 changes: 3 additions & 2 deletions src/core/classification/qgsclassificationequalinterval.cpp
Expand Up @@ -21,7 +21,7 @@
const QString QgsClassificationEqualInterval::METHOD_ID = QStringLiteral( "EqualInterval" );

QgsClassificationEqualInterval::QgsClassificationEqualInterval()
: QgsClassificationMethod( ValuesNotRequired | SymmetricModeAvailable, 0 /*codeComplexity*/ )
: QgsClassificationMethod( SymmetricModeAvailable, 0 /*codeComplexity*/ )
{
}

Expand All @@ -35,7 +35,7 @@ QString QgsClassificationEqualInterval::id() const
return METHOD_ID;
}

QList<double> QgsClassificationEqualInterval::calculateBreaks( double minimum, double maximum,
QList<double> QgsClassificationEqualInterval::calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses )
{
Q_UNUSED( values )
Expand Down Expand Up @@ -101,3 +101,4 @@ QIcon QgsClassificationEqualInterval::icon() const
{
return QgsApplication::getThemeIcon( "classification_methods/mClassificationEqualInterval.svg" );
}

5 changes: 3 additions & 2 deletions src/core/classification/qgsclassificationequalinterval.h
Expand Up @@ -35,13 +35,14 @@ class CORE_EXPORT QgsClassificationEqualInterval : public QgsClassificationMetho
QgsClassificationMethod *clone() const override;
QIcon icon() const override;

bool valuesRequired() const override { return false; }

static const QString METHOD_ID;

private:
QList<double> calculateBreaks( double minimum, double maximum,
QList<double> calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses ) override;


};

#endif // QGSCLASSIFICATIONEQUALINTERVAL_H
2 changes: 1 addition & 1 deletion src/core/classification/qgsclassificationjenks.cpp
Expand Up @@ -46,7 +46,7 @@ QIcon QgsClassificationJenks::icon() const
}


QList<double> QgsClassificationJenks::calculateBreaks( double minimum, double maximum,
QList<double> QgsClassificationJenks::calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses )
{
// Jenks Optimal (Natural Breaks) algorithm
Expand Down
2 changes: 1 addition & 1 deletion src/core/classification/qgsclassificationjenks.h
Expand Up @@ -36,7 +36,7 @@ class CORE_EXPORT QgsClassificationJenks : public QgsClassificationMethod
QIcon icon() const override;

private:
QList<double> calculateBreaks( double minimum, double maximum,
QList<double> calculateBreaks( double &minimum, double &maximum,
const QList<double> &values, int nclasses ) override;

int mMaximumSize = 3000;
Expand Down
36 changes: 32 additions & 4 deletions src/core/classification/qgsclassificationlogarithmic.cpp
Expand Up @@ -13,14 +13,19 @@
* *
***************************************************************************/

#include <QObject>

#include "qgsclassificationlogarithmic.h"
#include "qgssymbollayerutils.h"
#include "qgsapplication.h"
#include "qgsprocessingcontext.h"


QgsClassificationLogarithmic::QgsClassificationLogarithmic()
: QgsClassificationMethod( ValuesNotRequired, 0 )
: QgsClassificationMethod( NoFlag, 0 )
{

QgsProcessingParameterBoolean *param = new QgsProcessingParameterBoolean( QStringLiteral( "FILTER_ZERO_NEG_VALUES" ), QObject::tr( "Filter values ≤ 0" ), false );
addParameter( param );
}


Expand All @@ -46,9 +51,27 @@ QIcon QgsClassificationLogarithmic::icon() const
return QgsApplication::getThemeIcon( "classification_methods/mClassificationLogarithmic.svg" );
}

QList<double> QgsClassificationLogarithmic::calculateBreaks( double minimum, double maximum, const QList<double> &values, int nclasses )
QList<double> QgsClassificationLogarithmic::calculateBreaks( double &minimum, double &maximum, const QList<double> &values, int nclasses )
{
Q_UNUSED( values )
// not possible if only negative values
if ( maximum <= 0 )
return QList<double>();

QgsProcessingContext context;
bool filterZeroNeg = QgsProcessingParameters::parameterAsBool( parameterDefinition( QStringLiteral( "FILTER_ZERO_NEG_VALUES" ) ), parameterValues(), context );

if ( filterZeroNeg && minimum <= 0 )
{
Q_ASSERT( values.count() );
minimum = std::numeric_limits<double>::max();
for ( int i = 0; i < values.count(); i++ )
{
if ( values.at( i ) > 0 )
minimum = std::min( minimum, values.at( i ) );
}
if ( minimum == std::numeric_limits<double>::max() )
return QList<double>();
}

// get the min/max in log10 scale
double log_min = std::floor( std::log10( minimum ) );
Expand Down Expand Up @@ -89,3 +112,8 @@ QString QgsClassificationLogarithmic::labelForRange( double lowerValue, double u
return labelFormat().arg( lowerLabel ).arg( upperLabel );
}

bool QgsClassificationLogarithmic::valuesRequired() const
{
QgsProcessingContext context;
return QgsProcessingParameters::parameterAsBool( parameterDefinition( QStringLiteral( "FILTER_ZERO_NEG_VALUES" ) ), parameterValues(), context );
}
5 changes: 4 additions & 1 deletion src/core/classification/qgsclassificationlogarithmic.h
Expand Up @@ -34,10 +34,13 @@ class CORE_EXPORT QgsClassificationLogarithmic : public QgsClassificationMethod
QString id() const override;
QIcon icon() const override;
QString labelForRange( double lowerValue, double upperValue, ClassPosition position ) const override;
bool valuesRequired() const override;

private:
QList<double> calculateBreaks( double minimum, double maximum, const QList<double> &values, int nclasses ) override;
QList<double> calculateBreaks( double &minimum, double &maximum, const QList<double> &values, int nclasses ) override;
QString valueToLabel( double value ) const override;


};

#endif // QGSCLASSIFICATIONLOGARITHMIC_H
32 changes: 30 additions & 2 deletions src/core/classification/qgsclassificationmethod.cpp
Expand Up @@ -39,7 +39,7 @@ QList<double> QgsClassificationMethod::rangesToBreaks( const QList<QgsClassifica
QgsClassificationMethod::QgsClassificationMethod( MethodProperties properties, int codeComplexity )
: mFlags( properties )
, mCodeComplexity( codeComplexity )
, mLabelFormat( QStringLiteral( "%1 - %2 " ) )
, mLabelFormat( QStringLiteral( "%1 - %2" ) )
{
}

Expand Down Expand Up @@ -161,6 +161,33 @@ QString QgsClassificationMethod::formatNumber( double value ) const
}
}

void QgsClassificationMethod::addParameter( QgsProcessingParameterDefinition *definition )
{
mParameters.append( definition );
}

const QgsProcessingParameterDefinition *QgsClassificationMethod::parameterDefinition( const QString &parameterName ) const
{
for ( const QgsProcessingParameterDefinition *def : mParameters )
{
if ( def->name() == parameterName )
return def;
}
return nullptr;
}

void QgsClassificationMethod::setParameterValues( const QVariantMap &values )
{
mParameterValues = values;
for ( auto it = mParameterValues.begin(); it != mParameterValues.end(); ++it )
{
if ( !parameterDefinition( it.key() ) )
{
QgsMessageLog::logMessage( name(), QObject::tr( "Parameter %1 does not exist in the method" ).arg( it.key() ) );
}
}
}

QList<QgsClassificationRange> QgsClassificationMethod::classes( const QgsVectorLayer *layer, const QString &expression, int nclasses )
{
if ( expression.isEmpty() )
Expand All @@ -173,6 +200,7 @@ QList<QgsClassificationRange> QgsClassificationMethod::classes( const QgsVectorL
double minimum;
double maximum;


int fieldIndex = layer->fields().indexFromName( expression );

bool ok;
Expand All @@ -192,7 +220,7 @@ QList<QgsClassificationRange> QgsClassificationMethod::classes( const QgsVectorL
maximum = layer->maximumValue( fieldIndex ).toDouble();
}

// get the breaks
// get the breaks, minimum and maximum might be updated by implementation
QList<double> breaks = calculateBreaks( minimum, maximum, values, nclasses );
breaks.insert( 0, minimum );
// create classes
Expand Down

0 comments on commit d147a8d

Please sign in to comment.