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