PG raster: reset renderer when filter changes

This commit is contained in:
Alessandro Pasotti 2020-03-04 16:25:50 +01:00
parent 9815b2ae84
commit 385acae48c
4 changed files with 105 additions and 80 deletions

View File

@ -447,6 +447,7 @@ Emitted when the layer's subset string has changed.
virtual QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const;
};

View File

@ -815,6 +815,7 @@ void QgsRasterLayer::setDataProvider( QString const &provider, const QgsDataProv
QgsDebugMsgLevel( QStringLiteral( "exiting." ), 4 );
}
void QgsRasterLayer::setDataSource( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, bool loadDefaultStyleFlag )
@ -1142,97 +1143,105 @@ void QgsRasterLayer::refreshContrastEnhancement( const QgsRectangle &extent )
void QgsRasterLayer::refreshRendererIfNeeded( QgsRasterRenderer *rasterRenderer,
const QgsRectangle &extent )
{
if ( !( mDataProvider &&
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded != extent &&
rasterRenderer->minMaxOrigin().limits() != QgsRasterMinMaxOrigin::None &&
rasterRenderer->minMaxOrigin().extent() == QgsRasterMinMaxOrigin::UpdatedCanvas ) )
return;
QgsSingleBandGrayRenderer *singleBandRenderer = nullptr;
QgsMultiBandColorRenderer *multiBandRenderer = nullptr;
QgsSingleBandPseudoColorRenderer *sbpcr = nullptr;
const QgsContrastEnhancement *ce = nullptr;
if ( ( singleBandRenderer = dynamic_cast<QgsSingleBandGrayRenderer *>( rasterRenderer ) ) )
if ( mDataProvider &&
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded != extent &&
rasterRenderer->minMaxOrigin().limits() != QgsRasterMinMaxOrigin::None &&
rasterRenderer->minMaxOrigin().extent() == QgsRasterMinMaxOrigin::UpdatedCanvas )
{
ce = singleBandRenderer->contrastEnhancement();
refreshRenderer( rasterRenderer, extent );
}
else if ( ( multiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer *>( rasterRenderer ) ) )
{
ce = multiBandRenderer->redContrastEnhancement();
}
else if ( ( sbpcr = dynamic_cast<QgsSingleBandPseudoColorRenderer *>( rasterRenderer ) ) )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
double min;
double max;
computeMinMax( sbpcr->band(),
rasterRenderer->minMaxOrigin(),
rasterRenderer->minMaxOrigin().limits(), extent,
SAMPLE_SIZE, min, max );
sbpcr->setClassificationMin( min );
sbpcr->setClassificationMax( max );
}
if ( sbpcr->shader() )
void QgsRasterLayer::refreshRenderer( QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent )
{
if ( mDataProvider )
{
QgsSingleBandGrayRenderer *singleBandRenderer = nullptr;
QgsMultiBandColorRenderer *multiBandRenderer = nullptr;
QgsSingleBandPseudoColorRenderer *sbpcr = nullptr;
const QgsContrastEnhancement *ce = nullptr;
if ( ( singleBandRenderer = dynamic_cast<QgsSingleBandGrayRenderer *>( rasterRenderer ) ) )
{
QgsColorRampShader *colorRampShader = dynamic_cast<QgsColorRampShader *>( sbpcr->shader()->rasterShaderFunction() );
if ( colorRampShader )
ce = singleBandRenderer->contrastEnhancement();
}
else if ( ( multiBandRenderer = dynamic_cast<QgsMultiBandColorRenderer *>( rasterRenderer ) ) )
{
ce = multiBandRenderer->redContrastEnhancement();
}
else if ( ( sbpcr = dynamic_cast<QgsSingleBandPseudoColorRenderer *>( rasterRenderer ) ) )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
double min;
double max;
computeMinMax( sbpcr->band(),
rasterRenderer->minMaxOrigin(),
rasterRenderer->minMaxOrigin().limits(), extent,
SAMPLE_SIZE, min, max );
sbpcr->setClassificationMin( min );
sbpcr->setClassificationMax( max );
if ( sbpcr->shader() )
{
colorRampShader->classifyColorRamp( sbpcr->band(), extent, rasterRenderer->input() );
QgsColorRampShader *colorRampShader = dynamic_cast<QgsColorRampShader *>( sbpcr->shader()->rasterShaderFunction() );
if ( colorRampShader )
{
colorRampShader->classifyColorRamp( sbpcr->band(), extent, rasterRenderer->input() );
}
}
QgsSingleBandPseudoColorRenderer *r = dynamic_cast<QgsSingleBandPseudoColorRenderer *>( renderer() );
r->setClassificationMin( min );
r->setClassificationMax( max );
if ( r->shader() )
{
QgsColorRampShader *colorRampShader = dynamic_cast<QgsColorRampShader *>( r->shader()->rasterShaderFunction() );
if ( colorRampShader )
{
colorRampShader->classifyColorRamp( sbpcr->band(), extent, rasterRenderer->input() );
}
}
emit repaintRequested();
emit styleChanged();
emit rendererChanged();
return;
}
QgsSingleBandPseudoColorRenderer *r = dynamic_cast<QgsSingleBandPseudoColorRenderer *>( renderer() );
r->setClassificationMin( min );
r->setClassificationMax( max );
if ( r->shader() )
if ( ce &&
ce->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
{
QgsColorRampShader *colorRampShader = dynamic_cast<QgsColorRampShader *>( r->shader()->rasterShaderFunction() );
if ( colorRampShader )
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
setContrastEnhancement( ce->contrastEnhancementAlgorithm(),
rasterRenderer->minMaxOrigin().limits(),
extent,
SAMPLE_SIZE,
true,
rasterRenderer );
// Update main renderer so that the legends get updated
if ( singleBandRenderer )
static_cast<QgsSingleBandGrayRenderer *>( renderer() )->setContrastEnhancement( new QgsContrastEnhancement( * singleBandRenderer->contrastEnhancement() ) );
else if ( multiBandRenderer )
{
colorRampShader->classifyColorRamp( sbpcr->band(), extent, rasterRenderer->input() );
if ( multiBandRenderer->redContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setRedContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->redContrastEnhancement() ) );
}
if ( multiBandRenderer->greenContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setGreenContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->greenContrastEnhancement() ) );
}
if ( multiBandRenderer->blueContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setBlueContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->blueContrastEnhancement() ) );
}
}
emit styleChanged();
emit rendererChanged();
}
emit repaintRequested();
emit styleChanged();
emit rendererChanged();
return;
}
if ( ce &&
ce->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
{
mLastRectangleUsedByRefreshContrastEnhancementIfNeeded = extent;
setContrastEnhancement( ce->contrastEnhancementAlgorithm(),
rasterRenderer->minMaxOrigin().limits(),
extent,
SAMPLE_SIZE,
true,
rasterRenderer );
// Update main renderer so that the legends get updated
if ( singleBandRenderer )
static_cast<QgsSingleBandGrayRenderer *>( renderer() )->setContrastEnhancement( new QgsContrastEnhancement( * singleBandRenderer->contrastEnhancement() ) );
else if ( multiBandRenderer )
{
if ( multiBandRenderer->redContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setRedContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->redContrastEnhancement() ) );
}
if ( multiBandRenderer->greenContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setGreenContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->greenContrastEnhancement() ) );
}
if ( multiBandRenderer->blueContrastEnhancement() )
{
static_cast<QgsMultiBandColorRenderer *>( renderer() )->setBlueContrastEnhancement( new QgsContrastEnhancement( *multiBandRenderer->blueContrastEnhancement() ) );
}
}
emit styleChanged();
emit rendererChanged();
}
}
@ -1275,8 +1284,8 @@ bool QgsRasterLayer::setSubsetString( const QString &subset )
if ( res )
{
setExtent( mDataProvider->extent() );
refreshRenderer( renderer(), extent() );
emit subsetStringChanged();
triggerRepaint();
}
return res;

View File

@ -481,6 +481,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;
private:
//! \brief Initialize default values
void init();
@ -501,6 +502,9 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool generateLookupTableFlag,
QgsRasterRenderer *rasterRenderer );
//! Refresh renderer
void refreshRenderer( QgsRasterRenderer *rasterRenderer, const QgsRectangle &extent );
void computeMinMax( int band,
const QgsRasterMinMaxOrigin &mmo,
QgsRasterMinMaxOrigin::Limits limits,

View File

@ -281,6 +281,11 @@ class TestPyQgsPostgresRasterProvider(unittest.TestCase):
self.assertEqual(int(stats.minimumValue), 136)
self.assertEqual(int(stats.maximumValue), 169)
ce = rl.renderer().contrastEnhancement()
min_max = int(ce.minimumValue()), int(ce.maximumValue())
self.assertEqual(min_max, (136, 169))
# Change filter:
self.assertTrue(rl.setSubsetString('"pk" = 1'))
block = rl.dataProvider().block(1, rl.extent(), 2, 2)
data = []
@ -294,6 +299,12 @@ class TestPyQgsPostgresRasterProvider(unittest.TestCase):
self.assertEqual(int(stats.minimumValue), 136)
self.assertEqual(int(stats.maximumValue), 153)
# Check that the renderer has been updated
ce = rl.renderer().contrastEnhancement()
new_min_max = int(ce.minimumValue()), int(ce.maximumValue())
self.assertNotEqual(new_min_max, min_max)
self.assertEqual(new_min_max, (136, 153))
# Set invalid filter
self.assertFalse(rl.setSubsetString('"pk_wrong" = 1'))
block = rl.dataProvider().block(1, rl.extent(), 2, 2)