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