Address review

This commit is contained in:
Mathieu Pellerin 2024-04-08 09:34:33 +07:00
parent 4bd2e66b3f
commit d68a428f6e
9 changed files with 106 additions and 44 deletions

View File

@ -14,7 +14,7 @@
class QgsRasterSingleColorRenderer: QgsRasterRenderer
{
%Docstring(signature="appended")
Raster single color renderer pipe.
Raster renderer which renders all data pixels using a single color.
.. versionadded:: 3.38
%End
@ -24,7 +24,7 @@ Raster single color renderer pipe.
%End
public:
QgsRasterSingleColorRenderer( QgsRasterInterface *input, QColor color );
QgsRasterSingleColorRenderer( QgsRasterInterface *input, int band, const QColor &color );
%Docstring
Creates a single ``color`` renderer
%End
@ -49,16 +49,24 @@ Creates an instance of the renderer based on definition from XML (used by the re
QColor color() const;
%Docstring
Returns the single color used by the renderer.
.. seealso:: :py:func:`setColor`
%End
void setColor( QColor &color );
void setColor( const QColor &color );
%Docstring
Sets the single color used by the renderer.
Sets the single ``color`` used by the renderer.
.. seealso:: :py:func:`color`
%End
virtual void writeXml( QDomDocument &doc, QDomElement &parentElem ) const;
virtual int inputBand() const;
virtual bool setInputBand( int band );
virtual QList<int> usesBands() const;

View File

@ -14,7 +14,7 @@
class QgsRasterSingleColorRenderer: QgsRasterRenderer
{
%Docstring(signature="appended")
Raster single color renderer pipe.
Raster renderer which renders all data pixels using a single color.
.. versionadded:: 3.38
%End
@ -24,7 +24,7 @@ Raster single color renderer pipe.
%End
public:
QgsRasterSingleColorRenderer( QgsRasterInterface *input, QColor color );
QgsRasterSingleColorRenderer( QgsRasterInterface *input, int band, const QColor &color );
%Docstring
Creates a single ``color`` renderer
%End
@ -49,16 +49,24 @@ Creates an instance of the renderer based on definition from XML (used by the re
QColor color() const;
%Docstring
Returns the single color used by the renderer.
.. seealso:: :py:func:`setColor`
%End
void setColor( QColor &color );
void setColor( const QColor &color );
%Docstring
Sets the single color used by the renderer.
Sets the single ``color`` used by the renderer.
.. seealso:: :py:func:`color`
%End
virtual void writeXml( QDomDocument &doc, QDomElement &parentElem ) const;
virtual int inputBand() const;
virtual bool setInputBand( int band );
virtual QList<int> usesBands() const;

View File

@ -22,15 +22,16 @@
#include <QDomDocument>
#include <QDomElement>
QgsRasterSingleColorRenderer::QgsRasterSingleColorRenderer( QgsRasterInterface *input, QColor color )
QgsRasterSingleColorRenderer::QgsRasterSingleColorRenderer( QgsRasterInterface *input, int band, const QColor &color )
: QgsRasterRenderer( input, QStringLiteral( "singlecolor" ) )
, mInputBand( band )
, mColor( color )
{
}
QgsRasterSingleColorRenderer *QgsRasterSingleColorRenderer::clone() const
{
QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( nullptr, mColor );
QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( nullptr, mInputBand, mColor );
renderer->copyCommonProperties( this );
return renderer;
}
@ -48,23 +49,24 @@ QgsRasterRenderer *QgsRasterSingleColorRenderer::create( const QDomElement &elem
}
const QColor color = QgsColorUtils::colorFromString( elem.attribute( QStringLiteral( "color" ), QStringLiteral( "0,0,0" ) ) );
QgsRasterSingleColorRenderer *r = new QgsRasterSingleColorRenderer( input, color );
const int band = elem.attribute( QStringLiteral( "band" ), QStringLiteral( "1" ) ).toInt();
QgsRasterSingleColorRenderer *r = new QgsRasterSingleColorRenderer( input, band, color );
r->readXml( elem );
return r;
}
QgsRasterBlock *QgsRasterSingleColorRenderer::block( int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback )
QgsRasterBlock *QgsRasterSingleColorRenderer::block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback )
{
QgsDebugMsgLevel( QStringLiteral( "width = %1 height = %2" ).arg( width ).arg( height ), 4 );
std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
if ( !mInput )
if ( !mInput || mInputBand == -1 )
{
return outputBlock.release();
}
const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( bandNo, extent, width, height, feedback ) );
const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mInputBand, extent, width, height, feedback ) );
if ( !inputBlock || inputBlock->isEmpty() )
{
QgsDebugError( QStringLiteral( "No raster data!" ) );
@ -82,14 +84,17 @@ QgsRasterBlock *QgsRasterSingleColorRenderer::block( int bandNo, const QgsRectan
return outputBlock.release();
}
const QRgb myDefaultColor = renderColorForNodataPixel();
const QRgb defaultColor = renderColorForNodataPixel();
const QRgb rendererColor = qRgba( mColor.red(), mColor.green(), mColor.blue(), mColor.alpha() );
bool isNoData = false;
for ( qgssize i = 0; i < ( qgssize )width * height; i++ )
const qgssize blockSize = static_cast< qgssize >( width ) * height;
for ( qgssize i = 0; i < blockSize; i++ )
{
double value = inputBlock->valueAndNoData( i, isNoData );
if ( isNoData )
{
outputBlock->setColor( i, myDefaultColor );
outputBlock->setColor( i, defaultColor );
continue;
}
@ -103,7 +108,7 @@ QgsRasterBlock *QgsRasterSingleColorRenderer::block( int bandNo, const QgsRectan
const double alpha = alphaBlock->value( i );
if ( alpha == 0 )
{
outputBlock->setColor( i, myDefaultColor );
outputBlock->setColor( i, defaultColor );
continue;
}
else
@ -114,7 +119,7 @@ QgsRasterBlock *QgsRasterSingleColorRenderer::block( int bandNo, const QgsRectan
if ( qgsDoubleNear( currentAlpha, 1.0 ) )
{
outputBlock->setColor( i, qRgba( mColor.red(), mColor.green(), mColor.blue(), mColor.alpha() ) );
outputBlock->setColor( i, rendererColor );
}
else
{
@ -128,7 +133,7 @@ QgsRasterBlock *QgsRasterSingleColorRenderer::block( int bandNo, const QgsRectan
return outputBlock.release();
}
void QgsRasterSingleColorRenderer::setColor( QColor &color )
void QgsRasterSingleColorRenderer::setColor( const QColor &color )
{
mColor = color;;
}
@ -149,16 +154,37 @@ void QgsRasterSingleColorRenderer::writeXml( QDomDocument &doc, QDomElement &par
_writeXml( doc, rasterRendererElem );
rasterRendererElem.setAttribute( QStringLiteral( "color" ), QgsColorUtils::colorToString( mColor ) );
rasterRendererElem.setAttribute( QStringLiteral( "band" ), QgsColorUtils::colorToString( mInputBand ) );
parentElem.appendChild( rasterRendererElem );
}
int QgsRasterSingleColorRenderer::inputBand() const
{
return mInputBand;
}
bool QgsRasterSingleColorRenderer::setInputBand( int band )
{
if ( !mInput )
{
mInputBand = band;
return true;
}
else if ( band > 0 && band <= mInput->bandCount() )
{
mInputBand = band;
return true;
}
return false;
}
QList<int> QgsRasterSingleColorRenderer::usesBands() const
{
QList<int> bandList;
for ( int i = 0; i <= bandCount(); i++ )
QList<int> bands;
if ( mInputBand != -1 )
{
bandList << i;
bands << mInputBand;
}
return bandList;
return bands;
}

View File

@ -28,7 +28,7 @@ class QDomElement;
/**
* \ingroup core
* \brief Raster single color renderer pipe.
* \brief Raster renderer which renders all data pixels using a single color.
* \since QGIS 3.38
*/
class CORE_EXPORT QgsRasterSingleColorRenderer: public QgsRasterRenderer
@ -36,7 +36,7 @@ class CORE_EXPORT QgsRasterSingleColorRenderer: public QgsRasterRenderer
public:
//! Creates a single \a color renderer
QgsRasterSingleColorRenderer( QgsRasterInterface *input, QColor color );
QgsRasterSingleColorRenderer( QgsRasterInterface *input, int band, const QColor &color );
//! QgsRasterSingleColorRenderer cannot be copied. Use clone() instead.
QgsRasterSingleColorRenderer( const QgsRasterSingleColorRenderer & ) = delete;
@ -53,16 +53,20 @@ class CORE_EXPORT QgsRasterSingleColorRenderer: public QgsRasterRenderer
/**
* Returns the single color used by the renderer.
* \see setColor()
*/
QColor color() const;
/**
* Sets the single color used by the renderer.
* Sets the single \a color used by the renderer.
* \see color()
*/
void setColor( QColor &color );
void setColor( const QColor &color );
void writeXml( QDomDocument &doc, QDomElement &parentElem ) const override;
int inputBand() const override;
bool setInputBand( int band ) override;
QList<int> usesBands() const override;
private:
@ -71,6 +75,7 @@ class CORE_EXPORT QgsRasterSingleColorRenderer: public QgsRasterRenderer
const QgsRasterSingleColorRenderer &operator=( const QgsRasterSingleColorRenderer & );
#endif
int mInputBand = -1;
QColor mColor;
};

View File

@ -33,7 +33,10 @@ QgsRasterSingleColorRendererWidget::QgsRasterSingleColorRendererWidget( QgsRaste
return;
}
connect( mColor, &QgsColorButton::colorChanged, this, &QgsRasterSingleColorRendererWidget::colorChanged );
mBandComboBox->setLayer( layer );
connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, [ = ]( int ) { emit widgetChanged(); } );
connect( mColorButton, &QgsColorButton::colorChanged, this, [ = ]( const QColor & ) { emit widgetChanged(); } );
setFromRenderer( layer->renderer() );
}
@ -52,24 +55,21 @@ QgsRasterRenderer *QgsRasterSingleColorRendererWidget::renderer()
return nullptr;
}
QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( provider, mColor->color() );
QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( provider, mBandComboBox->currentBand(), mColorButton->color() );
return renderer;
}
void QgsRasterSingleColorRendererWidget::colorChanged( const QColor & )
{
emit widgetChanged();
}
void QgsRasterSingleColorRendererWidget::setFromRenderer( const QgsRasterRenderer *r )
{
const QgsRasterSingleColorRenderer *scr = dynamic_cast<const QgsRasterSingleColorRenderer *>( r );
if ( scr )
{
mColor->setColor( scr->color() );
mBandComboBox->setBand( scr->inputBand() );
mColorButton->setColor( scr->color() );
}
else
{
mColor->setColor( QColor( 0, 0, 0 ) );
mBandComboBox->setBand( 1 );
mColorButton->setColor( QColor( 0, 0, 0 ) );
}
}

View File

@ -46,9 +46,6 @@ class GUI_EXPORT QgsRasterSingleColorRendererWidget: public QgsRasterRendererWid
*/
void setFromRenderer( const QgsRasterRenderer *r );
private slots:
void colorChanged( const QColor &color );
};
#endif // QGSRASTERSINGLECOLORRENDERERWIDGET_H

View File

@ -29,14 +29,24 @@
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="mBandLabel">
<property name="text">
<string>Band</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsRasterBandComboBox" name="mBandComboBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mColorLabel">
<property name="text">
<string>Color</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsColorButton" name="mColor">
<item row="1" column="1">
<widget class="QgsColorButton" name="mColorButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -80,6 +90,11 @@
<extends>QToolButton</extends>
<header>qgscolorbutton.h</header>
</customwidget>
<customwidget>
<class>QgsRasterBandComboBox</class>
<extends>QComboBox</extends>
<header>qgsrasterbandcombobox.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@ -291,7 +291,7 @@ ADD_PYTHON_TEST(PyQgsSingleBandColorDataRenderer test_qgssinglebandcolordatarend
ADD_PYTHON_TEST(PyQgsSingleBandGrayRenderer test_qgssinglebandgrayrenderer.py)
ADD_PYTHON_TEST(PyQgsSingleBandPseudoColorRenderer test_qgssinglebandpseudocolorrenderer.py)
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsRasterSingleColorRenderer test_rasterqgssinglecolorrenderer.py)
ADD_PYTHON_TEST(PyQgsRasterSingleColorRenderer test_qgsrastersinglecolorrenderer.py)
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
ADD_PYTHON_TEST(PyQgsSphere test_qgssphere.py)
ADD_PYTHON_TEST(PyQgsSvgCache test_qgssvgcache.py)

View File

@ -36,8 +36,11 @@ class TestQgsRasterSingleBandGrayRenderer(QgisTestCase):
self.assertTrue(layer.isValid(), f'Raster not loaded: {path}')
renderer = QgsRasterSingleColorRenderer(layer.dataProvider(),
1,
QColor(255, 0, 0))
self.assertEqual(renderer.inputBand(), 1)
self.assertEqual(renderer.usesBands(), [1])
self.assertEqual(renderer.color(), QColor(255, 0, 0))
renderer.setColor(QColor(0, 255, 0))
self.assertEqual(renderer.color(), QColor(0, 255, 0))