Skip to content
Permalink
Browse files

Raster shader: store label precision

  • Loading branch information
elpaso committed Nov 9, 2020
1 parent 58ce77f commit 02552e489a5f92e0ed73b39891b3461c78436267
@@ -113,11 +113,27 @@ Returns the minimum value for the raster shader.
virtual void legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems /Out/ ) const;
%Docstring
Returns legend symbology items if provided by renderer.
%End

int labelPrecision() const;
%Docstring
Returns label precision

.. versionadded:: 3.16
%End

void setLabelPrecision( int labelPrecision );
%Docstring
Sets label precision to ``labelPrecision``

.. versionadded:: 3.16
%End

protected:




};
/************************************************************************
* This file has been generated automatically from *
@@ -112,6 +112,7 @@ Loads min and max values from color ramp tree
%End

protected:

void populateColormapTreeWidget( const QList<QgsColorRampShader::ColorRampItem> &colorRampItems );
%Docstring
Populates color ramp tree from ramp items
@@ -507,6 +507,7 @@ QDomElement QgsColorRampShader::writeXml( QDomDocument &doc ) const
colorRampShaderElem.setAttribute( QStringLiteral( "clip" ), clip() );
colorRampShaderElem.setAttribute( QStringLiteral( "minimumValue" ), mMinimumValue );
colorRampShaderElem.setAttribute( QStringLiteral( "maximumValue" ), mMaximumValue );
colorRampShaderElem.setAttribute( QStringLiteral( "labelPrecision" ), mLabelPrecision );

// save source color ramp
if ( sourceColorRamp() )
@@ -544,6 +545,7 @@ void QgsColorRampShader::readXml( const QDomElement &colorRampShaderElem )
setClip( colorRampShaderElem.attribute( QStringLiteral( "clip" ), QStringLiteral( "0" ) ) == QLatin1String( "1" ) );
setMinimumValue( colorRampShaderElem.attribute( QStringLiteral( "minimumValue" ) ).toDouble() );
setMaximumValue( colorRampShaderElem.attribute( QStringLiteral( "maximumValue" ) ).toDouble() );
setLabelPrecision( colorRampShaderElem.attribute( QStringLiteral( "labelPrecision" ), QStringLiteral( "6" ) ).toDouble() );

QList<QgsColorRampShader::ColorRampItem> itemList;
QDomElement itemElem;
@@ -229,6 +229,7 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction

//! Do not render values out of range
bool mClip = false;

};

#endif
@@ -115,3 +115,4 @@ void QgsRasterShader::readXml( const QDomElement &elem )
setRasterShaderFunction( colorRampShader );
}
}

@@ -69,3 +69,14 @@ bool QgsRasterShaderFunction::shade( double redValue, double greenValue, double

return false;
}


int QgsRasterShaderFunction::labelPrecision() const
{
return mLabelPrecision;
}

void QgsRasterShaderFunction::setLabelPrecision( int labelPrecision )
{
mLabelPrecision = labelPrecision;
}
@@ -123,6 +123,18 @@ class CORE_EXPORT QgsRasterShaderFunction
*/
virtual void legendSymbologyItems( QList< QPair< QString, QColor > > &symbolItems SIP_OUT ) const { Q_UNUSED( symbolItems ) }

/**
* Returns label precision
* \since QGIS 3.16
*/
int labelPrecision() const;

/**
* Sets label precision to \a labelPrecision
* \since QGIS 3.16
*/
void setLabelPrecision( int labelPrecision );

protected:
//! \brief User defineable maximum value for the shading function
double mMaximumValue;
@@ -132,5 +144,9 @@ class CORE_EXPORT QgsRasterShaderFunction

//! \brief Minimum maximum range for the shading function
double mMinimumMaximumRange;

//! \brief Label precision
int mLabelPrecision = 6;

};
#endif
@@ -144,6 +144,7 @@ void QgsColorRampShaderWidget::setExtent( const QgsRectangle &extent )
QgsColorRampShader QgsColorRampShaderWidget::shader() const
{
QgsColorRampShader colorRampShader( mMin, mMax );
colorRampShader.setLabelPrecision( mLabelPrecisionSpinBox->value() );
colorRampShader.setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) );
colorRampShader.setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) );
colorRampShader.setClip( mClipCheckBox->isChecked() );
@@ -183,57 +184,9 @@ void QgsColorRampShaderWidget::autoLabel()
dumpClasses();
#endif

QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() );
bool discrete = interpolation == QgsColorRampShader::Discrete;
QString unit = mUnitLineEdit->text();
QString label;
const QString unit = mUnitLineEdit->text();
int topLevelItemCount = mColormapTreeWidget->topLevelItemCount();

auto applyPrecision = [ = ]( const QString & value )
{
Qgis::DataType dataType { mRasterDataProvider ? mRasterDataProvider->dataType( mBand ) : Qgis::DataType::Float64 };
switch ( dataType )
{
case Qgis::DataType::Int16:
case Qgis::DataType::UInt16:
case Qgis::DataType::Int32:
case Qgis::DataType::UInt32:
case Qgis::DataType::Byte:
case Qgis::DataType::CInt16:
case Qgis::DataType::CInt32:
case Qgis::DataType::ARGB32:
case Qgis::DataType::ARGB32_Premultiplied:
{
return QLocale().toString( QLocale().toLongLong( value ) );
}
case Qgis::DataType::Float32:
case Qgis::DataType::CFloat32:
{
double val { value.toFloat( ) };
if ( mLabelPrecisionSpinBox->value() < 0 )
{
const double factor = std::pow( 10, - mLabelPrecisionSpinBox->value() );
val = static_cast<qlonglong>( val / factor ) * factor;
return QLocale().toString( val, 'f', 0 );
}
return QLocale().toString( val, 'f', mLabelPrecisionSpinBox->value() );
}
case Qgis::DataType::Float64:
case Qgis::DataType::CFloat64:
case Qgis::DataType::UnknownDataType:
{
double val { value.toDouble( ) };
if ( mLabelPrecisionSpinBox->value() < 0 )
{
const double factor = std::pow( 10, - mLabelPrecisionSpinBox->value() );
val = static_cast<qlonglong>( val / factor ) * factor;
return QLocale().toString( val, 'f', 0 );
}
return QLocale().toString( val, 'f', mLabelPrecisionSpinBox->value() );
}
}
};

QTreeWidgetItem *currentItem = nullptr;
for ( int i = 0; i < topLevelItemCount; ++i )
{
@@ -244,29 +197,11 @@ void QgsColorRampShaderWidget::autoLabel()
continue;
}

if ( discrete )
{
if ( i == 0 )
{
label = "<= " + applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
else if ( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toDouble( ) == std::numeric_limits<double>::infinity() )
{
label = "> " + applyPrecision( mColormapTreeWidget->topLevelItem( i - 1 )->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
else
{
label = applyPrecision( mColormapTreeWidget->topLevelItem( i - 1 )->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + " - " + applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
}
else
{
label = applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
const QString lbl = label( currentItem, i, unit );

if ( currentItem->text( LabelColumn ).isEmpty() || currentItem->text( LabelColumn ) == label || currentItem->foreground( LabelColumn ).color() == QColor( Qt::gray ) )
if ( currentItem->text( LabelColumn ).isEmpty() || currentItem->text( LabelColumn ) == lbl || currentItem->foreground( LabelColumn ).color() == QColor( Qt::gray ) )
{
currentItem->setText( LabelColumn, label );
currentItem->setText( LabelColumn, lbl );
currentItem->setForeground( LabelColumn, QBrush( QColor( Qt::gray ) ) );
}
}
@@ -496,23 +431,38 @@ void QgsColorRampShaderWidget::populateColormapTreeWidget( const QList<QgsColorR
{
mColormapTreeWidget->clear();
QList<QgsColorRampShader::ColorRampItem>::const_iterator it = colorRampItems.constBegin();
int i = 0;
for ( ; it != colorRampItems.constEnd(); ++it )
{
QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget );
newItem->setText( ValueColumn, QLocale().toString( it->value, 'g', 15 ) );
newItem->setData( ValueColumn, Qt::ItemDataRole::DisplayRole, it->value );
newItem->setData( ColorColumn, Qt::ItemDataRole::EditRole, it->color );
newItem->setText( LabelColumn, it->label );
newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable );
connect( newItem, &QgsTreeWidgetItemObject::itemEdited,
this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited );
++i;
}

#ifdef QGISDEBUG
dumpClasses();
#endif

setUnitFromLabels();

// Now we have the suffix
const QString unit = mUnitLineEdit->text();
for ( i = 0; i < mColormapTreeWidget->topLevelItemCount(); i++ )
{
QgsTreeWidgetItemObject *currentItem { static_cast<QgsTreeWidgetItemObject *>( mColormapTreeWidget->topLevelItem( i ) ) };
QString lbl { label( currentItem, i, unit )};
if ( currentItem->text( LabelColumn ).isEmpty() || currentItem->text( LabelColumn ) == lbl || currentItem->foreground( LabelColumn ).color() == QColor( Qt::gray ) )
{
currentItem->setText( LabelColumn, lbl );
currentItem->setForeground( LabelColumn, QBrush( QColor( Qt::gray ) ) );
}
}

}

void QgsColorRampShaderWidget::mLoadFromBandButton_clicked()
@@ -675,6 +625,8 @@ void QgsColorRampShaderWidget::setFromShader( const QgsColorRampShader &colorRam
btnColorRamp->setColorRampFromName( defaultPalette );
}

mLabelPrecisionSpinBox->setValue( colorRampShader.labelPrecision() );

populateColormapTreeWidget( colorRampShader.colorRampItemList() );

emit widgetChanged();
@@ -787,6 +739,81 @@ void QgsColorRampShaderWidget::resetClassifyButton()
}
}

QString QgsColorRampShaderWidget::label( QTreeWidgetItem *currentItem, bool row, const QString unit )
{
auto applyPrecision = [ = ]( const QString & value )
{
Qgis::DataType dataType { mRasterDataProvider ? mRasterDataProvider->dataType( mBand ) : Qgis::DataType::Float64 };
switch ( dataType )
{
case Qgis::DataType::Int16:
case Qgis::DataType::UInt16:
case Qgis::DataType::Int32:
case Qgis::DataType::UInt32:
case Qgis::DataType::Byte:
case Qgis::DataType::CInt16:
case Qgis::DataType::CInt32:
case Qgis::DataType::ARGB32:
case Qgis::DataType::ARGB32_Premultiplied:
{
return QLocale().toString( QLocale().toLongLong( value ) );
}
case Qgis::DataType::Float32:
case Qgis::DataType::CFloat32:
{
double val { value.toFloat( ) };
if ( mLabelPrecisionSpinBox->value() < 0 )
{
const double factor = std::pow( 10, - mLabelPrecisionSpinBox->value() );
val = static_cast<qlonglong>( val / factor ) * factor;
return QLocale().toString( val, 'f', 0 );
}
return QLocale().toString( val, 'f', mLabelPrecisionSpinBox->value() );
}
case Qgis::DataType::Float64:
case Qgis::DataType::CFloat64:
case Qgis::DataType::UnknownDataType:
{
double val { value.toDouble( ) };
if ( mLabelPrecisionSpinBox->value() < 0 )
{
const double factor = std::pow( 10, - mLabelPrecisionSpinBox->value() );
val = static_cast<qlonglong>( val / factor ) * factor;
return QLocale().toString( val, 'f', 0 );
}
return QLocale().toString( val, 'f', mLabelPrecisionSpinBox->value() );
}
}
};

QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() );
bool discrete = interpolation == QgsColorRampShader::Discrete;
QString lbl;

if ( discrete )
{
if ( row == 0 )
{
lbl = "<= " + applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
else if ( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toDouble( ) == std::numeric_limits<double>::infinity() )
{
lbl = "> " + applyPrecision( mColormapTreeWidget->topLevelItem( row - 1 )->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
else
{
lbl = applyPrecision( mColormapTreeWidget->topLevelItem( row - 1 )->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + " - " + applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}
}
else
{
lbl = applyPrecision( currentItem->data( ValueColumn, Qt::ItemDataRole::DisplayRole ).toString() ) + unit;
}

return lbl;

}

void QgsColorRampShaderWidget::changeColor()
{
QList<QTreeWidgetItem *> itemList;
@@ -102,6 +102,7 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
void loadMinimumMaximumFromTree();

protected:

//! Populates color ramp tree from ramp items
void populateColormapTreeWidget( const QList<QgsColorRampShader::ColorRampItem> &colorRampItems );

@@ -150,6 +151,8 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo
double lineEditValue( const QLineEdit *lineEdit ) const;
void resetClassifyButton();

QString label( QTreeWidgetItem *item, bool row, const QString unit );

#ifdef QGISDEBUG
//! Dump all the classes for debugging purposes
void dumpClasses();

0 comments on commit 02552e4

Please sign in to comment.
You can’t perform that action at this time.