Skip to content
Permalink
Browse files

Proxy QgsRasterLayer::setOpacity/opacity to QgsRasterRenderer::setOpa…

…city

This allows layer opacity for raster layers to be set and retrieved using
the exact same API as all other map layer types
  • Loading branch information
nyalldawson committed Nov 13, 2020
1 parent 77bc748 commit 0056bb15808fb6651b1c745624b95a978e905f29
@@ -450,7 +450,7 @@ Returns the current blending mode for a layer.
.. seealso:: :py:func:`setBlendMode`
%End

void setOpacity( double opacity );
virtual void setOpacity( double opacity );
%Docstring
Sets the ``opacity`` for the layer, where ``opacity`` is a value between 0 (totally transparent)
and 1.0 (fully opaque).
@@ -466,7 +466,7 @@ and 1.0 (fully opaque).
.. versionadded:: 3.18
%End

double opacity() const;
virtual double opacity() const;
%Docstring
Returns the opacity for the layer, where opacity is a value between 0 (totally transparent)
and 1.0 (fully opaque).
@@ -338,6 +338,11 @@ In a world file, this is normally the first row (without the sign).
.. seealso:: :py:func:`rasterUnitsPerPixelX`
%End

virtual void setOpacity( double opacity ) ${SIP_FINAL};

virtual double opacity() const ${SIP_FINAL};


void setContrastEnhancement( QgsContrastEnhancement::ContrastEnhancementAlgorithm algorithm,
QgsRasterMinMaxOrigin::Limits limits = QgsRasterMinMaxOrigin::MinMax,
const QgsRectangle &extent = QgsRectangle(),
@@ -483,7 +483,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \note Prior to QGIS 3.18, this method was available for vector layers only
* \since QGIS 3.18
*/
void setOpacity( double opacity );
virtual void setOpacity( double opacity );

/**
* Returns the opacity for the layer, where opacity is a value between 0 (totally transparent)
@@ -493,7 +493,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \note Prior to QGIS 3.18, this method was available for vector layers only
* \since QGIS 3.18
*/
double opacity() const;
virtual double opacity() const;

//! Returns if this layer is read only.
bool readOnly() const { return isReadOnly(); }
@@ -78,7 +78,7 @@ QHash<QgsMapLayer *, int> QgsMapRendererJob::perLayerRenderingTime() const
QHash<QgsMapLayer *, int> result;
for ( auto it = mPerLayerRenderingTime.constBegin(); it != mPerLayerRenderingTime.constEnd(); ++it )
{
if ( auto && lKey = it.key() )
if ( auto &&lKey = it.key() )
result.insert( lKey, it.value() );
}
return result;
@@ -395,7 +395,10 @@ LayerRenderJobs QgsMapRendererJob::prepareJobs( QPainter *painter, QgsLabelingEn
styleOverride.setOverrideStyle( mSettings.layerStyleOverrides().value( ml->id() ) );

job.blendMode = ml->blendMode();
job.opacity = ml->opacity();

// raster layer opacity is handled directly within the raster layer renderer, so don't
// apply default opacity handling here!
job.opacity = ml->type() != QgsMapLayerType::RasterLayer ? ml->opacity() : 1.0;

// if we can use the cache, let's do it and avoid rendering!
if ( mCache && mCache->hasCacheImage( ml->id() ) )
@@ -590,6 +590,21 @@ double QgsRasterLayer::rasterUnitsPerPixelY() const
return 1;
}

void QgsRasterLayer::setOpacity( double opacity )
{
if ( !mPipe.renderer() || mPipe.renderer()->opacity() == opacity )
return;

mPipe.renderer()->setOpacity( opacity );
emit opacityChanged( opacity );
emit styleChanged();
}

double QgsRasterLayer::opacity() const
{
return mPipe.renderer() ? mPipe.renderer()->opacity() : 1.0;
}

void QgsRasterLayer::init()
{
mRasterType = QgsRasterLayer::GrayOrUndefined;
@@ -379,6 +379,9 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
*/
double rasterUnitsPerPixelY() const;

void setOpacity( double opacity ) FINAL;
double opacity() const FINAL;

/**
* \brief Set contrast enhancement algorithm
* \param algorithm Contrast enhancement algorithm
@@ -20,11 +20,7 @@
#include <QLabel>
#include <QSlider>
#include <QTimer>

#include "qgsrasterlayer.h"
#include "qgsrasterrenderer.h"
#include "qgsvectorlayer.h"

#include "qgsmaplayer.h"

///@cond PRIVATE

@@ -58,27 +54,8 @@ QgsLayerTreeOpacityWidget::QgsLayerTreeOpacityWidget( QgsMapLayer *layer )
connect( mSlider, &QAbstractSlider::valueChanged, this, &QgsLayerTreeOpacityWidget::sliderValueChanged );

// init from layer
switch ( mLayer->type() )
{
case QgsMapLayerType::VectorLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
{
mSlider->setValue( mLayer->opacity() * 1000.0 );
connect( mLayer, &QgsMapLayer::opacityChanged, this, &QgsLayerTreeOpacityWidget::layerTrChanged );
break;
}

case QgsMapLayerType::RasterLayer:
{
mSlider->setValue( qobject_cast<QgsRasterLayer *>( mLayer )->renderer()->opacity() * 1000 );
// TODO: there is no signal for raster layers
break;
}
}
mSlider->setValue( mLayer->opacity() * 1000.0 );
connect( mLayer, &QgsMapLayer::opacityChanged, this, &QgsLayerTreeOpacityWidget::layerTrChanged );
}

QSize QgsLayerTreeOpacityWidget::sizeHint() const
@@ -99,27 +76,7 @@ void QgsLayerTreeOpacityWidget::sliderValueChanged( int value )
void QgsLayerTreeOpacityWidget::updateOpacityFromSlider()
{
int value = mSlider->value();

switch ( mLayer->type() )
{
case QgsMapLayerType::VectorLayer:
case QgsMapLayerType::PluginLayer:
case QgsMapLayerType::MeshLayer:
case QgsMapLayerType::VectorTileLayer:
case QgsMapLayerType::AnnotationLayer:
case QgsMapLayerType::PointCloudLayer:
{
mLayer->setOpacity( value / 1000.0 );
break;
}

case QgsMapLayerType::RasterLayer:
{
qobject_cast<QgsRasterLayer *>( mLayer )->renderer()->setOpacity( value / 1000.0 );
break;
}
}

mLayer->setOpacity( value / 1000.0 );
mLayer->triggerRepaint();
}

@@ -94,6 +94,7 @@ class TestQgsRasterLayer : public QObject
void singleBandPseudoRendererNoData();
void singleBandPseudoRendererNoDataColor();
void setRenderer();
void setLayerOpacity();
void regression992(); //test for issue #992 - GeoJP2 images improperly displayed as all black
void testRefreshRendererIfNeeded();
void sample();
@@ -897,6 +898,26 @@ void TestQgsRasterLayer::setRenderer()
QCOMPARE( mpRasterLayer->renderer(), renderer );
}

void TestQgsRasterLayer::setLayerOpacity()
{
QSignalSpy spy( mpRasterLayer, &QgsMapLayer::opacityChanged );

mpRasterLayer->setOpacity( 0.5 );
QCOMPARE( spy.count(), 1 );
QCOMPARE( spy.at( 0 ).at( 0 ).toDouble(), 0.5 );
QCOMPARE( mpRasterLayer->opacity(), 0.5 );
// QgsRasterLayer::setOpacity is a proxy to QgsRasterRenderer::setOpacity
QCOMPARE( mpRasterLayer->renderer()->opacity(), 0.5 );

mpRasterLayer->setOpacity( 0.5 );
QCOMPARE( spy.count(), 1 );
mpRasterLayer->setOpacity( 1.0 );
QCOMPARE( spy.count(), 2 );
QCOMPARE( spy.at( 1 ).at( 0 ).toDouble(), 1.0 );
QCOMPARE( mpRasterLayer->opacity(), 1.0 );
QCOMPARE( mpRasterLayer->renderer()->opacity(), 1.0 );
}

void TestQgsRasterLayer::regression992()
{
if ( ! mGeoJp2RasterLayer->isValid() )

0 comments on commit 0056bb1

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