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