QGIS API Documentation 4.3.0-Master (f865f0c58a6)
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
19
20#include "qgscolorutils.h"
22
23#include <QDomDocument>
24#include <QDomElement>
25#include <QString>
26
27using namespace Qt::StringLiterals;
28
30 : QgsRasterRenderer( input, u"singlecolor"_s )
31 , mInputBand( band )
32 , mColor( color )
33{}
34
36{
37 QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( nullptr, mInputBand, mColor );
38 renderer->copyCommonProperties( this );
39 return renderer;
40}
41
46
47std::unique_ptr<QgsRasterRenderer> QgsRasterSingleColorRenderer::create( const QDomElement &elem, QgsRasterInterface *input )
48{
49 if ( elem.isNull() )
50 {
51 return nullptr;
52 }
53
54 const QColor color = QgsColorUtils::colorFromString( elem.attribute( u"color"_s, u"0,0,0"_s ) );
55 const int band = elem.attribute( u"band"_s, u"1"_s ).toInt();
56 auto r = std::make_unique<QgsRasterSingleColorRenderer>( input, band, color );
57 r->readXml( elem );
58
59 return r;
60}
61
63{
64 QgsDebugMsgLevel( u"width = %1 height = %2"_s.arg( width ).arg( height ), 4 );
65
66 auto outputBlock = std::make_unique<QgsRasterBlock>();
67 if ( !mInput || mInputBand == -1 )
68 {
69 return outputBlock.release();
70 }
71
72 const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mInputBand, extent, width, height, feedback ) );
73 if ( !inputBlock || inputBlock->isEmpty() )
74 {
75 QgsDebugError( u"No raster data!"_s );
76 return outputBlock.release();
77 }
78
79 std::shared_ptr< QgsRasterBlock > alphaBlock;
80 if ( mAlphaBand > 0 )
81 {
82 alphaBlock = inputBlock;
83 }
84
85 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
86 {
87 return outputBlock.release();
88 }
89
90 const QRgb defaultColor = renderColorForNodataPixel();
91 const QRgb rendererColor = qRgba( mColor.red(), mColor.green(), mColor.blue(), mColor.alpha() );
92
93 bool isNoData = false;
94 const qgssize blockSize = static_cast< qgssize >( width ) * height;
95 for ( qgssize i = 0; i < blockSize; i++ )
96 {
97 double value = inputBlock->valueAndNoData( i, isNoData );
98 if ( isNoData )
99 {
100 outputBlock->setColor( i, defaultColor );
101 continue;
102 }
103
104 double currentAlpha = mOpacity;
106 {
107 currentAlpha *= mRasterTransparency->opacityForValue( value );
108 }
109 if ( mAlphaBand > 0 )
110 {
111 const double alpha = alphaBlock->value( i );
112 if ( alpha == 0 )
113 {
114 outputBlock->setColor( i, defaultColor );
115 continue;
116 }
117 else
118 {
119 currentAlpha *= alpha / 255.0;
120 }
121 }
122
123 if ( qgsDoubleNear( currentAlpha, 1.0 ) )
124 {
125 outputBlock->setColor( i, rendererColor );
126 }
127 else
128 {
129 outputBlock->setColor(
130 i,
131 qRgba(
132 static_cast<int>( currentAlpha * mColor.red() ),
133 static_cast<int>( currentAlpha * mColor.green() ),
134 static_cast<int>( currentAlpha * mColor.blue() ),
135 static_cast<int>( currentAlpha * mColor.alpha() )
136 )
137 );
138 }
139 }
140
141 return outputBlock.release();
142}
143
145{
146 mColor = color;
147 ;
148}
149
151{
152 return mColor;
153}
154
155void QgsRasterSingleColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
156{
157 if ( parentElem.isNull() )
158 {
159 return;
160 }
161
162 QDomElement rasterRendererElem = doc.createElement( u"rasterrenderer"_s );
163 _writeXml( doc, rasterRendererElem );
164
165 rasterRendererElem.setAttribute( u"color"_s, QgsColorUtils::colorToString( mColor ) );
166 rasterRendererElem.setAttribute( u"band"_s, mInputBand );
167
168 parentElem.appendChild( rasterRendererElem );
169}
170
172{
173 return mInputBand;
174}
175
177{
178 if ( !mInput || ( band > 0 && band <= mInput->bandCount() ) )
179 {
180 mInputBand = band;
181 return true;
182 }
183 return false;
184}
185
187{
188 QList<int> bands;
189 if ( mInputBand != -1 )
190 {
191 bands << mInputBand;
192 }
193 return bands;
194}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1662
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
Definition qgis.h:1652
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:408
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.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
QgsRasterInterface * mInput
virtual QgsRectangle extent() const
Gets the extent of the interface.
virtual QgsRasterInterface * input() const
Current input.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
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.
std::unique_ptr< QgsRasterTransparency > mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
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.
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
int inputBand() const override
Returns the input band for the renderer, or -1 if no input band is available.
static std::unique_ptr< QgsRasterRenderer > create(const QDomElement &elem, QgsRasterInterface *input)
Creates an instance of the renderer based on definition from XML (used by the renderer registry).
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.
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.
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:8174
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7557
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:80
#define QgsDebugError(str)
Definition qgslogger.h:71