QGIS API Documentation 3.99.0-Master (d270888f95f)
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}
35
37{
38 QgsRasterSingleColorRenderer *renderer = new QgsRasterSingleColorRenderer( nullptr, mInputBand, mColor );
39 renderer->copyCommonProperties( this );
40 return renderer;
41}
42
47
49{
50 if ( elem.isNull() )
51 {
52 return nullptr;
53 }
54
55 const QColor color = QgsColorUtils::colorFromString( elem.attribute( u"color"_s, u"0,0,0"_s ) );
56 const int band = elem.attribute( u"band"_s, u"1"_s ).toInt();
58 r->readXml( elem );
59
60 return r;
61}
62
64{
65 QgsDebugMsgLevel( u"width = %1 height = %2"_s.arg( width ).arg( height ), 4 );
66
67 auto outputBlock = std::make_unique<QgsRasterBlock>();
68 if ( !mInput || mInputBand == -1 )
69 {
70 return outputBlock.release();
71 }
72
73 const std::shared_ptr< QgsRasterBlock > inputBlock( mInput->block( mInputBand, extent, width, height, feedback ) );
74 if ( !inputBlock || inputBlock->isEmpty() )
75 {
76 QgsDebugError( u"No raster data!"_s );
77 return outputBlock.release();
78 }
79
80 std::shared_ptr< QgsRasterBlock > alphaBlock;
81 if ( mAlphaBand > 0 )
82 {
83 alphaBlock = inputBlock;
84 }
85
86 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
87 {
88 return outputBlock.release();
89 }
90
91 const QRgb defaultColor = renderColorForNodataPixel();
92 const QRgb rendererColor = qRgba( mColor.red(), mColor.green(), mColor.blue(), mColor.alpha() );
93
94 bool isNoData = false;
95 const qgssize blockSize = static_cast< qgssize >( width ) * height;
96 for ( qgssize i = 0; i < blockSize; i++ )
97 {
98 double value = inputBlock->valueAndNoData( i, isNoData );
99 if ( isNoData )
100 {
101 outputBlock->setColor( i, defaultColor );
102 continue;
103 }
104
105 double currentAlpha = mOpacity;
107 {
108 currentAlpha *= mRasterTransparency->opacityForValue( value );
109 }
110 if ( mAlphaBand > 0 )
111 {
112 const double alpha = alphaBlock->value( i );
113 if ( alpha == 0 )
114 {
115 outputBlock->setColor( i, defaultColor );
116 continue;
117 }
118 else
119 {
120 currentAlpha *= alpha / 255.0;
121 }
122 }
123
124 if ( qgsDoubleNear( currentAlpha, 1.0 ) )
125 {
126 outputBlock->setColor( i, rendererColor );
127 }
128 else
129 {
130 outputBlock->setColor( i, qRgba( static_cast<int>( currentAlpha * mColor.red() ),
131 static_cast<int>( currentAlpha * mColor.green() ),
132 static_cast<int>( currentAlpha * mColor.blue() ),
133 static_cast<int>( currentAlpha * mColor.alpha() ) ) );
134 }
135 }
136
137 return outputBlock.release();
138}
139
141{
142 mColor = color;;
143}
144
146{
147 return mColor;
148}
149
150void QgsRasterSingleColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
151{
152 if ( parentElem.isNull() )
153 {
154 return;
155 }
156
157 QDomElement rasterRendererElem = doc.createElement( u"rasterrenderer"_s );
158 _writeXml( doc, rasterRendererElem );
159
160 rasterRendererElem.setAttribute( u"color"_s, QgsColorUtils::colorToString( mColor ) );
161 rasterRendererElem.setAttribute( u"band"_s, mInputBand );
162
163 parentElem.appendChild( rasterRendererElem );
164}
165
167{
168 return mInputBand;
169}
170
172{
173 if ( !mInput || ( band > 0 && band <= mInput->bandCount() ) )
174 {
175 mInputBand = band;
176 return true;
177 }
178 return false;
179}
180
182{
183 QList<int> bands;
184 if ( mInputBand != -1 )
185 {
186 bands << mInputBand;
187 }
188 return bands;
189}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1570
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
Definition qgis.h:1561
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:394
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.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
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.
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:7423
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6900
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
#define QgsDebugError(str)
Definition qgslogger.h:59