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