mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-18 00:04:02 -04:00
classify symmetric squashed (17 commits) to rebase easily on master; 13 may 2018
This commit is contained in:
parent
05f35f2e19
commit
fe049d372c
@ -225,7 +225,63 @@ Tests whether classes assigned to the renderer have gaps between the ranges.
|
||||
Mode mode() const;
|
||||
void setMode( Mode mode );
|
||||
|
||||
void updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses );
|
||||
bool useSymmetricMode();
|
||||
%Docstring
|
||||
get mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setUseSymmetricMode( bool useSymmetricMode );
|
||||
%Docstring
|
||||
set mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
double symmetryPoint();
|
||||
%Docstring
|
||||
get mSymmetryPoint, the pivot value for symmetric classification
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setSymmetryPoint( double symmetryPoint );
|
||||
%Docstring
|
||||
set the pivot point
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
QStringList listForCboPrettyBreaks();
|
||||
%Docstring
|
||||
get mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setListForCboPrettyBreaks( QStringList listForCboPrettyBreaks );
|
||||
%Docstring
|
||||
set mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
bool astride();
|
||||
%Docstring
|
||||
get mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setAstride( bool astride );
|
||||
%Docstring
|
||||
set mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses, bool useSymmetricMode = false, double symmetryPoint = 0.0, bool astride = false );
|
||||
%Docstring
|
||||
Recalculate classes for a layer
|
||||
|
||||
@ -234,6 +290,11 @@ Recalculate classes for a layer
|
||||
:param nclasses: The number of classes to calculate (approximate for some modes)
|
||||
|
||||
.. versionadded:: 2.6
|
||||
:param useSymmetricMode: A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
:param symmetryPoint: The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
:param astride: A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
const QgsRendererRangeLabelFormat &labelFormat() const;
|
||||
@ -266,6 +327,10 @@ Reset the label decimal places to a numberbased on the minimum class interval
|
||||
const QString &attrName,
|
||||
int classes,
|
||||
Mode mode,
|
||||
bool useSymmetricMode,
|
||||
double symmetryPoint,
|
||||
QStringList listForCboPrettyBreaks,
|
||||
bool astride,
|
||||
QgsSymbol *symbol /Transfer/,
|
||||
QgsColorRamp *ramp /Transfer/,
|
||||
const QgsRendererRangeLabelFormat &legendFormat = QgsRendererRangeLabelFormat() );
|
||||
@ -276,6 +341,10 @@ Creates a new graduated renderer.
|
||||
:param attrName: attribute to classify
|
||||
:param classes: number of classes
|
||||
:param mode: classification mode
|
||||
:param useSymmetricMode: A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
:param symmetryPoint: The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
:param listForCboPrettyBreaks: The list of potential pivot values for symmetric mode with prettybreaks mode
|
||||
:param astride: A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
:param symbol: base symbol
|
||||
:param ramp: color ramp for classes
|
||||
:param legendFormat:
|
||||
@ -440,6 +509,7 @@ Will return null if the functionality is disabled.
|
||||
|
||||
|
||||
|
||||
|
||||
QgsSymbol *symbolForValue( double value ) const;
|
||||
%Docstring
|
||||
Gets the symbol which is used to represent ``value``.
|
||||
|
535
python/core/symbology/qgsgraduatedsymbolrenderer.sip
Normal file
535
python/core/symbology/qgsgraduatedsymbolrenderer.sip
Normal file
@ -0,0 +1,535 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/symbology/qgsgraduatedsymbolrenderer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsRendererRange
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgraduatedsymbolrenderer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsRendererRange();
|
||||
%Docstring
|
||||
Constructor for QgsRendererRange.
|
||||
%End
|
||||
QgsRendererRange( double lowerValue, double upperValue, QgsSymbol *symbol /Transfer/, const QString &label, bool render = true );
|
||||
QgsRendererRange( const QgsRendererRange &range );
|
||||
|
||||
|
||||
bool operator<( const QgsRendererRange &other ) const;
|
||||
|
||||
double lowerValue() const;
|
||||
double upperValue() const;
|
||||
|
||||
QgsSymbol *symbol() const;
|
||||
QString label() const;
|
||||
|
||||
void setSymbol( QgsSymbol *s /Transfer/ );
|
||||
void setLabel( const QString &label );
|
||||
void setLowerValue( double lowerValue );
|
||||
void setUpperValue( double upperValue );
|
||||
|
||||
bool renderState() const;
|
||||
void setRenderState( bool render );
|
||||
|
||||
QString dump() const;
|
||||
|
||||
void toSld( QDomDocument &doc, QDomElement &element, QgsStringMap props, bool firstRange = false ) const;
|
||||
%Docstring
|
||||
Creates a DOM element representing the range in SLD format.
|
||||
|
||||
:param doc: DOM document
|
||||
:param element: destination DOM element
|
||||
:param props: graduated renderer properties
|
||||
:param firstRange: set to true if the range is the first range, where the lower value uses a <= test
|
||||
rather than a < test.
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
void swap( QgsRendererRange &other );
|
||||
};
|
||||
|
||||
typedef QList<QgsRendererRange> QgsRangeList;
|
||||
|
||||
|
||||
class QgsRendererRangeLabelFormat
|
||||
{
|
||||
%Docstring
|
||||
|
||||
.. versionadded:: 2.6
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgraduatedsymbolrenderer.h"
|
||||
%End
|
||||
public:
|
||||
QgsRendererRangeLabelFormat();
|
||||
QgsRendererRangeLabelFormat( const QString &format, int precision = 4, bool trimTrailingZeroes = false );
|
||||
|
||||
bool operator==( const QgsRendererRangeLabelFormat &other ) const;
|
||||
bool operator!=( const QgsRendererRangeLabelFormat &other ) const;
|
||||
|
||||
QString format() const;
|
||||
void setFormat( const QString &format );
|
||||
|
||||
int precision() const;
|
||||
void setPrecision( int precision );
|
||||
|
||||
bool trimTrailingZeroes() const;
|
||||
void setTrimTrailingZeroes( bool trimTrailingZeroes );
|
||||
|
||||
QString labelForRange( double lower, double upper ) const /PyName=labelForLowerUpper/;
|
||||
%Docstring
|
||||
|
||||
.. note::
|
||||
|
||||
labelForLowerUpper in Python bindings
|
||||
%End
|
||||
QString labelForRange( const QgsRendererRange &range ) const;
|
||||
QString formatNumber( double value ) const;
|
||||
|
||||
void setFromDomElement( QDomElement &element );
|
||||
void saveToDomElement( QDomElement &element );
|
||||
|
||||
static const int MAX_PRECISION;
|
||||
static const int MIN_PRECISION;
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
|
||||
class QgsGraduatedSymbolRenderer : QgsFeatureRenderer
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgraduatedsymbolrenderer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsGraduatedSymbolRenderer( const QString &attrName = QString(), const QgsRangeList &ranges = QgsRangeList() );
|
||||
|
||||
~QgsGraduatedSymbolRenderer();
|
||||
|
||||
virtual QgsSymbol *symbolForFeature( QgsFeature &feature, QgsRenderContext &context );
|
||||
|
||||
virtual QgsSymbol *originalSymbolForFeature( QgsFeature &feature, QgsRenderContext &context );
|
||||
|
||||
virtual void startRender( QgsRenderContext &context, const QgsFields &fields );
|
||||
|
||||
virtual void stopRender( QgsRenderContext &context );
|
||||
|
||||
virtual QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual QString dump() const;
|
||||
|
||||
virtual QgsGraduatedSymbolRenderer *clone() const /Factory/;
|
||||
|
||||
virtual void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props = QgsStringMap() ) const;
|
||||
|
||||
virtual QgsFeatureRenderer::Capabilities capabilities();
|
||||
virtual QgsSymbolList symbols( QgsRenderContext &context );
|
||||
|
||||
|
||||
QString classAttribute() const;
|
||||
void setClassAttribute( const QString &attr );
|
||||
|
||||
const QgsRangeList &ranges() const;
|
||||
|
||||
bool updateRangeSymbol( int rangeIndex, QgsSymbol *symbol /Transfer/ );
|
||||
bool updateRangeLabel( int rangeIndex, const QString &label );
|
||||
bool updateRangeUpperValue( int rangeIndex, double value );
|
||||
bool updateRangeLowerValue( int rangeIndex, double value );
|
||||
bool updateRangeRenderState( int rangeIndex, bool render );
|
||||
%Docstring
|
||||
|
||||
.. versionadded:: 2.5
|
||||
%End
|
||||
|
||||
void addClass( QgsSymbol *symbol );
|
||||
void addClass( const QgsRendererRange &range ) /PyName=addClassRange/;
|
||||
%Docstring
|
||||
|
||||
.. note::
|
||||
|
||||
available in Python bindings as addClassRange
|
||||
%End
|
||||
void addClass( double lower, double upper ) /PyName=addClassLowerUpper/;
|
||||
%Docstring
|
||||
|
||||
.. note::
|
||||
|
||||
available in Python bindings as addClassLowerUpper
|
||||
%End
|
||||
|
||||
void addBreak( double breakValue, bool updateSymbols = true );
|
||||
%Docstring
|
||||
Add a breakpoint by splitting existing classes so that the specified
|
||||
value becomes a break between two classes.
|
||||
|
||||
:param breakValue: position to insert break
|
||||
:param updateSymbols: set to true to reapply ramp colors to the new
|
||||
symbol ranges
|
||||
|
||||
.. versionadded:: 2.9
|
||||
%End
|
||||
|
||||
void deleteClass( int idx );
|
||||
void deleteAllClasses();
|
||||
|
||||
void moveClass( int from, int to );
|
||||
%Docstring
|
||||
Moves the category at index position from to index position to.
|
||||
%End
|
||||
|
||||
bool rangesOverlap() const;
|
||||
%Docstring
|
||||
Tests whether classes assigned to the renderer have ranges which overlap.
|
||||
|
||||
:return: true if ranges overlap
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
bool rangesHaveGaps() const;
|
||||
%Docstring
|
||||
Tests whether classes assigned to the renderer have gaps between the ranges.
|
||||
|
||||
:return: true if ranges have gaps
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
void sortByValue( Qt::SortOrder order = Qt::AscendingOrder );
|
||||
void sortByLabel( Qt::SortOrder order = Qt::AscendingOrder );
|
||||
|
||||
enum Mode
|
||||
{
|
||||
EqualInterval,
|
||||
Quantile,
|
||||
Jenks,
|
||||
StdDev,
|
||||
Pretty,
|
||||
Custom
|
||||
};
|
||||
|
||||
Mode mode() const;
|
||||
void setMode( Mode mode );
|
||||
|
||||
bool useSymmetricMode();
|
||||
%Docstring
|
||||
get mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setUseSymmetricMode( bool useSymmetricMode );
|
||||
%Docstring
|
||||
set mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
double symmetryPoint();
|
||||
%Docstring
|
||||
get mSymmetryPoint, the pivot value for symmetric classification
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setSymmetryPoint( double symmetryPoint );
|
||||
%Docstring
|
||||
set the pivot point
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
QStringList listForCboPrettyBreaks();
|
||||
%Docstring
|
||||
get mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setListForCboPrettyBreaks( QStringList listForCboPrettyBreaks );
|
||||
%Docstring
|
||||
set mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
bool astride();
|
||||
%Docstring
|
||||
get mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void setAstride( bool astride );
|
||||
%Docstring
|
||||
set mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
void updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses, bool useSymmetricMode = false, double symmetryPoint = 0.0, bool astride = false );
|
||||
%Docstring
|
||||
Recalculate classes for a layer
|
||||
|
||||
:param vlayer: The layer being rendered (from which data values are calculated)
|
||||
:param mode: The calculation mode
|
||||
:param nclasses: The number of classes to calculate (approximate for some modes)
|
||||
|
||||
.. versionadded:: 2.6
|
||||
:param useSymmetricMode: A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
:param symmetryPoint: The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
:param astride: A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
|
||||
.. versionadded:: 3.2
|
||||
%End
|
||||
|
||||
const QgsRendererRangeLabelFormat &labelFormat() const;
|
||||
%Docstring
|
||||
Return the label format used to generate default classification labels
|
||||
|
||||
.. versionadded:: 2.6
|
||||
%End
|
||||
|
||||
void setLabelFormat( const QgsRendererRangeLabelFormat &labelFormat, bool updateRanges = false );
|
||||
%Docstring
|
||||
Set the label format used to generate default classification labels
|
||||
|
||||
:param labelFormat: The string appended to classification labels
|
||||
:param updateRanges: If true then ranges ending with the old unit string are updated to the new.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
%End
|
||||
|
||||
void calculateLabelPrecision( bool updateRanges = true );
|
||||
%Docstring
|
||||
Reset the label decimal places to a numberbased on the minimum class interval
|
||||
|
||||
:param updateRanges: if true then ranges currently using the default label will be updated
|
||||
|
||||
.. versionadded:: 2.6
|
||||
%End
|
||||
|
||||
static QgsGraduatedSymbolRenderer *createRenderer( QgsVectorLayer *vlayer,
|
||||
const QString &attrName,
|
||||
int classes,
|
||||
Mode mode,
|
||||
bool useSymmetricMode,
|
||||
double symmetryPoint,
|
||||
QStringList listForCboPrettyBreaks,
|
||||
bool astride,
|
||||
QgsSymbol *symbol /Transfer/,
|
||||
QgsColorRamp *ramp /Transfer/,
|
||||
const QgsRendererRangeLabelFormat &legendFormat = QgsRendererRangeLabelFormat() );
|
||||
%Docstring
|
||||
Creates a new graduated renderer.
|
||||
|
||||
:param vlayer: vector layer
|
||||
:param attrName: attribute to classify
|
||||
:param classes: number of classes
|
||||
:param mode: classification mode
|
||||
:param useSymmetricMode: A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
:param symmetryPoint: The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
:param listForCboPrettyBreaks: The list of potential pivot values for symmetric mode with prettybreaks mode
|
||||
:param astride: A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
:param symbol: base symbol
|
||||
:param ramp: color ramp for classes
|
||||
:param legendFormat:
|
||||
|
||||
:return: new QgsGraduatedSymbolRenderer object
|
||||
%End
|
||||
|
||||
static QgsFeatureRenderer *create( QDomElement &element, const QgsReadWriteContext &context ) /Factory/;
|
||||
%Docstring
|
||||
create renderer from XML element
|
||||
%End
|
||||
|
||||
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context );
|
||||
|
||||
virtual QgsLegendSymbolList legendSymbolItems() const;
|
||||
|
||||
virtual QSet< QString > legendKeysForFeature( QgsFeature &feature, QgsRenderContext &context );
|
||||
|
||||
|
||||
QgsSymbol *sourceSymbol();
|
||||
%Docstring
|
||||
Returns the renderer's source symbol, which is the base symbol used for the each classes' symbol before applying
|
||||
the classes' color.
|
||||
|
||||
.. seealso:: :py:func:`setSourceSymbol`
|
||||
|
||||
.. seealso:: :py:func:`sourceColorRamp`
|
||||
%End
|
||||
|
||||
void setSourceSymbol( QgsSymbol *sym /Transfer/ );
|
||||
%Docstring
|
||||
Sets the source symbol for the renderer, which is the base symbol used for the each classes' symbol before applying
|
||||
the classes' color.
|
||||
|
||||
:param sym: source symbol, ownership is transferred to the renderer
|
||||
|
||||
.. seealso:: :py:func:`sourceSymbol`
|
||||
|
||||
.. seealso:: :py:func:`setSourceColorRamp`
|
||||
%End
|
||||
|
||||
QgsColorRamp *sourceColorRamp();
|
||||
%Docstring
|
||||
Returns the source color ramp, from which each classes' color is derived.
|
||||
|
||||
.. seealso:: :py:func:`setSourceColorRamp`
|
||||
|
||||
.. seealso:: :py:func:`sourceSymbol`
|
||||
%End
|
||||
|
||||
void setSourceColorRamp( QgsColorRamp *ramp /Transfer/ );
|
||||
%Docstring
|
||||
Sets the source color ramp.
|
||||
|
||||
:param ramp: color ramp. Ownership is transferred to the renderer
|
||||
%End
|
||||
|
||||
void updateColorRamp( QgsColorRamp *ramp /Transfer/ = 0 );
|
||||
%Docstring
|
||||
Update the color ramp used. Also updates all symbols colors.
|
||||
Doesn't alter current breaks.
|
||||
|
||||
:param ramp: color ramp. Ownership is transferred to the renderer
|
||||
%End
|
||||
|
||||
void updateSymbols( QgsSymbol *sym );
|
||||
%Docstring
|
||||
Update all the symbols but leave breaks and colors. This method also sets the source
|
||||
symbol for the renderer.
|
||||
|
||||
:param sym: source symbol to use for classes. Ownership is not transferred.
|
||||
|
||||
.. seealso:: :py:func:`setSourceSymbol`
|
||||
%End
|
||||
|
||||
void setSymbolSizes( double minSize, double maxSize );
|
||||
%Docstring
|
||||
set varying symbol size for classes
|
||||
|
||||
.. note::
|
||||
|
||||
the classes must already be set so that symbols exist
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
double minSymbolSize() const;
|
||||
%Docstring
|
||||
return the min symbol size when graduated by size
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
double maxSymbolSize() const;
|
||||
%Docstring
|
||||
return the max symbol size when graduated by size
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
enum GraduatedMethod
|
||||
{
|
||||
GraduatedColor,
|
||||
GraduatedSize
|
||||
};
|
||||
|
||||
GraduatedMethod graduatedMethod() const;
|
||||
%Docstring
|
||||
return the method used for graduation (either size or color)
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
void setGraduatedMethod( GraduatedMethod method );
|
||||
%Docstring
|
||||
set the method used for graduation (either size or color)
|
||||
|
||||
.. versionadded:: 2.10
|
||||
%End
|
||||
|
||||
virtual bool legendSymbolItemsCheckable() const;
|
||||
|
||||
virtual bool legendSymbolItemChecked( const QString &key );
|
||||
|
||||
virtual void checkLegendSymbolItem( const QString &key, bool state = true );
|
||||
|
||||
virtual void setLegendSymbolItem( const QString &key, QgsSymbol *symbol /Transfer/ );
|
||||
|
||||
virtual QString legendClassificationAttribute() const;
|
||||
|
||||
static QgsGraduatedSymbolRenderer *convertFromRenderer( const QgsFeatureRenderer *renderer ) /Factory/;
|
||||
%Docstring
|
||||
creates a QgsGraduatedSymbolRenderer from an existing renderer.
|
||||
|
||||
:return: a new renderer if the conversion was possible, otherwise 0.
|
||||
|
||||
.. versionadded:: 2.6
|
||||
%End
|
||||
|
||||
void setDataDefinedSizeLegend( QgsDataDefinedSizeLegend *settings /Transfer/ );
|
||||
%Docstring
|
||||
Configures appearance of legend when renderer is configured to use data-defined size for marker symbols.
|
||||
This allows configuring for which values (symbol sizes) should be shown in the legend, whether to display
|
||||
different symbol sizes collapsed in one legend node or separated across multiple legend nodes etc.
|
||||
|
||||
When renderer does not use data-defined size or does not use marker symbols, these settings will be ignored.
|
||||
Takes ownership of the passed settings objects. Null pointer is a valid input that disables data-defined
|
||||
size legend.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QgsDataDefinedSizeLegend *dataDefinedSizeLegend() const;
|
||||
%Docstring
|
||||
Returns configuration of appearance of legend when using data-defined size for marker symbols.
|
||||
Will return null if the functionality is disabled.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
QgsSymbol *symbolForValue( double value );
|
||||
%Docstring
|
||||
attribute index (derived from attribute name in startRender)
|
||||
%End
|
||||
|
||||
QString legendKeyForValue( double value ) const;
|
||||
%Docstring
|
||||
Returns the matching legend key for a value.
|
||||
%End
|
||||
|
||||
|
||||
private:
|
||||
QgsGraduatedSymbolRenderer( const QgsGraduatedSymbolRenderer & );
|
||||
QgsGraduatedSymbolRenderer &operator=( const QgsGraduatedSymbolRenderer & );
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/symbology/qgsgraduatedsymbolrenderer.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
100
python/gui/symbology/qgsgraduatedsymbolrendererwidget.sip
Normal file
100
python/gui/symbology/qgsgraduatedsymbolrendererwidget.sip
Normal file
@ -0,0 +1,100 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/symbology/qgsgraduatedsymbolrendererwidget.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsGraduatedSymbolRendererWidget : QgsRendererWidget
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsgraduatedsymbolrendererwidget.h"
|
||||
%End
|
||||
public:
|
||||
static QgsRendererWidget *create( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer ) /Factory/;
|
||||
|
||||
QgsGraduatedSymbolRendererWidget( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer );
|
||||
~QgsGraduatedSymbolRendererWidget();
|
||||
|
||||
virtual QgsFeatureRenderer *renderer();
|
||||
|
||||
|
||||
public slots:
|
||||
void changeGraduatedSymbol();
|
||||
void graduatedColumnChanged( const QString &field );
|
||||
void classifyGraduated();
|
||||
void reapplyColorRamp();
|
||||
void reapplySizes();
|
||||
void rangesDoubleClicked( const QModelIndex &idx );
|
||||
void rangesClicked( const QModelIndex &idx );
|
||||
void changeCurrentValue( QStandardItem *item );
|
||||
|
||||
void addClass();
|
||||
%Docstring
|
||||
Adds a class manually to the classification
|
||||
%End
|
||||
void deleteClasses();
|
||||
%Docstring
|
||||
Removes currently selected classes
|
||||
%End
|
||||
void deleteAllClasses();
|
||||
%Docstring
|
||||
Removes all classes from the classification
|
||||
%End
|
||||
void toggleBoundariesLink( bool linked );
|
||||
%Docstring
|
||||
Toggle the link between classes boundaries
|
||||
%End
|
||||
|
||||
void labelFormatChanged();
|
||||
|
||||
void showSymbolLevels();
|
||||
|
||||
void rowsMoved();
|
||||
void modelDataChanged();
|
||||
void refreshRanges( bool reset = false );
|
||||
|
||||
protected:
|
||||
void updateUiFromRenderer( bool updateCount = true );
|
||||
void connectUpdateHandlers();
|
||||
void disconnectUpdateHandlers();
|
||||
bool rowsOrdered();
|
||||
|
||||
void updateGraduatedSymbolIcon();
|
||||
|
||||
QList<int> selectedClasses();
|
||||
%Docstring
|
||||
return a list of indexes for the classes under selection
|
||||
%End
|
||||
QgsRangeList selectedRanges();
|
||||
|
||||
void changeRangeSymbol( int rangeIdx );
|
||||
void changeRange( int rangeIdx );
|
||||
|
||||
void changeSelectedSymbols();
|
||||
|
||||
virtual QList<QgsSymbol *> selectedSymbols();
|
||||
|
||||
QgsSymbol *findSymbolForRange( double lowerBound, double upperBound, const QgsRangeList &ranges ) const;
|
||||
virtual void refreshSymbolView();
|
||||
|
||||
|
||||
virtual void keyPressEvent( QKeyEvent *event );
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/symbology/qgsgraduatedsymbolrendererwidget.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -288,7 +288,8 @@ QgsGraduatedSymbolRenderer::QgsGraduatedSymbolRenderer( const QString &attrName,
|
||||
{
|
||||
mRanges << range;
|
||||
}
|
||||
|
||||
mUseSymmetricMode = false;
|
||||
mAstride = false;
|
||||
}
|
||||
|
||||
QgsGraduatedSymbolRenderer::~QgsGraduatedSymbolRenderer()
|
||||
@ -484,6 +485,11 @@ QgsGraduatedSymbolRenderer *QgsGraduatedSymbolRenderer::clone() const
|
||||
{
|
||||
QgsGraduatedSymbolRenderer *r = new QgsGraduatedSymbolRenderer( mAttrName, mRanges );
|
||||
r->setMode( mMode );
|
||||
r->setUseSymmetricMode( mUseSymmetricMode );
|
||||
r->setSymmetryPoint( mSymmetryPoint );
|
||||
r->setListForCboPrettyBreaks( mListForCboPrettyBreaks );
|
||||
r->setAstride( mAstride );
|
||||
|
||||
if ( mSourceSymbol )
|
||||
r->setSourceSymbol( mSourceSymbol->clone() );
|
||||
if ( mSourceColorRamp )
|
||||
@ -525,29 +531,83 @@ QgsSymbolList QgsGraduatedSymbolRenderer::symbols( QgsRenderContext &context ) c
|
||||
return lst;
|
||||
}
|
||||
|
||||
static QList<double> _calcEqualIntervalBreaks( double minimum, double maximum, int classes )
|
||||
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 balanced around symmetryPoint
|
||||
// if astride is true, remove the symmetryPoint break so that
|
||||
// the 2 classes form only one
|
||||
|
||||
// Equal interval algorithm
|
||||
//
|
||||
// Returns breaks based on dividing the range ('minimum' to 'maximum')
|
||||
// into 'classes' parts.
|
||||
|
||||
double step = ( maximum - minimum ) / classes;
|
||||
|
||||
QList<double> breaks;
|
||||
double value = minimum;
|
||||
breaks.reserve( classes );
|
||||
for ( int i = 0; i < classes; i++ )
|
||||
if ( breaks.size() > 1 ) //to avoid crash when only 1 class
|
||||
{
|
||||
value += step;
|
||||
breaks.append( value );
|
||||
std::sort( breaks.begin(), breaks.end() );
|
||||
// breaks contain the maximum of the distrib but not the minimum
|
||||
double distBelowSymmetricValue = std::abs( breaks[0] - symmetryPoint );
|
||||
double distAboveSymmetricValue = std::abs( breaks[ breaks.size() - 2 ] - symmetryPoint ) ;
|
||||
double absMin = std::min( std::abs( distAboveSymmetricValue ), std::abs( distBelowSymmetricValue ) );
|
||||
// make symmetric
|
||||
for ( int i = 0; i <= breaks.size() - 2; ++i )
|
||||
{
|
||||
if ( std::abs( breaks.at( i ) - symmetryPoint ) > absMin )
|
||||
{
|
||||
breaks.removeAt( i );
|
||||
--i;
|
||||
}
|
||||
}
|
||||
// remove symmetry point
|
||||
if ( true == astride ) // && breaks.indexOf( symmetryPoint ) != -1) // if symmetryPoint is found
|
||||
{
|
||||
breaks.removeAt( breaks.indexOf( symmetryPoint ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// floating point arithmetics is not precise:
|
||||
// set the last break to be exactly maximum so we do not miss it
|
||||
breaks[classes - 1] = maximum;
|
||||
static QList<double> _calcEqualIntervalBreaks( double minimum, double maximum, int classes, bool useSymmetricMode, double symmetryPoint, bool astride )
|
||||
{
|
||||
// Equal interval algorithm
|
||||
// Returns breaks based on dividing the range ('minimum' to 'maximum') into 'classes' parts.
|
||||
QList<double> breaks;
|
||||
if ( false == useSymmetricMode ) // nomal mode
|
||||
{
|
||||
double step = ( maximum - minimum ) / classes;
|
||||
|
||||
double value = minimum;
|
||||
breaks.reserve( classes );
|
||||
for ( int i = 0; i < classes; i++ )
|
||||
{
|
||||
value += step;
|
||||
breaks.append( value );
|
||||
}
|
||||
// floating point arithmetics is not precise:
|
||||
// set the last break to be exactly maximum so we do not miss it
|
||||
breaks[classes - 1] = maximum;
|
||||
}
|
||||
else if ( true == useSymmetricMode ) // symmetric mode
|
||||
{
|
||||
double distBelowSymmetricValue = std::abs( minimum - symmetryPoint );
|
||||
double distAboveSymmetricValue = std::abs( maximum - symmetryPoint ) ;
|
||||
|
||||
if ( true == astride )
|
||||
{
|
||||
( 0 == classes % 2 ) ? ++classes : classes; // we want odd number of classes
|
||||
}
|
||||
else
|
||||
{
|
||||
( 1 == classes % 2 ) ? ++classes : classes; // we want even number of classes
|
||||
}
|
||||
double step = 2 * std::min( distBelowSymmetricValue, distAboveSymmetricValue ) / classes;
|
||||
|
||||
double value;
|
||||
breaks.reserve( classes );
|
||||
value = ( distBelowSymmetricValue < distAboveSymmetricValue ) ? minimum : maximum - classes * step;
|
||||
|
||||
for ( int i = 0; i < classes; i++ )
|
||||
{
|
||||
value += step;
|
||||
breaks.append( value );
|
||||
}
|
||||
breaks[classes - 1] = maximum;
|
||||
}
|
||||
return breaks;
|
||||
}
|
||||
|
||||
@ -593,7 +653,7 @@ static QList<double> _calcQuantileBreaks( QList<double> values, int classes )
|
||||
return breaks;
|
||||
}
|
||||
|
||||
static QList<double> _calcStdDevBreaks( QList<double> values, int classes, QList<double> &labels )
|
||||
static QList<double> _calcStdDevBreaks( QList<double> values, int classes, QList<double> &labels, bool useSymmetricMode, double symmetryPoint, bool astride )
|
||||
{
|
||||
|
||||
// C++ implementation of the standard deviation class interval algorithm
|
||||
@ -629,13 +689,17 @@ static QList<double> _calcStdDevBreaks( QList<double> values, int classes, QList
|
||||
}
|
||||
stdDev = std::sqrt( stdDev / n );
|
||||
|
||||
QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( ( minimum - mean ) / stdDev, ( maximum - mean ) / stdDev, classes );
|
||||
for ( int i = 0; i < breaks.count(); i++ )
|
||||
if ( false == useSymmetricMode )
|
||||
symmetryPoint = mean; // otherwise symmetryPoint = symmetryPoint
|
||||
|
||||
QList<double> breaks = QgsSymbolLayerUtils::prettyBreaks( ( minimum - symmetryPoint ) / stdDev, ( maximum - symmetryPoint ) / stdDev, classes );
|
||||
_makeBreaksSymmetric( breaks, 0.0, astride ); //0.0 because breaks where computed on a centered distribution
|
||||
|
||||
for ( int i = 0; i < breaks.count(); i++ ) //unNormalize breaks and put labels
|
||||
{
|
||||
labels.append( breaks[i] );
|
||||
breaks[i] = ( breaks[i] * stdDev ) + mean;
|
||||
breaks[i] = ( breaks[i] * stdDev ) + symmetryPoint;
|
||||
}
|
||||
|
||||
return breaks;
|
||||
} // _calcStdDevBreaks
|
||||
|
||||
@ -769,12 +833,25 @@ static QList<double> _calcJenksBreaks( QList<double> values, int classes,
|
||||
return breaks.toList();
|
||||
} //_calcJenksBreaks
|
||||
|
||||
static QStringList _breaksAsStrings( QList<double> breaks ) // get QStringList from QList<double> without maxi break (min is not in)
|
||||
{
|
||||
QStringList breaksAsTrings;
|
||||
for ( int i = 0; i < breaks.count() - 1; i++ )
|
||||
{
|
||||
breaksAsTrings << QString::number( breaks.at( i ), 'f', 2 );
|
||||
}
|
||||
return breaksAsTrings;
|
||||
}
|
||||
|
||||
QgsGraduatedSymbolRenderer *QgsGraduatedSymbolRenderer::createRenderer(
|
||||
QgsVectorLayer *vlayer,
|
||||
const QString &attrName,
|
||||
int classes,
|
||||
Mode mode,
|
||||
bool useSymmetricMode,
|
||||
double symmetryPoint,
|
||||
QStringList listForCboPrettyBreaks,
|
||||
bool astride,
|
||||
QgsSymbol *symbol,
|
||||
QgsColorRamp *ramp,
|
||||
const QgsRendererRangeLabelFormat &labelFormat
|
||||
@ -785,17 +862,25 @@ QgsGraduatedSymbolRenderer *QgsGraduatedSymbolRenderer::createRenderer(
|
||||
r->setSourceSymbol( symbol->clone() );
|
||||
r->setSourceColorRamp( ramp->clone() );
|
||||
r->setMode( mode );
|
||||
r->setUseSymmetricMode( useSymmetricMode );
|
||||
r->setSymmetryPoint( symmetryPoint );
|
||||
r->setListForCboPrettyBreaks( listForCboPrettyBreaks );
|
||||
r->setAstride( astride );
|
||||
r->setLabelFormat( labelFormat );
|
||||
r->updateClasses( vlayer, mode, classes );
|
||||
r->updateClasses( vlayer, mode, classes, useSymmetricMode, symmetryPoint, astride );
|
||||
return r;
|
||||
}
|
||||
|
||||
void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses )
|
||||
void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses,
|
||||
bool useSymmetricMode, double symmetryPoint, bool astride )
|
||||
{
|
||||
if ( mAttrName.isEmpty() )
|
||||
return;
|
||||
|
||||
setMode( mode );
|
||||
setSymmetryPoint( symmetryPoint );
|
||||
setUseSymmetricMode( useSymmetricMode );
|
||||
setAstride( astride );
|
||||
|
||||
// Custom classes are not recalculated
|
||||
if ( mode == Custom )
|
||||
return;
|
||||
@ -831,13 +916,18 @@ void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mod
|
||||
QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
|
||||
QList<double> breaks;
|
||||
QList<double> labels;
|
||||
|
||||
if ( mode == EqualInterval )
|
||||
{
|
||||
breaks = _calcEqualIntervalBreaks( minimum, maximum, nclasses );
|
||||
breaks = _calcEqualIntervalBreaks( minimum, maximum, nclasses, mUseSymmetricMode, symmetryPoint, astride );
|
||||
}
|
||||
else if ( mode == Pretty )
|
||||
{
|
||||
breaks = QgsSymbolLayerUtils::prettyBreaks( minimum, maximum, nclasses );
|
||||
setListForCboPrettyBreaks( _breaksAsStrings( breaks ) );
|
||||
|
||||
if ( true == useSymmetricMode )
|
||||
_makeBreaksSymmetric( breaks, symmetryPoint, astride );
|
||||
}
|
||||
else if ( mode == Quantile || mode == Jenks || mode == StdDev )
|
||||
{
|
||||
@ -846,20 +936,13 @@ void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mod
|
||||
{
|
||||
values = QgsVectorLayerUtils::getDoubleValues( vlayer, mAttrName, ok );
|
||||
}
|
||||
|
||||
// calculate the breaks
|
||||
if ( mode == Quantile )
|
||||
{
|
||||
breaks = _calcQuantileBreaks( values, nclasses );
|
||||
}
|
||||
else if ( mode == Jenks )
|
||||
{
|
||||
breaks = _calcJenksBreaks( values, nclasses, minimum, maximum );
|
||||
}
|
||||
else if ( mode == StdDev )
|
||||
{
|
||||
breaks = _calcStdDevBreaks( values, nclasses, labels );
|
||||
}
|
||||
breaks = _calcStdDevBreaks( values, nclasses, labels, mUseSymmetricMode, symmetryPoint, astride );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -871,7 +954,6 @@ void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mod
|
||||
deleteAllClasses();
|
||||
|
||||
// "breaks" list contains all values at class breaks plus maximum as last break
|
||||
|
||||
int i = 0;
|
||||
for ( QList<double>::iterator it = breaks.begin(); it != breaks.end(); ++it, ++i )
|
||||
{
|
||||
@ -904,6 +986,7 @@ void QgsGraduatedSymbolRenderer::updateClasses( QgsVectorLayer *vlayer, Mode mod
|
||||
updateColorRamp( nullptr );
|
||||
}
|
||||
|
||||
|
||||
QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, const QgsReadWriteContext &context )
|
||||
{
|
||||
QDomElement symbolsElem = element.firstChildElement( QStringLiteral( "symbols" ) );
|
||||
@ -989,6 +1072,21 @@ QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, co
|
||||
r->setMode( Pretty );
|
||||
}
|
||||
|
||||
// symmetric mode
|
||||
QDomElement symmetricModeElem = element.firstChildElement( QStringLiteral( "symmetricMode" ) );
|
||||
if ( !symmetricModeElem.isNull() )
|
||||
{
|
||||
QString symmetricEnabled = symmetricModeElem.attribute( QStringLiteral( "enabled" ) );
|
||||
symmetricEnabled == QLatin1String( "true" ) ? r->setUseSymmetricMode( true ) : r->setUseSymmetricMode( false );
|
||||
|
||||
QString symmetricPointString = symmetricModeElem.attribute( QStringLiteral( "symmetryPoint" ) );
|
||||
r->setSymmetryPoint( symmetricPointString.toDouble() );
|
||||
QString breaksForPretty = symmetricModeElem.attribute( QStringLiteral( "valueForCboPrettyBreaks" ) );
|
||||
r->setListForCboPrettyBreaks( breaksForPretty.split( "/" ) );
|
||||
|
||||
QString astrideEnabled = symmetricModeElem.attribute( QStringLiteral( "astride" ) );
|
||||
astrideEnabled == QLatin1String( "true" ) ? r->setAstride( true ) : r->setAstride( false );
|
||||
}
|
||||
QDomElement rotationElem = element.firstChildElement( QStringLiteral( "rotation" ) );
|
||||
if ( !rotationElem.isNull() && !rotationElem.attribute( QStringLiteral( "field" ) ).isEmpty() )
|
||||
{
|
||||
@ -1001,7 +1099,6 @@ QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, co
|
||||
convertSymbolRotation( r->mSourceSymbol.get(), rotationElem.attribute( QStringLiteral( "field" ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
QDomElement sizeScaleElem = element.firstChildElement( QStringLiteral( "sizescale" ) );
|
||||
if ( !sizeScaleElem.isNull() && !sizeScaleElem.attribute( QStringLiteral( "field" ) ).isEmpty() )
|
||||
{
|
||||
@ -1032,7 +1129,6 @@ QgsFeatureRenderer *QgsGraduatedSymbolRenderer::create( QDomElement &element, co
|
||||
{
|
||||
r->mDataDefinedSizeLegend.reset( QgsDataDefinedSizeLegend::readXml( ddsLegendSizeElem, context ) );
|
||||
}
|
||||
|
||||
// TODO: symbol levels
|
||||
return r;
|
||||
}
|
||||
@ -1108,6 +1204,25 @@ QDomElement QgsGraduatedSymbolRenderer::save( QDomDocument &doc, const QgsReadWr
|
||||
rendererElem.appendChild( modeElem );
|
||||
}
|
||||
|
||||
// symmetry
|
||||
QDomElement symmetricModeElem = doc.createElement( QStringLiteral( "symmetricMode" ) );
|
||||
symmetricModeElem.setAttribute( QStringLiteral( "enabled" ), mUseSymmetricMode ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
|
||||
symmetricModeElem.setAttribute( QStringLiteral( "symmetryPoint" ), mSymmetryPoint );
|
||||
symmetricModeElem.setAttribute( QStringLiteral( "astride" ), mAstride ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
|
||||
if ( Pretty == mMode )
|
||||
{
|
||||
QString breaks;
|
||||
for ( int i = 0; i < mListForCboPrettyBreaks.size() - 1; i++ ) // -1 to write 1/2/3 instead of 1/2/3/
|
||||
{
|
||||
breaks.append( mListForCboPrettyBreaks.at( i ) );
|
||||
breaks.append( QStringLiteral( "/" ) );
|
||||
}
|
||||
breaks.append( mListForCboPrettyBreaks.at( mListForCboPrettyBreaks.size() - 1 ) );
|
||||
symmetricModeElem.setAttribute( QStringLiteral( "valueForCboPrettyBreaks" ), breaks );
|
||||
}
|
||||
|
||||
rendererElem.appendChild( symmetricModeElem );
|
||||
|
||||
QDomElement rotationElem = doc.createElement( QStringLiteral( "rotation" ) );
|
||||
rendererElem.appendChild( rotationElem );
|
||||
|
||||
|
@ -222,14 +222,66 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
|
||||
Mode mode() const { return mMode; }
|
||||
void setMode( Mode mode ) { mMode = mode; }
|
||||
|
||||
/**
|
||||
* get mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
bool useSymmetricMode() { return mUseSymmetricMode; }
|
||||
|
||||
/**
|
||||
* set mUseSymmetricMode, which says if we want to classify symmetric around a given value
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void setUseSymmetricMode( bool useSymmetricMode ) { mUseSymmetricMode = useSymmetricMode; }
|
||||
|
||||
/**
|
||||
* get mSymmetryPoint, the pivot value for symmetric classification
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
double symmetryPoint() { return mSymmetryPoint; }
|
||||
|
||||
/**
|
||||
* set the pivot point
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void setSymmetryPoint( double symmetryPoint ) { mSymmetryPoint = symmetryPoint; }
|
||||
|
||||
/**
|
||||
* get mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
QStringList listForCboPrettyBreaks() { return mListForCboPrettyBreaks; }
|
||||
|
||||
/**
|
||||
* set mListForCboPrettyBreaks, which is need to recover this list in saved configuration, or when property window in closed and reopened
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void setListForCboPrettyBreaks( QStringList listForCboPrettyBreaks ) { mListForCboPrettyBreaks = listForCboPrettyBreaks; }
|
||||
|
||||
/**
|
||||
* get mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
bool astride() { return mAstride; }
|
||||
|
||||
/**
|
||||
* set mAstride, a bool saying if we want to have a central class astride the pivot value
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void setAstride( bool astride ) { mAstride = astride; }
|
||||
|
||||
/**
|
||||
* Recalculate classes for a layer
|
||||
* \param vlayer The layer being rendered (from which data values are calculated)
|
||||
* \param mode The calculation mode
|
||||
* \param nclasses The number of classes to calculate (approximate for some modes)
|
||||
* \since QGIS 2.6
|
||||
* \param useSymmetricMode A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
* \param symmetryPoint The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
* \param astride A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
* \since QGIS 3.2
|
||||
*/
|
||||
void updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses );
|
||||
void updateClasses( QgsVectorLayer *vlayer, Mode mode, int nclasses, bool useSymmetricMode = false, double symmetryPoint = 0.0, bool astride = false );
|
||||
|
||||
/**
|
||||
* Returns the label format used to generate default classification labels
|
||||
@ -258,6 +310,10 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
|
||||
* \param attrName attribute to classify
|
||||
* \param classes number of classes
|
||||
* \param mode classification mode
|
||||
* \param useSymmetricMode A bool indicating if we want to have classes and hence colors ramp symmetric around a value
|
||||
* \param symmetryPoint The value around which the classes will be symmetric if useSymmetricMode is checked
|
||||
* \param listForCboPrettyBreaks The list of potential pivot values for symmetric mode with prettybreaks mode
|
||||
* \param astride A bool indicating if the symmetry is made astride the symmetryPoint or not ( [-1,1] vs. [-1,0][0,1] )
|
||||
* \param symbol base symbol
|
||||
* \param ramp color ramp for classes
|
||||
* \param legendFormat
|
||||
@ -267,6 +323,10 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
|
||||
const QString &attrName,
|
||||
int classes,
|
||||
Mode mode,
|
||||
bool useSymmetricMode,
|
||||
double symmetryPoint,
|
||||
QStringList listForCboPrettyBreaks,
|
||||
bool astride,
|
||||
QgsSymbol *symbol SIP_TRANSFER,
|
||||
QgsColorRamp *ramp SIP_TRANSFER,
|
||||
const QgsRendererRangeLabelFormat &legendFormat = QgsRendererRangeLabelFormat() );
|
||||
@ -396,6 +456,10 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
|
||||
QString mAttrName;
|
||||
QgsRangeList mRanges;
|
||||
Mode mMode = Custom;
|
||||
bool mUseSymmetricMode;
|
||||
double mSymmetryPoint;
|
||||
QStringList mListForCboPrettyBreaks;
|
||||
bool mAstride;
|
||||
std::unique_ptr<QgsSymbol> mSourceSymbol;
|
||||
std::unique_ptr<QgsColorRamp> mSourceColorRamp;
|
||||
QgsRendererRangeLabelFormat mLabelFormat;
|
||||
@ -403,6 +467,7 @@ class CORE_EXPORT QgsGraduatedSymbolRenderer : public QgsFeatureRenderer
|
||||
std::unique_ptr<QgsExpression> mExpression;
|
||||
GraduatedMethod mGraduatedMethod = GraduatedColor;
|
||||
//! attribute index (derived from attribute name in startRender)
|
||||
|
||||
int mAttrNum = -1;
|
||||
bool mCounting = false;
|
||||
|
||||
|
@ -4068,6 +4068,24 @@ QList<double> QgsSymbolLayerUtils::prettyBreaks( double minimum, double maximum,
|
||||
breaks[breaks.count() - 1] = maximum;
|
||||
}
|
||||
|
||||
// because sometimes when number of classes is big,
|
||||
// break supposed to be at zero is something like -2.22045e-16
|
||||
if ( minimum < 0.0 && maximum > 0.0 ) //then there should be a zero somewhere
|
||||
{
|
||||
QList<double> breaksMinusZero; // compute difference "each break - 0"
|
||||
for ( int i = 0; i < breaks.count(); i++ )
|
||||
{
|
||||
breaksMinusZero.append( breaks[i] - 0.0 );
|
||||
}
|
||||
int posOfMin = 0;
|
||||
for ( int i = 1; i < breaks.count(); i++ ) // find position of minimal difference
|
||||
{
|
||||
if ( std::abs( breaksMinusZero[i] ) < std::abs( breaksMinusZero[i - 1] ) )
|
||||
posOfMin = i;
|
||||
}
|
||||
breaks[posOfMin] = 0.0;
|
||||
}
|
||||
|
||||
return breaks;
|
||||
}
|
||||
|
||||
|
@ -435,10 +435,7 @@ QgsExpressionContext QgsGraduatedSymbolRendererWidget::createExpressionContext()
|
||||
|
||||
QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLayer *layer, QgsStyle *style, QgsFeatureRenderer *renderer )
|
||||
: QgsRendererWidget( layer, style )
|
||||
|
||||
{
|
||||
|
||||
|
||||
// try to recognize the previous renderer
|
||||
// (null renderer means "no previous renderer")
|
||||
if ( renderer )
|
||||
@ -513,7 +510,6 @@ QgsGraduatedSymbolRendererWidget::QgsGraduatedSymbolRendererWidget( QgsVectorLay
|
||||
connect( btnDeleteAllClasses, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::deleteAllClasses );
|
||||
connect( btnGraduatedAdd, &QAbstractButton::clicked, this, &QgsGraduatedSymbolRendererWidget::addClass );
|
||||
connect( cbxLinkBoundaries, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::toggleBoundariesLink );
|
||||
|
||||
connect( mSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsGraduatedSymbolRendererWidget::mSizeUnitWidget_changed );
|
||||
|
||||
connectUpdateHandlers();
|
||||
@ -563,7 +559,6 @@ QgsFeatureRenderer *QgsGraduatedSymbolRendererWidget::renderer()
|
||||
}
|
||||
|
||||
// Connect/disconnect event handlers which trigger updating renderer
|
||||
|
||||
void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers()
|
||||
{
|
||||
connect( spinGraduatedClasses, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
@ -577,10 +572,14 @@ void QgsGraduatedSymbolRendererWidget::connectUpdateHandlers()
|
||||
|
||||
connect( mModel, &QgsGraduatedSymbolRendererModel::rowsMoved, this, &QgsGraduatedSymbolRendererWidget::rowsMoved );
|
||||
connect( mModel, &QAbstractItemModel::dataChanged, this, &QgsGraduatedSymbolRendererWidget::modelDataChanged );
|
||||
|
||||
connect( cbxClassifySymmetric, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
connect( cbxAstride, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
connect( cboSymmetryPointForPretty, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
connect( spinSymmetryPointForOtherMethods, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
}
|
||||
|
||||
// Connect/disconnect event handlers which trigger updating renderer
|
||||
|
||||
void QgsGraduatedSymbolRendererWidget::disconnectUpdateHandlers()
|
||||
{
|
||||
disconnect( spinGraduatedClasses, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
@ -594,17 +593,74 @@ void QgsGraduatedSymbolRendererWidget::disconnectUpdateHandlers()
|
||||
|
||||
disconnect( mModel, &QgsGraduatedSymbolRendererModel::rowsMoved, this, &QgsGraduatedSymbolRendererWidget::rowsMoved );
|
||||
disconnect( mModel, &QAbstractItemModel::dataChanged, this, &QgsGraduatedSymbolRendererWidget::modelDataChanged );
|
||||
|
||||
disconnect( cbxClassifySymmetric, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
disconnect( cbxAstride, &QAbstractButton::toggled, this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
disconnect( cboSymmetryPointForPretty, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
disconnect( spinSymmetryPointForOtherMethods, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsGraduatedSymbolRendererWidget::classifyGraduated );
|
||||
}
|
||||
|
||||
void QgsGraduatedSymbolRendererWidget::updateUiFromRenderer( bool updateCount )
|
||||
{
|
||||
disconnectUpdateHandlers();
|
||||
|
||||
updateGraduatedSymbolIcon();
|
||||
spinSymmetryPointForOtherMethods->setShowClearButton( false );
|
||||
|
||||
// update UI from the graduated renderer (update combo boxes, view)
|
||||
if ( mRenderer->mode() < cboGraduatedMode->count() )
|
||||
{
|
||||
cboGraduatedMode->setCurrentIndex( mRenderer->mode() );
|
||||
}
|
||||
|
||||
// symmetric classification
|
||||
if ( cboGraduatedMode->currentIndex() == 0 || cboGraduatedMode->currentIndex() == 3 ) // EqualInterval or StdDev
|
||||
{
|
||||
cbxClassifySymmetric->setVisible( true );
|
||||
cbxAstride->setVisible( true );
|
||||
cboSymmetryPointForPretty->setVisible( false );
|
||||
spinSymmetryPointForOtherMethods->setVisible( true );
|
||||
spinSymmetryPointForOtherMethods->setValue( mRenderer->symmetryPoint() );
|
||||
}
|
||||
else if ( cboGraduatedMode->currentIndex() == 4 ) // Pretty
|
||||
{
|
||||
cbxClassifySymmetric->setVisible( true );
|
||||
cbxAstride->setVisible( true );
|
||||
spinSymmetryPointForOtherMethods->setVisible( false );
|
||||
cboSymmetryPointForPretty->setVisible( true );
|
||||
cboSymmetryPointForPretty->clear();
|
||||
cboSymmetryPointForPretty->addItems( mRenderer->listForCboPrettyBreaks() );
|
||||
// replace the combobox on the good old value
|
||||
cboSymmetryPointForPretty->setCurrentText( QString::number( mRenderer->symmetryPoint(), 'f', 2 ) );
|
||||
}
|
||||
else // quantile or Jenks
|
||||
{
|
||||
cbxClassifySymmetric->setVisible( false );
|
||||
cbxAstride->setVisible( false );
|
||||
cboSymmetryPointForPretty->setVisible( false );
|
||||
spinSymmetryPointForOtherMethods->setVisible( false );
|
||||
spinSymmetryPointForOtherMethods->setValue( mRenderer->symmetryPoint() );
|
||||
}
|
||||
|
||||
if ( true == mRenderer->useSymmetricMode() )
|
||||
{
|
||||
cbxClassifySymmetric->setChecked( true );
|
||||
spinSymmetryPointForOtherMethods->setEnabled( true );
|
||||
cbxAstride->setEnabled( true );
|
||||
cboSymmetryPointForPretty->setEnabled( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
cbxClassifySymmetric->setChecked( false );
|
||||
spinSymmetryPointForOtherMethods->setEnabled( false );
|
||||
cbxAstride->setEnabled( false );
|
||||
cboSymmetryPointForPretty->setEnabled( false );
|
||||
}
|
||||
|
||||
if ( true == mRenderer->astride() )
|
||||
cbxAstride->setChecked( true );
|
||||
else
|
||||
cbxAstride->setChecked( false );
|
||||
|
||||
|
||||
// Only update class count if different - otherwise typing value gets very messy
|
||||
int nclasses = mRenderer->ranges().count();
|
||||
@ -796,7 +852,6 @@ void QgsGraduatedSymbolRendererWidget::applyChangeToSymbol()
|
||||
void QgsGraduatedSymbolRendererWidget::classifyGraduated()
|
||||
{
|
||||
QString attrName = mExpressionWidget->currentField();
|
||||
|
||||
int nclasses = spinGraduatedClasses->value();
|
||||
|
||||
std::unique_ptr<QgsColorRamp> ramp( btnColorRamp->colorRamp() );
|
||||
@ -807,16 +862,53 @@ void QgsGraduatedSymbolRendererWidget::classifyGraduated()
|
||||
}
|
||||
|
||||
QgsGraduatedSymbolRenderer::Mode mode;
|
||||
if ( cboGraduatedMode->currentIndex() == 0 )
|
||||
bool useSymmetricMode = false;
|
||||
bool astride = false;
|
||||
double symmetryPoint = 0.0;
|
||||
int attrNum = mLayer->fields().lookupField( attrName );
|
||||
double minimum = mLayer->minimumValue( attrNum ).toDouble();
|
||||
double maximum = mLayer->maximumValue( attrNum ).toDouble();
|
||||
spinSymmetryPointForOtherMethods->setMinimum( minimum );
|
||||
spinSymmetryPointForOtherMethods->setMaximum( maximum );
|
||||
|
||||
if ( cboGraduatedMode->currentIndex() == 0 ) // EqualInterval
|
||||
{
|
||||
mode = QgsGraduatedSymbolRenderer::EqualInterval;
|
||||
else if ( cboGraduatedMode->currentIndex() == 2 )
|
||||
if ( cbxClassifySymmetric->isChecked() )
|
||||
{
|
||||
useSymmetricMode = true;
|
||||
symmetryPoint = spinSymmetryPointForOtherMethods->value();
|
||||
cbxAstride->isChecked() ? astride = true : astride = false;
|
||||
}
|
||||
}
|
||||
else if ( cboGraduatedMode->currentIndex() == 2 ) // Jenks
|
||||
{
|
||||
mode = QgsGraduatedSymbolRenderer::Jenks;
|
||||
else if ( cboGraduatedMode->currentIndex() == 3 )
|
||||
}
|
||||
else if ( cboGraduatedMode->currentIndex() == 3 ) // StdDev
|
||||
{
|
||||
mode = QgsGraduatedSymbolRenderer::StdDev;
|
||||
else if ( cboGraduatedMode->currentIndex() == 4 )
|
||||
if ( cbxClassifySymmetric->isChecked() )
|
||||
{
|
||||
useSymmetricMode = true;
|
||||
symmetryPoint = spinSymmetryPointForOtherMethods->value();
|
||||
cbxAstride->isChecked() ? astride = true : astride = false;
|
||||
}
|
||||
}
|
||||
else if ( cboGraduatedMode->currentIndex() == 4 ) // Pretty
|
||||
{
|
||||
mode = QgsGraduatedSymbolRenderer::Pretty;
|
||||
if ( cbxClassifySymmetric->isChecked() )
|
||||
{
|
||||
useSymmetricMode = true;
|
||||
cbxAstride->isChecked() ? astride = true : astride = false;
|
||||
symmetryPoint = cboSymmetryPointForPretty->currentText().toDouble(); //selected number
|
||||
}
|
||||
}
|
||||
else // default should be quantile for now
|
||||
mode = QgsGraduatedSymbolRenderer::Quantile;
|
||||
{
|
||||
mode = QgsGraduatedSymbolRenderer::Quantile; // Quantile
|
||||
}
|
||||
|
||||
// Jenks is n^2 complexity, warn for big dataset (more than 50k records)
|
||||
// and give the user the chance to cancel
|
||||
@ -825,11 +917,12 @@ void QgsGraduatedSymbolRendererWidget::classifyGraduated()
|
||||
if ( QMessageBox::Cancel == QMessageBox::question( this, tr( "Apply Classification" ), tr( "Natural break classification (Jenks) is O(n2) complexity, your classification may take a long time.\nPress cancel to abort breaks calculation or OK to continue." ), QMessageBox::Cancel, QMessageBox::Ok ) )
|
||||
return;
|
||||
}
|
||||
|
||||
// create and set new renderer
|
||||
|
||||
mRenderer->setClassAttribute( attrName );
|
||||
mRenderer->setMode( mode );
|
||||
mRenderer->setUseSymmetricMode( useSymmetricMode );
|
||||
mRenderer->setSymmetryPoint( symmetryPoint );
|
||||
mRenderer->setAstride( astride );
|
||||
|
||||
if ( methodComboBox->currentIndex() == 0 )
|
||||
{
|
||||
@ -846,7 +939,8 @@ void QgsGraduatedSymbolRendererWidget::classifyGraduated()
|
||||
}
|
||||
|
||||
QApplication::setOverrideCursor( Qt::WaitCursor );
|
||||
mRenderer->updateClasses( mLayer, mode, nclasses );
|
||||
|
||||
mRenderer->updateClasses( mLayer, mode, nclasses, useSymmetricMode, symmetryPoint, astride );
|
||||
|
||||
if ( methodComboBox->currentIndex() == 1 )
|
||||
mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() );
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>442</width>
|
||||
<width>952</width>
|
||||
<height>554</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -206,7 +206,7 @@ Negative rounds to powers of 10</string>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="showClearButton">
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -238,7 +238,7 @@ Negative rounds to powers of 10</string>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
<property name="showClearButton">
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
@ -316,6 +316,9 @@ Negative rounds to powers of 10</string>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboGraduatedMode">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Equal Interval</string>
|
||||
@ -343,6 +346,9 @@ Negative rounds to powers of 10</string>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
@ -387,6 +393,80 @@ Negative rounds to powers of 10</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetDefaultConstraint</enum>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxClassifySymmetric">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="visible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Symmetric around:</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDoubleSpinBox" name="spinSymmetryPointForOtherMethods">
|
||||
<property name="specialValueText">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cboSymmetryPointForPretty"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbxAstride">
|
||||
<property name="text">
|
||||
<string>with a class astride that value</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user