LCOV - code coverage report
Current view: top level - core/classification - qgsclassificationmethod.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 24 0.0 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :     qgsclassificationmethod.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                 :            : #ifndef QGSCLASSIFICATIONMETHOD_H
      17                 :            : #define QGSCLASSIFICATIONMETHOD_H
      18                 :            : 
      19                 :            : #include <QIcon>
      20                 :            : 
      21                 :            : #include "qgis_sip.h"
      22                 :            : #include "qgis_core.h"
      23                 :            : #include "qgsprocessingparameters.h"
      24                 :            : 
      25                 :            : class QgsVectorLayer;
      26                 :            : class QgsRendererRange;
      27                 :            : 
      28                 :            : 
      29                 :            : #ifdef SIP_RUN
      30                 :            : // This is required for the ConvertToSubClassCode to work properly
      31                 :            : // so RTTI for casting is available in the whole module.
      32                 :            : % ModuleCode
      33                 :            : #include "qgsclassificationequalinterval.h"
      34                 :            : #include "qgsclassificationjenks.h"
      35                 :            : #include "qgsclassificationprettybreaks.h"
      36                 :            : #include "qgsclassificationquantile.h"
      37                 :            : #include "qgsclassificationstandarddeviation.h"
      38                 :            : % End
      39                 :            : #endif
      40                 :            : 
      41                 :            : 
      42                 :            : 
      43                 :            : /**
      44                 :            :  * \ingroup core
      45                 :            :  * \brief QgsClassificationRange contains the information about a classification range
      46                 :            :  * \since QGIS 3.10
      47                 :            :  */
      48                 :          0 : class CORE_EXPORT QgsClassificationRange
      49                 :            : {
      50                 :            :   public:
      51                 :            :     //! Constructor
      52                 :          0 :     QgsClassificationRange( const QString &label, double lowerBound, double upperBound )
      53                 :          0 :       : mLabel( label )
      54                 :          0 :       , mLowerBound( lowerBound )
      55                 :          0 :       , mUpperBound( upperBound )
      56                 :          0 :     {}
      57                 :            :     //! Returns the lower bound
      58                 :          0 :     double lowerBound() const {return mLowerBound;}
      59                 :            :     //! Returns the upper bound
      60                 :          0 :     double upperBound() const {return mUpperBound;}
      61                 :            : 
      62                 :            :     //! Returns the lower bound
      63                 :          0 :     QString label() const {return mLabel;}
      64                 :            : 
      65                 :            : #ifdef SIP_RUN
      66                 :            :     SIP_PYOBJECT __repr__();
      67                 :            :     % MethodCode
      68                 :            :     QString str = QStringLiteral( "<QgsClassificationRange: '%1'>" ).arg( sipCpp->label() );
      69                 :            :     sipRes = PyUnicode_FromString( str.toUtf8().constData() );
      70                 :            :     % End
      71                 :            : #endif
      72                 :            : 
      73                 :            :   private:
      74                 :            :     QString mLabel;
      75                 :            :     double mLowerBound;
      76                 :            :     double mUpperBound;
      77                 :            : };
      78                 :            : 
      79                 :            : 
      80                 :            : 
      81                 :            : /**
      82                 :            :  * \ingroup core
      83                 :            :  * \brief QgsClassificationMethod is an abstract class for implementations of classification methods
      84                 :            :  * \see QgsClassificationMethodRegistry
      85                 :            :  * \since QGIS 3.10
      86                 :            :  */
      87                 :            : class CORE_EXPORT QgsClassificationMethod SIP_ABSTRACT
      88                 :            : {
      89                 :            : 
      90                 :            : #ifdef SIP_RUN
      91                 :            :     SIP_CONVERT_TO_SUBCLASS_CODE
      92                 :            :     if ( dynamic_cast<QgsClassificationEqualInterval *>( sipCpp ) )
      93                 :            :       sipType = sipType_QgsClassificationEqualInterval;
      94                 :            :     else if ( dynamic_cast<QgsClassificationJenks *>( sipCpp ) )
      95                 :            :       sipType = sipType_QgsClassificationJenks;
      96                 :            :     else if ( dynamic_cast<QgsClassificationPrettyBreaks *>( sipCpp ) )
      97                 :            :       sipType = sipType_QgsClassificationPrettyBreaks;
      98                 :            :     else if ( dynamic_cast<QgsClassificationQuantile *>( sipCpp ) )
      99                 :            :       sipType = sipType_QgsClassificationQuantile;
     100                 :            :     else if ( dynamic_cast<QgsClassificationStandardDeviation *>( sipCpp ) )
     101                 :            :       sipType = sipType_QgsClassificationStandardDeviation;
     102                 :            :     else
     103                 :            :       sipType = 0;
     104                 :            :     SIP_END
     105                 :            : #endif
     106                 :            : 
     107                 :            :   public:
     108                 :            : 
     109                 :            :     //! Flags for the classification method
     110                 :            :     enum MethodProperty
     111                 :            :     {
     112                 :            :       NoFlag                 = 0,       //!< No flag
     113                 :            :       ValuesNotRequired      = 1 << 1,  //!< Deprecated since QGIS 3.12
     114                 :            :       SymmetricModeAvailable = 1 << 2,  //!< This allows using symmetric classification
     115                 :            :     };
     116                 :            :     Q_DECLARE_FLAGS( MethodProperties, MethodProperty )
     117                 :            : 
     118                 :            : 
     119                 :            :     //! Defines the class position
     120                 :            :     enum ClassPosition
     121                 :            :     {
     122                 :            :       LowerBound, //!< The class is at the lower bound
     123                 :            :       Inner,      //!< The class is not at a bound
     124                 :            :       UpperBound  //!< The class is at the upper bound
     125                 :            :     };
     126                 :            : 
     127                 :            :     /**
     128                 :            :       * Creates a classification method.
     129                 :            :       * \param properties The properties of the implemented method
     130                 :            :       * \param codeComplexity as the exponent in the big O notation
     131                 :            :       */
     132                 :            :     explicit QgsClassificationMethod( MethodProperties properties = NoFlag, int codeComplexity = 1 );
     133                 :            : 
     134                 :            :     virtual ~QgsClassificationMethod();
     135                 :            : 
     136                 :            :     /**
     137                 :            :      * Returns a clone of the method.
     138                 :            :      * Implementation can take advantage of copyBase method which copies the parameters of the base class
     139                 :            :      */
     140                 :            :     virtual QgsClassificationMethod *clone() const = 0 SIP_FACTORY;
     141                 :            : 
     142                 :            :     //! The readable and translate name of the method
     143                 :            :     virtual QString name() const = 0;
     144                 :            : 
     145                 :            :     //! The id of the method as saved in the project, must be unique in registry
     146                 :            :     virtual QString id() const = 0;
     147                 :            : 
     148                 :            :     //! The icon of the method
     149                 :          0 :     virtual QIcon icon() const {return QIcon();}
     150                 :            : 
     151                 :            :     /**
     152                 :            :      * Returns the label for a range
     153                 :            :      */
     154                 :            :     virtual QString labelForRange( double lowerValue, double upperValue, ClassPosition position = Inner ) const;
     155                 :            : 
     156                 :            : 
     157                 :            :     //! Writes extra information about the method
     158                 :          0 :     virtual void writeXml( QDomElement &element, const QgsReadWriteContext &context ) const {Q_UNUSED( element ); Q_UNUSED( context )}
     159                 :            :     //! Reads extra information to apply it to the method
     160                 :          0 :     virtual void readXml( const QDomElement &element, const QgsReadWriteContext &context ) {Q_UNUSED( element ); Q_UNUSED( context )}
     161                 :            : 
     162                 :            :     /**
     163                 :            :      * Returns if the method requires values to calculate the classes
     164                 :            :      * If not, bounds are sufficient
     165                 :            :      */
     166                 :          0 :     virtual bool valuesRequired() const {return true;}
     167                 :            : 
     168                 :            : 
     169                 :            :     // *******************
     170                 :            :     // non-virtual methods
     171                 :            : 
     172                 :            :     //! Code complexity as the exponent in Big O notation
     173                 :            :     int codeComplexity() const {return mCodeComplexity;}
     174                 :            : 
     175                 :            :     /**
     176                 :            :      * Returns if the method supports symmetric calculation
     177                 :            :      */
     178                 :          0 :     bool symmetricModeAvailable() const {return mFlags.testFlag( SymmetricModeAvailable );}
     179                 :            : 
     180                 :            :     /**
     181                 :            :      * Returns if the symmetric mode is enabled
     182                 :            :      */
     183                 :          0 :     bool symmetricModeEnabled() const {return symmetricModeAvailable() && mSymmetricEnabled;}
     184                 :            : 
     185                 :            :     /**
     186                 :            :      * Returns the symmetry point for symmetric mode
     187                 :            :      */
     188                 :          0 :     double symmetryPoint() const {return mSymmetryPoint;}
     189                 :            : 
     190                 :            :     /**
     191                 :            :      * Returns if the symmetric mode is astride
     192                 :            :      * if TRUE, it will remove the symmetry point break so that the 2 classes form only one
     193                 :            :      */
     194                 :          0 :     bool symmetryAstride() const {return mSymmetryAstride;}
     195                 :            : 
     196                 :            :     /**
     197                 :            :      * Defines if the symmetric mode is enables and configures its parameters.
     198                 :            :      * If the symmetric mode is not available in the current implementation, calling this method has no effect.
     199                 :            :      * \param enabled if the symmetric mode is enabled
     200                 :            :      * \param symmetryPoint the value of the symmetry point
     201                 :            :      * \param symmetryAstride if TRUE, it will remove the symmetry point break so that the 2 classes form only one
     202                 :            :      */
     203                 :            :     void setSymmetricMode( bool enabled, double symmetryPoint = 0, bool symmetryAstride = false );
     204                 :            : 
     205                 :            :     // Label properties
     206                 :            :     //! Returns the format of the label for the classes
     207                 :          0 :     QString labelFormat() const { return mLabelFormat; }
     208                 :            :     //! Defines the format of the labels for the classes, using %1 and %2 for the bounds
     209                 :          0 :     void setLabelFormat( const QString &format ) { mLabelFormat = format; }
     210                 :            :     //! Returns the precision for the formatting of the labels
     211                 :          0 :     int labelPrecision() const { return mLabelPrecision; }
     212                 :            :     //! Defines the precision for the formatting of the labels
     213                 :            :     void setLabelPrecision( int labelPrecision );
     214                 :            :     //! Returns if the trailing 0 are trimmed in the label
     215                 :          0 :     bool labelTrimTrailingZeroes() const { return mLabelTrimTrailingZeroes; }
     216                 :            :     //! Defines if the trailing 0 are trimmed in the label
     217                 :          0 :     void setLabelTrimTrailingZeroes( bool trimTrailingZeroes ) { mLabelTrimTrailingZeroes = trimTrailingZeroes; }
     218                 :            : 
     219                 :            :     //! Transforms a list of classes to a list of breaks
     220                 :            :     static QList<double> rangesToBreaks( const QList<QgsClassificationRange> &classes );
     221                 :            : 
     222                 :            :     /**
     223                 :            :      * This will calculate the classes for a given layer to define the classes.
     224                 :            :      * \param layer The vector layer
     225                 :            :      * \param expression The name of the field on which the classes are calculated
     226                 :            :      * \param nclasses The number of classes to be returned
     227                 :            :      */
     228                 :            :     QList<QgsClassificationRange> classes( const QgsVectorLayer *layer, const QString &expression, int nclasses );
     229                 :            : 
     230                 :            :     /**
     231                 :            :      * This will calculate the classes for a list of values.
     232                 :            :      * \param values The list of values
     233                 :            :      * \param nclasses The number of classes to be returned
     234                 :            :      */
     235                 :            :     QList<QgsClassificationRange> classes( const QList<double> &values, int nclasses );
     236                 :            : 
     237                 :            :     /**
     238                 :            :      * This will calculate the classes for defined bounds without any values.
     239                 :            :      * \warning If the method implementation requires values, this will return an empty list.
     240                 :            :      * \param minimum The minimum value for the breaks
     241                 :            :      * \param maximum The maximum value for the breaks
     242                 :            :      * \param nclasses The number of classes to be returned
     243                 :            :      */
     244                 :            :     QList<QgsClassificationRange> classes( double minimum, double maximum, int nclasses );
     245                 :            : 
     246                 :            :     /**
     247                 :            :      * Saves the method to a DOM element and return it
     248                 :            :      * \param doc the DOM document
     249                 :            :      * \param context the read/write context
     250                 :            :      */
     251                 :            :     QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
     252                 :            : 
     253                 :            :     /**
     254                 :            :      * Reads the DOM element and return a new classification method from it
     255                 :            :      * \param element the DOM element
     256                 :            :      * \param context the read/write context
     257                 :            :      */
     258                 :            :     static QgsClassificationMethod *create( const QDomElement &element, const QgsReadWriteContext &context ) SIP_FACTORY;
     259                 :            : 
     260                 :            :     /**
     261                 :            :      * Remove the breaks that are above the existing opposite sign classes to keep colors symmetrically balanced around symmetryPoint
     262                 :            :      * Does not put a break on the symmetryPoint. This is done before.
     263                 :            :      * \param breaks The breaks of an already-done classification
     264                 :            :      * \param symmetryPoint The point around which we want a symmetry
     265                 :            :      * \param astride A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
     266                 :            :      */
     267                 :            :     static void makeBreaksSymmetric( QList<double> &breaks SIP_INOUT, double symmetryPoint, bool astride );
     268                 :            : 
     269                 :            :     /**
     270                 :            :      * Returns the label for a range
     271                 :            :      */
     272                 :            :     QString labelForRange( const QgsRendererRange &range, ClassPosition position = Inner ) const;
     273                 :            : 
     274                 :            :     /**
     275                 :            :      * Returns the parameter from its name
     276                 :            :      * \since QGIS 3.12
     277                 :            :      */
     278                 :            :     const QgsProcessingParameterDefinition *parameterDefinition( const QString &parameterName ) const;
     279                 :            : 
     280                 :            :     /**
     281                 :            :      * Returns the list of parameters
     282                 :            :      * \since QGIS 3.12
     283                 :            :      */
     284                 :            :     QgsProcessingParameterDefinitions parameterDefinitions() const {return mParameters;}
     285                 :            : 
     286                 :            :     /**
     287                 :            :      * Defines the values of the additional parameters
     288                 :            :      * \since QGIS 3.12
     289                 :            :      */
     290                 :            :     void setParameterValues( const QVariantMap &values );
     291                 :            : 
     292                 :            :     /**
     293                 :            :      * Returns the values of the processing parameters.
     294                 :            :      * One could use QgsProcessingParameters::parameterAsXxxx to retrieve the actual value of a parameter.
     295                 :            :      * \since QGIS 3.12
     296                 :            :      */
     297                 :          0 :     QVariantMap parameterValues() const {return mParameterValues;}
     298                 :            : 
     299                 :            :     static const int MAX_PRECISION;
     300                 :            :     static const int MIN_PRECISION;
     301                 :            : 
     302                 :            :   protected:
     303                 :            : 
     304                 :            :     //! Copy the parameters (shall be used in clone implementation)
     305                 :            :     void copyBase( QgsClassificationMethod *c ) const;
     306                 :            : 
     307                 :            :     //! Format the number according to label properties
     308                 :            :     QString formatNumber( double value ) const;
     309                 :            : 
     310                 :            :     /**
     311                 :            :      * Add a parameter to the method.
     312                 :            :      * The paramaeter is a processing parameter which will allow its configuration in the GUI.
     313                 :            :      * \note Only parameters having their widget implementation in C++ are supported. i.e. pure
     314                 :            :      * Python parameters are not supported.
     315                 :            :      * \since QGIS 3.12
     316                 :            :      */
     317                 :            :     void addParameter( QgsProcessingParameterDefinition *definition SIP_TRANSFER );
     318                 :            : 
     319                 :            :   private:
     320                 :            : 
     321                 :            :     /**
     322                 :            :      * Calculate the breaks, should be reimplemented, values might be an empty list if they are not required
     323                 :            :      * If the symmetric mode is available, the implementation is responsible of applying the symmetry
     324                 :            :      * The maximum value is expected to be added at the end of the list, but not the minimum
     325                 :            :      */
     326                 :            :     virtual QList<double> calculateBreaks( double &minimum, double &maximum,
     327                 :            :                                            const QList<double> &values, int nclasses ) = 0;
     328                 :            : 
     329                 :            :     //! This is called after calculating the breaks or restoring from XML, so it can rely on private variables
     330                 :          0 :     virtual QString valueToLabel( double value ) const {return formatNumber( value );}
     331                 :            : 
     332                 :            :     //! Create a list of ranges from a list of classes
     333                 :            :     QList<QgsClassificationRange> breaksToClasses( const QList<double> &breaks ) const;
     334                 :            : 
     335                 :            :     // implementation properties (set by initialization)
     336                 :            :     MethodProperties mFlags = MethodProperties();
     337                 :            :     int mCodeComplexity = 1;
     338                 :            : 
     339                 :            :     // parameters (set by setters)
     340                 :            :     // if some are added here, they should be handled in the clone method
     341                 :            :     bool mSymmetricEnabled = false;
     342                 :            :     double mSymmetryPoint = 0;
     343                 :            :     bool mSymmetryAstride = false;
     344                 :            :     int mLabelPrecision = 4;
     345                 :            :     bool mLabelTrimTrailingZeroes = true;
     346                 :            :     QString mLabelFormat;
     347                 :            : 
     348                 :            :     // values used to manage number formatting - precision and trailing zeroes
     349                 :            :     double mLabelNumberScale = 1.0;
     350                 :            :     QString mLabelNumberSuffix;
     351                 :            : 
     352                 :            :     //! additional parameters
     353                 :            :     QgsProcessingParameterDefinitions mParameters;
     354                 :            :     QVariantMap mParameterValues;
     355                 :            : };
     356                 :            : 
     357                 :            : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsClassificationMethod::MethodProperties )
     358                 :            : 
     359                 :            : #endif // QGSCLASSIFICATIONMETHOD_H

Generated by: LCOV version 1.14