qgsrasterrenderer: Introduce refresh

This is similar to what is achieved in
`QgsRasterLayer::refreshRenderer()` to refresh the renderer according
to an extent. Contrary to the first one, this method does not perform
any GUI update or emit any signal.

It is not used at the moment. This will replace the logic to refresh a
renderer in the following commits.
This commit is contained in:
Jean Felder 2024-11-20 16:04:59 +01:00 committed by Nyall Dawson
parent 2747710499
commit dd36eb7249
16 changed files with 168 additions and 0 deletions

View File

@ -129,6 +129,7 @@ Ownership of the enhancement is transferred.
virtual void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props = QVariantMap() ) const;
private:
QgsMultiBandColorRenderer( const QgsMultiBandColorRenderer & );
const QgsMultiBandColorRenderer &operator=( const QgsMultiBandColorRenderer & );

View File

@ -222,6 +222,7 @@ should be canceled.
%End
protected:
void _writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const;

View File

@ -107,6 +107,7 @@ Ownership of ``settings`` is transferred.
.. versionadded:: 3.18
%End
private:
QgsSingleBandGrayRenderer( const QgsSingleBandGrayRenderer & );
const QgsSingleBandGrayRenderer &operator=( const QgsSingleBandGrayRenderer & );

View File

@ -120,6 +120,7 @@ Sets the band used by the renderer.
void setClassificationMin( double min );
void setClassificationMax( double max );
private:
QgsSingleBandPseudoColorRenderer( const QgsSingleBandPseudoColorRenderer & );
const QgsSingleBandPseudoColorRenderer &operator=( const QgsSingleBandPseudoColorRenderer & );

View File

@ -129,6 +129,7 @@ Ownership of the enhancement is transferred.
virtual void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props = QVariantMap() ) const;
private:
QgsMultiBandColorRenderer( const QgsMultiBandColorRenderer & );
const QgsMultiBandColorRenderer &operator=( const QgsMultiBandColorRenderer & );

View File

@ -222,6 +222,7 @@ should be canceled.
%End
protected:
void _writeXml( QDomDocument &doc, QDomElement &rasterRendererElem ) const;

View File

@ -107,6 +107,7 @@ Ownership of ``settings`` is transferred.
.. versionadded:: 3.18
%End
private:
QgsSingleBandGrayRenderer( const QgsSingleBandGrayRenderer & );
const QgsSingleBandGrayRenderer &operator=( const QgsSingleBandGrayRenderer & );

View File

@ -120,6 +120,7 @@ Sets the band used by the renderer.
void setClassificationMin( double min );
void setClassificationMax( double max );
private:
QgsSingleBandPseudoColorRenderer( const QgsSingleBandPseudoColorRenderer & );
const QgsSingleBandPseudoColorRenderer &operator=( const QgsSingleBandPseudoColorRenderer & );

View File

@ -589,3 +589,43 @@ void QgsMultiBandColorRenderer::toSld( QDomDocument &doc, QDomElement &element,
}
}
}
bool QgsMultiBandColorRenderer::refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh )
{
if ( !needsRefresh( extent ) && !forceRefresh )
{
return false;
}
bool refreshed = false;
if ( min.size() >= 3 && max.size() >= 3 )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
if ( mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement &&
!std::isnan( min[0] ) && !std::isnan( max[0] ) )
{
mRedContrastEnhancement->setMinimumValue( min[0] );
mRedContrastEnhancement->setMaximumValue( max[0] );
refreshed = true;
}
if ( mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement &&
!std::isnan( min[1] ) && !std::isnan( max[1] ) )
{
mGreenContrastEnhancement->setMinimumValue( min[1] );
mGreenContrastEnhancement->setMaximumValue( max[1] );
refreshed = true;
}
if ( mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement &&
!std::isnan( min[2] ) && !std::isnan( max[2] ) )
{
mBlueContrastEnhancement->setMinimumValue( min[2] );
mBlueContrastEnhancement->setMaximumValue( max[2] );
refreshed = true;
}
}
return refreshed;
}

View File

@ -123,6 +123,22 @@ class CORE_EXPORT QgsMultiBandColorRenderer: public QgsRasterRenderer
void toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props = QVariantMap() ) const override;
/**
* \brief Refreshes the renderer according to the \a min and \a max values associated with the \a extent.
* \a min and \a max size need to be at least 3.
* If \a min or \a max size is greater than 3, the last values are ignored.
* The first value is associated with the red contrast.
* The second value is associated with the green contrast.
* The third value is associated with the blue contrast.
* NaN values are ignored.
* If \a forceRefresh is TRUE, this will force the refresh even if needsRefresh() returns FALSE.
* \returns TRUE if the renderer has been refreshed
* \note not available in Python bindings
*
* \since QGIS 3.42
*/
bool refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh = false ) override SIP_SKIP;
private:
#ifdef SIP_RUN
QgsMultiBandColorRenderer( const QgsMultiBandColorRenderer & );

View File

@ -256,3 +256,14 @@ bool QgsRasterRenderer::needsRefresh( const QgsRectangle &extent ) const
return false;
}
bool QgsRasterRenderer::refresh( const QgsRectangle &extent, const QList<double> &, const QList<double> &, bool forceRefresh )
{
if ( !needsRefresh( extent ) && !forceRefresh )
{
return false;
}
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
return true;
}

View File

@ -231,6 +231,16 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
*/
bool needsRefresh( const QgsRectangle &extent ) const SIP_SKIP;
/**
* \brief Refreshes the renderer according to the \a min and \a max values associated with the \a extent.
* If \a forceRefresh is TRUE, this will force the refresh even if needsRefresh() returns FALSE.
* \returns TRUE if the renderer has been refreshed
* \note not available in Python bindings
*
* \since QGIS 3.42
*/
virtual bool refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh = false ) SIP_SKIP;
protected:
//! Write upper class info into rasterrenderer element (called by writeXml method of subclasses)
@ -262,6 +272,7 @@ class CORE_EXPORT QgsRasterRenderer : public QgsRasterInterface
*/
QRgb renderColorForNodataPixel() const;
//! To save computations and possible infinite cycle of notifications
QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded;
private:

View File

@ -458,3 +458,23 @@ void QgsSingleBandGrayRenderer::setLegendSettings( QgsColorRampLegendNodeSetting
return;
mLegendSettings.reset( settings );
}
bool QgsSingleBandGrayRenderer::refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh )
{
if ( !needsRefresh( extent ) && !forceRefresh )
{
return false;
}
bool refreshed = false;
if ( mContrastEnhancement && mContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement &&
min.size() >= 1 && max.size() >= 1 )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
mContrastEnhancement->setMinimumValue( min[0] );
mContrastEnhancement->setMaximumValue( max[0] );
refreshed = true;
}
return refreshed;
}

View File

@ -102,6 +102,17 @@ class CORE_EXPORT QgsSingleBandGrayRenderer: public QgsRasterRenderer
*/
void setLegendSettings( QgsColorRampLegendNodeSettings *settings SIP_TRANSFER );
/**
* \brief Refreshes the renderer according to the \a min and \a max values associated with the \a extent.
* If \a min or \a max size is greater than 1, the last values are ignored.
* If \a forceRefresh is TRUE, this will force the refresh even if needsRefresh() returns FALSE.
* \returns TRUE if the renderer has been refreshed
* \note not available in Python bindings
*
* \since QGIS 3.42
*/
bool refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh = false ) override SIP_SKIP;
private:
#ifdef SIP_RUN
QgsSingleBandGrayRenderer( const QgsSingleBandGrayRenderer & );

View File

@ -493,3 +493,42 @@ bool QgsSingleBandPseudoColorRenderer::canCreateRasterAttributeTable() const
return true;
}
bool QgsSingleBandPseudoColorRenderer::refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool force )
{
if ( !needsRefresh( extent ) && !force )
{
return false;
}
bool refreshed = false;
if ( min.size() >= 1 && max.size() >= 1 )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
// Do not overwrite min/max with NaN if they were already set,
// for example when the style was already loaded from a raster attribute table
// in that case we need to respect the style from the attribute table and do
// not perform any reclassification.
bool refreshed = false;
if ( !std::isnan( min[0] ) )
{
setClassificationMin( min[0] );
refreshed = true;
}
if ( !std::isnan( max[0] ) )
{
setClassificationMax( max[0] );
refreshed = true;
}
QgsColorRampShader *rampShader = dynamic_cast<QgsColorRampShader *>( mShader->rasterShaderFunction() );
if ( rampShader && refreshed )
{
rampShader->classifyColorRamp( mBand, extent, input() );
}
}
return refreshed;
}

View File

@ -107,6 +107,18 @@ class CORE_EXPORT QgsSingleBandPseudoColorRenderer: public QgsRasterRenderer
void setClassificationMin( double min );
void setClassificationMax( double max );
/**
* \brief Refreshes the renderer according to the \a min and \a max values associated with the \a extent.
* If \a min or \a max size is greater than 1, the last values are ignored.
* NaN values are ignored.
* If \a forceRefresh is TRUE, this will force the refresh even if needsRefresh() returns FALSE.
* \returns TRUE if the renderer has been refreshed
* \note not available in Python bindings
*
* \since QGIS 3.42
*/
bool refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh = false ) override SIP_SKIP;
private:
#ifdef SIP_RUN
QgsSingleBandPseudoColorRenderer( const QgsSingleBandPseudoColorRenderer & );