QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsmultibandcolorrenderer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmultibandcolorrenderer.cpp
3 -----------------------------
4 begin : December 2011
5 copyright : (C) 2011 by Marco Hugentobler
6 email : marco at sourcepole 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
21#include "qgsrasterviewport.h"
23#include "qgssymbol.h"
24
25#include <QDomDocument>
26#include <QDomElement>
27#include <QImage>
28#include <QSet>
29
30QgsMultiBandColorRenderer::QgsMultiBandColorRenderer( QgsRasterInterface *input, int redBand, int greenBand, int blueBand,
31 QgsContrastEnhancement *redEnhancement,
32 QgsContrastEnhancement *greenEnhancement,
33 QgsContrastEnhancement *blueEnhancement )
34 : QgsRasterRenderer( input, QStringLiteral( "multibandcolor" ) )
35 , mRedBand( redBand )
36 , mGreenBand( greenBand )
37 , mBlueBand( blueBand )
38 , mRedContrastEnhancement( redEnhancement )
39 , mGreenContrastEnhancement( greenEnhancement )
40 , mBlueContrastEnhancement( blueEnhancement )
41{
42}
43
45{
46 delete mRedContrastEnhancement;
47 delete mGreenContrastEnhancement;
48 delete mBlueContrastEnhancement;
49}
50
52{
53 QgsMultiBandColorRenderer *renderer = new QgsMultiBandColorRenderer( nullptr, mRedBand, mGreenBand, mBlueBand );
54 renderer->copyCommonProperties( this );
55
56 if ( mRedContrastEnhancement )
57 {
58 renderer->setRedContrastEnhancement( new QgsContrastEnhancement( *mRedContrastEnhancement ) );
59 }
60 if ( mGreenContrastEnhancement )
61 {
62 renderer->setGreenContrastEnhancement( new QgsContrastEnhancement( *mGreenContrastEnhancement ) );
63 }
64 if ( mBlueContrastEnhancement )
65 {
66 renderer->setBlueContrastEnhancement( new QgsContrastEnhancement( *mBlueContrastEnhancement ) );
67 }
68
69 return renderer;
70}
71
72Qgis::RasterRendererFlags QgsMultiBandColorRenderer::flags() const
73{
75}
76
78{
79 delete mRedContrastEnhancement;
80 mRedContrastEnhancement = ce;
81}
82
84{
85 delete mGreenContrastEnhancement;
86 mGreenContrastEnhancement = ce;
87}
88
90{
91 delete mBlueContrastEnhancement;
92 mBlueContrastEnhancement = ce;
93}
94
96{
97 if ( elem.isNull() )
98 {
99 return nullptr;
100 }
101
102 //red band, green band, blue band
103 const int redBand = elem.attribute( QStringLiteral( "redBand" ), QStringLiteral( "-1" ) ).toInt();
104 const int greenBand = elem.attribute( QStringLiteral( "greenBand" ), QStringLiteral( "-1" ) ).toInt();
105 const int blueBand = elem.attribute( QStringLiteral( "blueBand" ), QStringLiteral( "-1" ) ).toInt();
106
107 //contrast enhancements
109 const QDomElement redContrastElem = elem.firstChildElement( QStringLiteral( "redContrastEnhancement" ) );
110 if ( !redContrastElem.isNull() )
111 {
113 input->dataType( redBand ) ) );
114 redContrastEnhancement->readXml( redContrastElem );
115 }
116
118 const QDomElement greenContrastElem = elem.firstChildElement( QStringLiteral( "greenContrastEnhancement" ) );
119 if ( !greenContrastElem.isNull() )
120 {
122 input->dataType( greenBand ) ) );
123 greenContrastEnhancement->readXml( greenContrastElem );
124 }
125
127 const QDomElement blueContrastElem = elem.firstChildElement( QStringLiteral( "blueContrastEnhancement" ) );
128 if ( !blueContrastElem.isNull() )
129 {
131 input->dataType( blueBand ) ) );
132 blueContrastEnhancement->readXml( blueContrastElem );
133 }
134
137 r->readXml( elem );
138 return r;
139}
140
141QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
142{
143 Q_UNUSED( bandNo )
144 std::unique_ptr< QgsRasterBlock > outputBlock( new QgsRasterBlock() );
145 if ( !mInput )
146 {
147 return outputBlock.release();
148 }
149
150 //In some (common) cases, we can simplify the drawing loop considerably and save render time
151 bool fastDraw = ( !usesTransparency()
152 && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
153 && mAlphaBand < 1 );
154
155 QList<int> bands;
156 if ( mRedBand > 0 )
157 {
158 bands << mRedBand;
159 }
160 if ( mGreenBand > 0 )
161 {
162 bands << mGreenBand;
163 }
164 if ( mBlueBand > 0 )
165 {
166 bands << mBlueBand;
167 }
168 if ( bands.empty() )
169 {
170 // no need to draw anything if no band is set
171 // TODO:: we should probably return default color block
172 return outputBlock.release();
173 }
174
175 if ( mAlphaBand > 0 )
176 {
177 bands << mAlphaBand;
178 }
179
180 QMap<int, QgsRasterBlock *> bandBlocks;
181 QgsRasterBlock *defaultPointer = nullptr;
182 QList<int>::const_iterator bandIt = bands.constBegin();
183 for ( ; bandIt != bands.constEnd(); ++bandIt )
184 {
185 bandBlocks.insert( *bandIt, defaultPointer );
186 }
187
188 QgsRasterBlock *redBlock = nullptr;
189 QgsRasterBlock *greenBlock = nullptr;
190 QgsRasterBlock *blueBlock = nullptr;
191 QgsRasterBlock *alphaBlock = nullptr;
192
193 bandIt = bands.constBegin();
194 for ( ; bandIt != bands.constEnd(); ++bandIt )
195 {
196 bandBlocks[*bandIt] = mInput->block( *bandIt, extent, width, height, feedback );
197 if ( !bandBlocks[*bandIt] )
198 {
199 // We should free the allocated mem from block().
200 QgsDebugMsg( QStringLiteral( "No input band" ) );
201 --bandIt;
202 for ( ; bandIt != bands.constBegin(); --bandIt )
203 {
204 delete bandBlocks[*bandIt];
205 }
206 return outputBlock.release();
207 }
208 }
209
210 if ( mRedBand > 0 )
211 {
212 redBlock = bandBlocks[mRedBand];
213 }
214 if ( mGreenBand > 0 )
215 {
216 greenBlock = bandBlocks[mGreenBand];
217 }
218 if ( mBlueBand > 0 )
219 {
220 blueBlock = bandBlocks[mBlueBand];
221 }
222 if ( mAlphaBand > 0 )
223 {
224 alphaBlock = bandBlocks[mAlphaBand];
225 }
226
227 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
228 {
229 for ( int i = 0; i < bandBlocks.size(); i++ )
230 {
231 delete bandBlocks.value( i );
232 }
233 return outputBlock.release();
234 }
235
236 QRgb *outputBlockColorData = outputBlock->colorData();
237
238 // faster data access to data for the common case that input data are coming from RGB image with 8-bit bands
239 const bool hasByteRgb = ( redBlock && greenBlock && blueBlock && redBlock->dataType() == Qgis::DataType::Byte && greenBlock->dataType() == Qgis::DataType::Byte && blueBlock->dataType() == Qgis::DataType::Byte );
240 const quint8 *redData = nullptr, *greenData = nullptr, *blueData = nullptr;
241 if ( hasByteRgb )
242 {
243 redData = redBlock->byteData();
244 greenData = greenBlock->byteData();
245 blueData = blueBlock->byteData();
246 }
247
248 const QRgb myDefaultColor = renderColorForNodataPixel();
249
250 if ( fastDraw )
251 {
252 // By default RGB raster layers have contrast enhancement assigned and normally that requires us to take the slow
253 // route that applies the enhancement. However if the algorithm type is "no enhancement" and all input bands are byte-sized,
254 // no transform would be applied to the input values and we can take the fast route.
255 bool hasEnhancement;
256 if ( hasByteRgb )
257 {
258 hasEnhancement =
259 ( mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement ) ||
260 ( mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement ) ||
261 ( mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement );
262 }
263 else
264 {
265 hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
266 }
267 if ( hasEnhancement )
268 fastDraw = false;
269 }
270
271 const qgssize count = ( qgssize )width * height;
272 for ( qgssize i = 0; i < count; i++ )
273 {
274 if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc.
275 {
276 if ( hasByteRgb )
277 {
278 if ( redBlock->isNoData( i ) ||
279 greenBlock->isNoData( i ) ||
280 blueBlock->isNoData( i ) )
281 {
282 outputBlock->setColor( i, myDefaultColor );
283 }
284 else
285 {
286 outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
287 }
288 }
289 else
290 {
291 bool redIsNoData = false;
292 bool greenIsNoData = false;
293 bool blueIsNoData = false;
294 int redVal = 0;
295 int greenVal = 0;
296 int blueVal = 0;
297
298 redVal = redBlock->valueAndNoData( i, redIsNoData );
299 // as soon as any channel has a no data value, don't do any more work -- the result will
300 // always be the nodata color!
301 if ( !redIsNoData )
302 greenVal = greenBlock->valueAndNoData( i, greenIsNoData );
303 if ( !redIsNoData && !greenIsNoData )
304 blueVal = blueBlock->valueAndNoData( i, blueIsNoData );
305
306 if ( redIsNoData ||
307 greenIsNoData ||
308 blueIsNoData )
309 {
310 outputBlock->setColor( i, myDefaultColor );
311 }
312 else
313 {
314 outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
315 }
316 }
317 continue;
318 }
319
320 bool isNoData = false;
321 double redVal = 0;
322 double greenVal = 0;
323 double blueVal = 0;
324 if ( mRedBand > 0 )
325 {
326 redVal = redBlock->valueAndNoData( i, isNoData );
327 }
328 if ( !isNoData && mGreenBand > 0 )
329 {
330 greenVal = greenBlock->valueAndNoData( i, isNoData );
331 }
332 if ( !isNoData && mBlueBand > 0 )
333 {
334 blueVal = blueBlock->valueAndNoData( i, isNoData );
335 }
336 if ( isNoData )
337 {
338 outputBlock->setColor( i, myDefaultColor );
339 continue;
340 }
341
342 //apply default color if red, green or blue not in displayable range
343 if ( ( mRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( redVal ) )
344 || ( mGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( redVal ) )
345 || ( mBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( redVal ) ) )
346 {
347 outputBlock->setColor( i, myDefaultColor );
348 continue;
349 }
350
351 //stretch color values
352 if ( mRedContrastEnhancement )
353 {
354 redVal = mRedContrastEnhancement->enhanceContrast( redVal );
355 }
356 if ( mGreenContrastEnhancement )
357 {
358 greenVal = mGreenContrastEnhancement->enhanceContrast( greenVal );
359 }
360 if ( mBlueContrastEnhancement )
361 {
362 blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal );
363 }
364
365 //opacity
366 double currentOpacity = mOpacity;
368 {
369 currentOpacity = mRasterTransparency->alphaValue( redVal, greenVal, blueVal, mOpacity * 255 ) / 255.0;
370 }
371 if ( mAlphaBand > 0 )
372 {
373 currentOpacity *= alphaBlock->value( i ) / 255.0;
374 }
375
376 if ( qgsDoubleNear( currentOpacity, 1.0 ) )
377 {
378 outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
379 }
380 else
381 {
382 outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
383 }
384 }
385
386 //delete input blocks
387 QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
388 for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
389 {
390 delete bandDelIt.value();
391 }
392
393 return outputBlock.release();
394}
395
396void QgsMultiBandColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
397{
398 if ( parentElem.isNull() )
399 {
400 return;
401 }
402
403 QDomElement rasterRendererElem = doc.createElement( QStringLiteral( "rasterrenderer" ) );
404 _writeXml( doc, rasterRendererElem );
405 rasterRendererElem.setAttribute( QStringLiteral( "redBand" ), mRedBand );
406 rasterRendererElem.setAttribute( QStringLiteral( "greenBand" ), mGreenBand );
407 rasterRendererElem.setAttribute( QStringLiteral( "blueBand" ), mBlueBand );
408
409 //contrast enhancement
410 if ( mRedContrastEnhancement )
411 {
412 QDomElement redContrastElem = doc.createElement( QStringLiteral( "redContrastEnhancement" ) );
413 mRedContrastEnhancement->writeXml( doc, redContrastElem );
414 rasterRendererElem.appendChild( redContrastElem );
415 }
416 if ( mGreenContrastEnhancement )
417 {
418 QDomElement greenContrastElem = doc.createElement( QStringLiteral( "greenContrastEnhancement" ) );
419 mGreenContrastEnhancement->writeXml( doc, greenContrastElem );
420 rasterRendererElem.appendChild( greenContrastElem );
421 }
422 if ( mBlueContrastEnhancement )
423 {
424 QDomElement blueContrastElem = doc.createElement( QStringLiteral( "blueContrastEnhancement" ) );
425 mBlueContrastEnhancement->writeXml( doc, blueContrastElem );
426 rasterRendererElem.appendChild( blueContrastElem );
427 }
428 parentElem.appendChild( rasterRendererElem );
429}
430
432{
433 QList<int> bandList;
434 if ( mRedBand != -1 )
435 {
436 bandList << mRedBand;
437 }
438 if ( mGreenBand != -1 )
439 {
440 bandList << mGreenBand;
441 }
442 if ( mBlueBand != -1 )
443 {
444 bandList << mBlueBand;
445 }
446 return bandList;
447}
448
449QList<QgsLayerTreeModelLegendNode *> QgsMultiBandColorRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
450{
451 QList<QgsLayerTreeModelLegendNode *> res;
452 if ( mRedBand != -1 )
453 {
454 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 255, 0, 0 ), displayBandName( mRedBand ) );
455 }
456 if ( mGreenBand != -1 )
457 {
458 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 0, 255, 0 ), displayBandName( mGreenBand ) );
459 }
460 if ( mBlueBand != -1 )
461 {
462 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 0, 0, 255 ), displayBandName( mBlueBand ) );
463 }
464
465 return res;
466}
467
468void QgsMultiBandColorRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
469{
470 // create base structure
471 QgsRasterRenderer::toSld( doc, element, props );
472
473
474#if 0
475 // TODO: the following jumped code is necessary to avoid to export channelSelection in
476 // case it's set as default value. The drawback is that it's necessary to calc band
477 // statistics that can be really slow depending on dataProvider and rastr location.
478 // this is the reason this part of code is commented and the channelSelection is
479 // always exported.
480 //
481 // before to export check if the band combination and contrast setting are the
482 // default ones to avoid to export this tags
483 bool isDefaultCombination = true;
484 QList<int> defaultBandCombination( { 1, 2, 3 } );
485
486 isDefaultCombination = isDefaultCombination && ( usesBands() == defaultBandCombination );
487 isDefaultCombination = isDefaultCombination && (
491 );
492 // compute raster statistics (slow) only if true the previous conditions
493 if ( isDefaultCombination )
494 {
496 isDefaultCombination = isDefaultCombination && (
497 ( mRedContrastEnhancement->minimumValue() == statRed.minimumValue &&
498 mRedContrastEnhancement->maximumValue() == statRed.maximumValue )
499 );
500 }
501 if ( isDefaultCombination )
502 {
504 isDefaultCombination = isDefaultCombination && (
505 ( mGreenContrastEnhancement->minimumValue() == statGreen.minimumValue &&
506 mGreenContrastEnhancement->maximumValue() == statGreen.maximumValue )
507 );
508 }
509 if ( isDefaultCombination )
510 {
512 isDefaultCombination = isDefaultCombination && (
513 ( mBlueContrastEnhancement->minimumValue() == statBlue.minimumValue &&
514 mBlueContrastEnhancement->maximumValue() == statBlue.maximumValue )
515 );
516 }
517 if ( isDefaultCombination )
518 return;
519#endif
520
521 // look for RasterSymbolizer tag
522 QDomNodeList elements = element.elementsByTagName( QStringLiteral( "sld:RasterSymbolizer" ) );
523 if ( elements.size() == 0 )
524 return;
525
526 // there SHOULD be only one
527 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
528
529 // add Channel Selection tags
530 // Need to insert channelSelection in the correct sequence as in SLD standard e.g.
531 // after opacity or geometry or as first element after sld:RasterSymbolizer
532 QDomElement channelSelectionElem = doc.createElement( QStringLiteral( "sld:ChannelSelection" ) );
533 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Opacity" ) );
534 if ( elements.size() != 0 )
535 {
536 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
537 }
538 else
539 {
540 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( "sld:Geometry" ) );
541 if ( elements.size() != 0 )
542 {
543 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
544 }
545 else
546 {
547 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
548 }
549 }
550
551 // for each mapped band
552 static QStringList tags { QStringLiteral( "sld:RedChannel" ), QStringLiteral( "sld:GreenChannel" ), QStringLiteral( "sld:BlueChannel" ) };
553
554 QList<QgsContrastEnhancement *> contrastEnhancements;
555 contrastEnhancements.append( mRedContrastEnhancement );
556 contrastEnhancements.append( mGreenContrastEnhancement );
557 contrastEnhancements.append( mBlueContrastEnhancement );
558
559 const QList<int> bands = usesBands();
560 QList<int>::const_iterator bandIt = bands.constBegin();
561 for ( int tagCounter = 0 ; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
562 {
563 if ( *bandIt < 0 )
564 continue;
565
566 QDomElement channelElem = doc.createElement( tags[ tagCounter ] );
567 channelSelectionElem.appendChild( channelElem );
568
569 // set band
570 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( "sld:SourceChannelName" ) );
571 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
572 channelElem.appendChild( sourceChannelNameElem );
573
574 // set ContrastEnhancement for each band
575 // NO ContrastEnhancement parameter for the entire bands is managed e.g.
576 // because min/max values can vary depending on band.
577 if ( contrastEnhancements[ tagCounter ] )
578 {
579 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral( "sld:ContrastEnhancement" ) );
580 contrastEnhancements[ tagCounter ]->toSld( doc, contrastEnhancementElem );
581 channelElem.appendChild( contrastEnhancementElem );
582 }
583 }
584}
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
DataType
Raster data types.
Definition: qgis.h:129
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Byte
Eight bit unsigned integer (quint8)
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
@ StretchToMinimumMaximum
Linear histogram.
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
bool isValueInDisplayableRange(double value)
Returns true if a pixel value is in displayable range, false if pixel is outside of range (i....
int enhanceContrast(double value)
Applies the contrast enhancement to a value.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
void readXml(const QDomElement &elem)
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
Layer tree node points to a map layer.
Renderer for multiband images with the color components.
QgsMultiBandColorRenderer(QgsRasterInterface *input, int redBand, int greenBand, int blueBand, QgsContrastEnhancement *redEnhancement=nullptr, QgsContrastEnhancement *greenEnhancement=nullptr, QgsContrastEnhancement *blueEnhancement=nullptr)
const QgsContrastEnhancement * greenContrastEnhancement() const
Returns the contrast enhancement to use for the green channel.
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 toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
const QgsContrastEnhancement * blueContrastEnhancement() const
Returns the contrast enhancement to use for the blue channel.
void setGreenContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the green channel.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
QgsMultiBandColorRenderer * clone() const override
Clone itself, create deep copy.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the blue channel.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
void setRedContrastEnhancement(QgsContrastEnhancement *ce)
Sets the contrast enhancement to use for the red channel.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
const QgsContrastEnhancement * redContrastEnhancement() const
Returns the contrast enhancement to use for the red channel.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
Feedback object tailored for raster block reading.
Raster data container.
double valueAndNoData(int row, int column, bool &isNoData) const
Reads a single value from the pixel at row and column, if type of block is numeric.
Qgis::DataType dataType() const SIP_HOLDGIL
Returns data type.
double value(int row, int column) const SIP_HOLDGIL
Read a single value if type of block is numeric.
const quint8 * byteData() const
Gives direct access to the raster block data.
bool isNoData(int row, int column) const SIP_HOLDGIL
Checks if value at position is no data.
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.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
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)
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
bool usesTransparency() const
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
virtual void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Implementation of legend node interface for displaying raster legend entries.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
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:3032
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:2527
#define QgsDebugMsg(str)
Definition: qgslogger.h:38