QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
Loading...
Searching...
No Matches
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
19
23#include "qgssldexportcontext.h"
24
25#include <QDomDocument>
26#include <QDomElement>
27#include <QImage>
28#include <QSet>
29#include <QString>
30
31using namespace Qt::StringLiterals;
32
34 QgsRasterInterface *input, int redBand, int greenBand, int blueBand, QgsContrastEnhancement *redEnhancement, QgsContrastEnhancement *greenEnhancement, QgsContrastEnhancement *blueEnhancement
35)
36 : QgsRasterRenderer( input, u"multibandcolor"_s )
37 , mRedBand( redBand )
38 , mGreenBand( greenBand )
39 , mBlueBand( blueBand )
40 , mRedContrastEnhancement( redEnhancement )
41 , mGreenContrastEnhancement( greenEnhancement )
42 , mBlueContrastEnhancement( blueEnhancement )
43{}
44
46
48{
49 QgsMultiBandColorRenderer *renderer = new QgsMultiBandColorRenderer( nullptr, mRedBand, mGreenBand, mBlueBand );
50 renderer->copyCommonProperties( this );
51
52 if ( mRedContrastEnhancement )
53 {
54 renderer->setRedContrastEnhancement( new QgsContrastEnhancement( *mRedContrastEnhancement ) );
55 }
56 if ( mGreenContrastEnhancement )
57 {
58 renderer->setGreenContrastEnhancement( new QgsContrastEnhancement( *mGreenContrastEnhancement ) );
59 }
60 if ( mBlueContrastEnhancement )
61 {
62 renderer->setBlueContrastEnhancement( new QgsContrastEnhancement( *mBlueContrastEnhancement ) );
63 }
64
65 return renderer;
66}
67
72
74{
75 if ( ce == mRedContrastEnhancement.get() )
76 return;
77
78 mRedContrastEnhancement.reset( ce );
79}
80
82{
83 return mGreenContrastEnhancement.get();
84}
85
87{
88 if ( ce == mGreenContrastEnhancement.get() )
89 return;
90
91 mGreenContrastEnhancement.reset( ce );
92}
93
95{
96 return mBlueContrastEnhancement.get();
97}
98
100{
101 if ( ce == mBlueContrastEnhancement.get() )
102 return;
103
104 mBlueContrastEnhancement.reset( ce );
105}
106
108{
109 if ( elem.isNull() )
110 {
111 return nullptr;
112 }
113
114 //red band, green band, blue band
115 const int redBand = elem.attribute( u"redBand"_s, u"-1"_s ).toInt();
116 const int greenBand = elem.attribute( u"greenBand"_s, u"-1"_s ).toInt();
117 const int blueBand = elem.attribute( u"blueBand"_s, u"-1"_s ).toInt();
118
119 //contrast enhancements
121 const QDomElement redContrastElem = elem.firstChildElement( u"redContrastEnhancement"_s );
122 if ( !redContrastElem.isNull() )
123 {
125 redContrastEnhancement->readXml( redContrastElem );
126 }
127
129 const QDomElement greenContrastElem = elem.firstChildElement( u"greenContrastEnhancement"_s );
130 if ( !greenContrastElem.isNull() )
131 {
133 greenContrastEnhancement->readXml( greenContrastElem );
134 }
135
137 const QDomElement blueContrastElem = elem.firstChildElement( u"blueContrastEnhancement"_s );
138 if ( !blueContrastElem.isNull() )
139 {
141 blueContrastEnhancement->readXml( blueContrastElem );
142 }
143
145 r->readXml( elem );
146 return r;
147}
148
149QgsRasterBlock *QgsMultiBandColorRenderer::block( int bandNo, QgsRectangle const &extent, int width, int height, QgsRasterBlockFeedback *feedback )
150{
151 Q_UNUSED( bandNo )
152 auto outputBlock = std::make_unique<QgsRasterBlock>();
153 if ( !mInput )
154 {
155 return outputBlock.release();
156 }
157
158 //In some (common) cases, we can simplify the drawing loop considerably and save render time
159 bool fastDraw = ( !usesTransparency() && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0 && mAlphaBand < 1 );
160
161 QList<int> bands;
162 if ( mRedBand > 0 )
163 {
164 bands << mRedBand;
165 }
166 if ( mGreenBand > 0 )
167 {
168 bands << mGreenBand;
169 }
170 if ( mBlueBand > 0 )
171 {
172 bands << mBlueBand;
173 }
174 if ( bands.empty() )
175 {
176 // no need to draw anything if no band is set
177 // TODO:: we should probably return default color block
178 return outputBlock.release();
179 }
180
181 if ( mAlphaBand > 0 )
182 {
183 bands << mAlphaBand;
184 }
185
186 QMap<int, QgsRasterBlock *> bandBlocks;
187 QgsRasterBlock *defaultPointer = nullptr;
188 QList<int>::const_iterator bandIt = bands.constBegin();
189 for ( ; bandIt != bands.constEnd(); ++bandIt )
190 {
191 bandBlocks.insert( *bandIt, defaultPointer );
192 }
193
194 QgsRasterBlock *redBlock = nullptr;
195 QgsRasterBlock *greenBlock = nullptr;
196 QgsRasterBlock *blueBlock = nullptr;
197 QgsRasterBlock *alphaBlock = nullptr;
198
199 bandIt = bands.constBegin();
200 for ( ; bandIt != bands.constEnd(); ++bandIt )
201 {
202 bandBlocks[*bandIt] = mInput->block( *bandIt, extent, width, height, feedback );
203 if ( !bandBlocks[*bandIt] )
204 {
205 // We should free the allocated mem from block().
206 QgsDebugError( u"No input band"_s );
207 --bandIt;
208 for ( ; bandIt != bands.constBegin(); --bandIt )
209 {
210 delete bandBlocks[*bandIt];
211 }
212 return outputBlock.release();
213 }
214 }
215
216 if ( mRedBand > 0 )
217 {
218 redBlock = bandBlocks[mRedBand];
219 }
220 if ( mGreenBand > 0 )
221 {
222 greenBlock = bandBlocks[mGreenBand];
223 }
224 if ( mBlueBand > 0 )
225 {
226 blueBlock = bandBlocks[mBlueBand];
227 }
228 if ( mAlphaBand > 0 )
229 {
230 alphaBlock = bandBlocks[mAlphaBand];
231 }
232
233 if ( !outputBlock->reset( Qgis::DataType::ARGB32_Premultiplied, width, height ) )
234 {
235 for ( int i = 0; i < bandBlocks.size(); i++ )
236 {
237 delete bandBlocks.value( i );
238 }
239 return outputBlock.release();
240 }
241
242 QRgb *outputBlockColorData = outputBlock->colorData();
243
244 // faster data access to data for the common case that input data are coming from RGB image with 8-bit bands
245 const bool hasByteRgb
246 = ( redBlock && greenBlock && blueBlock && redBlock->dataType() == Qgis::DataType::Byte && greenBlock->dataType() == Qgis::DataType::Byte && blueBlock->dataType() == Qgis::DataType::Byte );
247 const quint8 *redData = nullptr, *greenData = nullptr, *blueData = nullptr;
248 if ( hasByteRgb )
249 {
250 redData = redBlock->byteData();
251 greenData = greenBlock->byteData();
252 blueData = blueBlock->byteData();
253 }
254
255 const QRgb myDefaultColor = renderColorForNodataPixel();
256
257 if ( fastDraw )
258 {
259 // By default RGB raster layers have contrast enhancement assigned and normally that requires us to take the slow
260 // route that applies the enhancement. However if the algorithm type is "no enhancement" and all input bands are byte-sized,
261 // no transform would be applied to the input values and we can take the fast route.
262 bool hasEnhancement;
263 if ( hasByteRgb )
264 {
265 hasEnhancement = ( mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
266 || ( mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement )
267 || ( mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement );
268 }
269 else
270 {
271 hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
272 }
273 if ( hasEnhancement )
274 fastDraw = false;
275 }
276
277 const qgssize count = ( qgssize ) width * height;
278 for ( qgssize i = 0; i < count; i++ )
279 {
280 if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc.
281 {
282 if ( hasByteRgb )
283 {
284 if ( redBlock->isNoData( i ) || greenBlock->isNoData( i ) || blueBlock->isNoData( i ) )
285 {
286 outputBlock->setColor( i, myDefaultColor );
287 }
288 else
289 {
290 outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
291 }
292 }
293 else
294 {
295 bool redIsNoData = false;
296 bool greenIsNoData = false;
297 bool blueIsNoData = false;
298 int redVal = 0;
299 int greenVal = 0;
300 int blueVal = 0;
301
302 redVal = redBlock->valueAndNoData( i, redIsNoData );
303 // as soon as any channel has a no data value, don't do any more work -- the result will
304 // always be the nodata color!
305 if ( !redIsNoData )
306 greenVal = greenBlock->valueAndNoData( i, greenIsNoData );
307 if ( !redIsNoData && !greenIsNoData )
308 blueVal = blueBlock->valueAndNoData( i, blueIsNoData );
309
310 if ( redIsNoData || greenIsNoData || blueIsNoData )
311 {
312 outputBlock->setColor( i, myDefaultColor );
313 }
314 else
315 {
316 outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
317 }
318 }
319 continue;
320 }
321
322 bool isNoData = false;
323 double redVal = 0;
324 double greenVal = 0;
325 double blueVal = 0;
326 if ( mRedBand > 0 )
327 {
328 redVal = redBlock->valueAndNoData( i, isNoData );
329 }
330 if ( !isNoData && mGreenBand > 0 )
331 {
332 greenVal = greenBlock->valueAndNoData( i, isNoData );
333 }
334 if ( !isNoData && mBlueBand > 0 )
335 {
336 blueVal = blueBlock->valueAndNoData( i, isNoData );
337 }
338 if ( isNoData )
339 {
340 outputBlock->setColor( i, myDefaultColor );
341 continue;
342 }
343
344 //apply default color if red, green or blue not in displayable range
345 if ( ( mRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( redVal ) )
346 || ( mGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( redVal ) )
347 || ( mBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( redVal ) ) )
348 {
349 outputBlock->setColor( i, myDefaultColor );
350 continue;
351 }
352
353 //stretch color values
354 if ( mRedContrastEnhancement )
355 {
356 redVal = mRedContrastEnhancement->enhanceContrast( redVal );
357 }
358 if ( mGreenContrastEnhancement )
359 {
360 greenVal = mGreenContrastEnhancement->enhanceContrast( greenVal );
361 }
362 if ( mBlueContrastEnhancement )
363 {
364 blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal );
365 }
366
367 //opacity
368 double currentOpacity = mOpacity;
370 {
371 currentOpacity *= mRasterTransparency->opacityForRgbValues( redVal, greenVal, blueVal );
372 }
373 if ( mAlphaBand > 0 )
374 {
375 const double alpha = alphaBlock->value( i );
376 if ( alpha == 0 )
377 {
378 outputBlock->setColor( i, myDefaultColor );
379 continue;
380 }
381 else
382 {
383 currentOpacity *= alpha / 255.0;
384 }
385 }
386
387 if ( qgsDoubleNear( currentOpacity, 1.0 ) )
388 {
389 outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
390 }
391 else
392 {
393 outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
394 }
395 }
396
397 //delete input blocks
398 QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
399 for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
400 {
401 delete bandDelIt.value();
402 }
403
404 return outputBlock.release();
405}
406
408{
409 return mRedContrastEnhancement.get();
410}
411
412void QgsMultiBandColorRenderer::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
413{
414 if ( parentElem.isNull() )
415 {
416 return;
417 }
418
419 QDomElement rasterRendererElem = doc.createElement( u"rasterrenderer"_s );
420 _writeXml( doc, rasterRendererElem );
421 rasterRendererElem.setAttribute( u"redBand"_s, mRedBand );
422 rasterRendererElem.setAttribute( u"greenBand"_s, mGreenBand );
423 rasterRendererElem.setAttribute( u"blueBand"_s, mBlueBand );
424
425 //contrast enhancement
426 if ( mRedContrastEnhancement )
427 {
428 QDomElement redContrastElem = doc.createElement( u"redContrastEnhancement"_s );
429 mRedContrastEnhancement->writeXml( doc, redContrastElem );
430 rasterRendererElem.appendChild( redContrastElem );
431 }
432 if ( mGreenContrastEnhancement )
433 {
434 QDomElement greenContrastElem = doc.createElement( u"greenContrastEnhancement"_s );
435 mGreenContrastEnhancement->writeXml( doc, greenContrastElem );
436 rasterRendererElem.appendChild( greenContrastElem );
437 }
438 if ( mBlueContrastEnhancement )
439 {
440 QDomElement blueContrastElem = doc.createElement( u"blueContrastEnhancement"_s );
441 mBlueContrastEnhancement->writeXml( doc, blueContrastElem );
442 rasterRendererElem.appendChild( blueContrastElem );
443 }
444 parentElem.appendChild( rasterRendererElem );
445}
446
448{
449 QList<int> bandList;
450 if ( mRedBand != -1 )
451 {
452 bandList << mRedBand;
453 }
454 if ( mGreenBand != -1 )
455 {
456 bandList << mGreenBand;
457 }
458 if ( mBlueBand != -1 )
459 {
460 bandList << mBlueBand;
461 }
462 return bandList;
463}
464
465QList<QgsLayerTreeModelLegendNode *> QgsMultiBandColorRenderer::createLegendNodes( QgsLayerTreeLayer *nodeLayer )
466{
467 QList<QgsLayerTreeModelLegendNode *> res;
468 if ( mRedBand != -1 )
469 {
470 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 255, 0, 0 ), displayBandName( mRedBand ) );
471 }
472 if ( mGreenBand != -1 )
473 {
474 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 0, 255, 0 ), displayBandName( mGreenBand ) );
475 }
476 if ( mBlueBand != -1 )
477 {
478 res << new QgsRasterSymbolLegendNode( nodeLayer, QColor( 0, 0, 255 ), displayBandName( mBlueBand ) );
479 }
480
481 return res;
482}
483
484void QgsMultiBandColorRenderer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
485{
486 QgsSldExportContext context;
487 context.setExtraProperties( props );
488 toSld( doc, element, context );
489}
490
491bool QgsMultiBandColorRenderer::toSld( QDomDocument &doc, QDomElement &element, QgsSldExportContext &context ) const
492{
493 // create base structure
494 QgsRasterRenderer::toSld( doc, element, context );
495
496
497#if 0
498 // TODO: the following jumped code is necessary to avoid to export channelSelection in
499 // case it's set as default value. The drawback is that it's necessary to calc band
500 // statistics that can be really slow depending on dataProvider and rastr location.
501 // this is the reason this part of code is commented and the channelSelection is
502 // always exported.
503 //
504 // before to export check if the band combination and contrast setting are the
505 // default ones to avoid to export this tags
506 bool isDefaultCombination = true;
507 QList<int> defaultBandCombination( { 1, 2, 3 } );
508
509 isDefaultCombination = isDefaultCombination && ( usesBands() == defaultBandCombination );
510 isDefaultCombination = isDefaultCombination && (
511 mRedContrastEnhancement->contrastEnhancementAlgorithm() == QgsContrastEnhancement::StretchToMinimumMaximum &&
512 mGreenContrastEnhancement->contrastEnhancementAlgorithm() == QgsContrastEnhancement::StretchToMinimumMaximum &&
513 mBlueContrastEnhancement->contrastEnhancementAlgorithm() == QgsContrastEnhancement::StretchToMinimumMaximum
514 );
515 // compute raster statistics (slow) only if true the previous conditions
516 if ( isDefaultCombination )
517 {
518 QgsRasterBandStats statRed = bandStatistics( 1, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
519 isDefaultCombination = isDefaultCombination && (
520 ( mRedContrastEnhancement->minimumValue() == statRed.minimumValue &&
521 mRedContrastEnhancement->maximumValue() == statRed.maximumValue )
522 );
523 }
524 if ( isDefaultCombination )
525 {
526 QgsRasterBandStats statGreen = bandStatistics( 2, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
527 isDefaultCombination = isDefaultCombination && (
528 ( mGreenContrastEnhancement->minimumValue() == statGreen.minimumValue &&
529 mGreenContrastEnhancement->maximumValue() == statGreen.maximumValue )
530 );
531 }
532 if ( isDefaultCombination )
533 {
534 QgsRasterBandStats statBlue = bandStatistics( 3, QgsRasterBandStats::Min | QgsRasterBandStats::Max );
535 isDefaultCombination = isDefaultCombination && (
536 ( mBlueContrastEnhancement->minimumValue() == statBlue.minimumValue &&
537 mBlueContrastEnhancement->maximumValue() == statBlue.maximumValue )
538 );
539 }
540 if ( isDefaultCombination )
541 return;
542#endif
543
544 // look for RasterSymbolizer tag
545 QDomNodeList elements = element.elementsByTagName( u"sld:RasterSymbolizer"_s );
546 if ( elements.size() == 0 )
547 return false;
548
549 // there SHOULD be only one
550 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
551
552 // add Channel Selection tags
553 // Need to insert channelSelection in the correct sequence as in SLD standard e.g.
554 // after opacity or geometry or as first element after sld:RasterSymbolizer
555 QDomElement channelSelectionElem = doc.createElement( u"sld:ChannelSelection"_s );
556 elements = rasterSymbolizerElem.elementsByTagName( u"sld:Opacity"_s );
557 if ( elements.size() != 0 )
558 {
559 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
560 }
561 else
562 {
563 elements = rasterSymbolizerElem.elementsByTagName( u"sld:Geometry"_s );
564 if ( elements.size() != 0 )
565 {
566 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
567 }
568 else
569 {
570 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
571 }
572 }
573
574 // for each mapped band
575 static QStringList tags { u"sld:RedChannel"_s, u"sld:GreenChannel"_s, u"sld:BlueChannel"_s };
576
577 QList<QgsContrastEnhancement *> contrastEnhancements;
578 contrastEnhancements.append( mRedContrastEnhancement.get() );
579 contrastEnhancements.append( mGreenContrastEnhancement.get() );
580 contrastEnhancements.append( mBlueContrastEnhancement.get() );
581
582 const QList<int> bands = usesBands();
583 QList<int>::const_iterator bandIt = bands.constBegin();
584 for ( int tagCounter = 0; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
585 {
586 if ( *bandIt < 0 )
587 continue;
588
589 QDomElement channelElem = doc.createElement( tags[tagCounter] );
590 channelSelectionElem.appendChild( channelElem );
591
592 // set band
593 QDomElement sourceChannelNameElem = doc.createElement( u"sld:SourceChannelName"_s );
594 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
595 channelElem.appendChild( sourceChannelNameElem );
596
597 // set ContrastEnhancement for each band
598 // NO ContrastEnhancement parameter for the entire bands is managed e.g.
599 // because min/max values can vary depending on band.
600 if ( contrastEnhancements[tagCounter] )
601 {
602 QDomElement contrastEnhancementElem = doc.createElement( u"sld:ContrastEnhancement"_s );
603 contrastEnhancements[tagCounter]->toSld( doc, contrastEnhancementElem );
604 channelElem.appendChild( contrastEnhancementElem );
605 }
606 }
607 return true;
608}
609
610bool QgsMultiBandColorRenderer::refresh( const QgsRectangle &extent, const QList<double> &min, const QList<double> &max, bool forceRefresh )
611{
612 if ( !needsRefresh( extent ) && !forceRefresh )
613 {
614 return false;
615 }
616
617 bool refreshed = false;
618 if ( min.size() >= 3 && max.size() >= 3 )
619 {
621
622 if ( mRedContrastEnhancement && mRedContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement && !std::isnan( min[0] ) && !std::isnan( max[0] ) )
623 {
624 mRedContrastEnhancement->setMinimumValue( min[0] );
625 mRedContrastEnhancement->setMaximumValue( max[0] );
626 refreshed = true;
627 }
628
629 if ( mGreenContrastEnhancement && mGreenContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement && !std::isnan( min[1] ) && !std::isnan( max[1] ) )
630 {
631 mGreenContrastEnhancement->setMinimumValue( min[1] );
632 mGreenContrastEnhancement->setMaximumValue( max[1] );
633 refreshed = true;
634 }
635
636 if ( mBlueContrastEnhancement && mBlueContrastEnhancement->contrastEnhancementAlgorithm() != QgsContrastEnhancement::NoEnhancement && !std::isnan( min[2] ) && !std::isnan( max[2] ) )
637 {
638 mBlueContrastEnhancement->setMinimumValue( min[2] );
639 mBlueContrastEnhancement->setMaximumValue( max[2] );
640 refreshed = true;
641 }
642 }
643
644 return refreshed;
645}
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
Definition qgis.h:1591
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
Definition qgis.h:1581
DataType
Raster data types.
Definition qgis.h:393
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition qgis.h:408
@ Byte
Eight bit unsigned integer (quint8).
Definition qgis.h:395
Handles contrast enhancement and clipping.
@ StretchToMinimumMaximum
Linear histogram.
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
Layer tree node points to a map layer.
bool refresh(const QgsRectangle &extent, const QList< double > &min, const QList< double > &max, bool forceRefresh=false) override
Refreshes the renderer according to the min and max values associated with the extent.
QgsMultiBandColorRenderer(QgsRasterInterface *input, int redBand, int greenBand, int blueBand, QgsContrastEnhancement *redEnhancement=nullptr, QgsContrastEnhancement *greenEnhancement=nullptr, QgsContrastEnhancement *blueEnhancement=nullptr)
Constructor for QgsMultiBandColorRenderer.
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.
Q_DECL_DEPRECATED 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.
int blueBand() const
Returns the band number for the blue channel.
~QgsMultiBandColorRenderer() override
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.
int redBand() const
Returns the band number for the red channel.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
int greenBand() const
Returns the band number for the green channel.
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 value(int row, int column) const
Read a single value if type of block is numeric.
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.
bool isNoData(int row, int column) const
Checks if value at position is no data.
Qgis::DataType dataType() const
Returns data type.
const quint8 * byteData() const
Gives direct access to the raster block data.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, 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.
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.
QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded
To save computations and possible infinite cycle of notifications.
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).
bool usesTransparency() const
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
bool needsRefresh(const QgsRectangle &extent) const
Checks if the renderer needs to be refreshed according to extent.
virtual Q_DECL_DEPRECATED 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.
A rectangle specified with double values.
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
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:7485
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:6975
#define QgsDebugError(str)
Definition qgslogger.h:59