QGIS API Documentation 3.39.0-Master (47f7b3a4989)
Loading...
Searching...
No Matches
qgsrastersinglecolorrenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsrastersinglecolorrenderer.cpp
3 -----------------------------
4 begin : April 2024
5 copyright : (C) 2024 by Mathieu Pellerin
6 email : mathieu at opengis dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
20#include "qgscolorutils.h"
21
22#include <QDomDocument>
23#include <QDomElement>
24
26 : QgsRasterRenderer( input, QStringLiteral( "singlecolor" ) )
27 , mInputBand( band )
28 , mColor( color )
29{
30}
31
33{
34 QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( nullptr, mInputBand, mColor );
35 renderer->copyCommonProperties( this );
36 return renderer;
37}
38
43
45{
46 if ( elem.isNull() )
47 {
48 return nullptr;
49 }
50
51 const QColor color = QgsColorUtils::colorFromString( elem.attribute( QStringLiteral( "color" ), QStringLiteral( "0,0,0" ) ) );
52 const int band = elem.attribute( QStringLiteral( "band" ), QStringLiteral( "1" ) ).toInt();
54 r->readXml( elem );
55
56 return r;
57}
58
59QgsRasterBlock *QgsRasterSingleColorRenderer::block( int, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback )
60{
61 QgsDebugMsgLevel( QStringLiteral( "width = %1 height = %2" ).arg( width ).arg( height ), 4 );
62
63 std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
64 if ( !mInput || mInputBand == -1 )
65 {
66 return outputBlock.release();
67 }
68
69 const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mInputBand, extent, width, height, feedback ) );
70 if ( !inputBlock || inputBlock->isEmpty() )
71 {
72 QgsDebugError( QStringLiteral( "No raster data!" ) );
73 return outputBlock.release();
74 }
75
76 std::shared_ptr< QgsRasterBlock > alphaBlock;
77 if ( mAlphaBand > 0 )
78 {
79 alphaBlock = inputBlock;
80 }
81
82 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
83 {
84 return outputBlock.release();
85 }
86
87 const QRgb defaultColor = renderColorForNodataPixel();
88 const QRgb rendererColor = qRgba( mColor.red(), mColor.green(), mColor.blue(), mColor.alpha() );
89
90 bool isNoData = false;
91 const qgssize blockSize = static_cast< qgssize >( width ) * height;
92 for ( qgssize i = 0; i < blockSize; i++ )
93 {
94 double value = inputBlock->valueAndNoData( i, isNoData );
95 if ( isNoData )
96 {
97 outputBlock->setColor( i, defaultColor );
98 continue;
99 }
100
101 double currentAlpha = mOpacity;
103 {
104 currentAlpha *= mRasterTransparency->opacityForValue( value );
105 }
106 if ( mAlphaBand > 0 )
107 {
108 const double alpha = alphaBlock->value( i );
109 if ( alpha == 0 )
110 {
111 outputBlock->setColor( i, defaultColor );
112 continue;
113 }
114 else
115 {
116 currentAlpha *= alpha / 255.0;
117 }
118 }
119
120 if ( qgsDoubleNear( currentAlpha, 1.0 ) )
121 {
122 outputBlock->setColor( i, rendererColor );
123 }
124 else
125 {
126 outputBlock->setColor( i, qRgba( static_cast<int>( currentAlpha * mColor.red() ),
127 static_cast<int>( currentAlpha * mColor.green() ),
128 static_cast<int>( currentAlpha * mColor.blue() ),
129 static_cast<int>( currentAlpha * mColor.alpha() ) ) );
130 }
131 }
132
133 return outputBlock.release();
134}
135
136void QgsRasterSingleColorRenderer::setColor( const QColor &color )
137{
138 mColor = color;;
139}
140
142{
143 return mColor;
144}
145
146void QgsRasterSingleColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
147{
148 if ( parentElem.isNull() )
149 {
150 return;
151 }
152
153 QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
154 _writeXml( doc, rasterRendererElem );
155
156 rasterRendererElem.setAttribute( QStringLiteral( "color" ), QgsColorUtils::colorToString( mColor ) );
157 rasterRendererElem.setAttribute( QStringLiteral( "band" ), mInputBand );
158
159 parentElem.appendChild( rasterRendererElem );
160}
161
163{
164 return mInputBand;
165}
166
168{
169 if ( !mInput || ( band > 0 && band <= mInput->bandCount() ) )
170 {
171 mInputBand = band;
172 return true;
173 }
174 return false;
175}
176
178{
179 QList<int> bands;
180 if ( mInputBand != -1 )
181 {
182 bands << mInputBand;
183 }
184 return bands;
185}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1227
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Feedback object tailored for raster block reading.
Raster data container.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
Raster renderer pipe that applies colors to a raster.
double mOpacity
Global alpha value (0-1)
int mAlphaBand
Read alpha value from band.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses)
int bandCount() const override
Gets number of bands.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Raster renderer which renders all data pixels using a single color.
int inputBand() const override
Returns the input band for the renderer, or -1 if no input band is available.
bool setInputBand(int band) override
Attempts to set the input band for the renderer.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
QgsRasterSingleColorRenderer * clone() const override
Clone itself, create deep copy.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Creates an instance of the renderer based on definition from XML (used by the renderer registry)
QgsRasterSingleColorRenderer(QgsRasterInterface *input, int band, const QColor &color)
Creates a single color renderer.
QColor color() const
Returns the single color used by the renderer.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
void setColor(const QColor &color)
Sets the single color used by the renderer.
double opacityForValue(double value) const
Returns the opacity (as a value from 0 to 1) for a single value pixel.
A rectangle specified with double values.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
Definition qgis.h:6013
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:5465
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:39
#define QgsDebugError(str)
Definition qgslogger.h:38