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