25#include <QDomDocument> 
   36  , mGreenBand( greenBand )
 
   37  , mBlueBand( blueBand )
 
   38  , mRedContrastEnhancement( redEnhancement )
 
   39  , mGreenContrastEnhancement( greenEnhancement )
 
   40  , mBlueContrastEnhancement( blueEnhancement )
 
   46  delete mRedContrastEnhancement;
 
   47  delete mGreenContrastEnhancement;
 
   48  delete mBlueContrastEnhancement;
 
   56  if ( mRedContrastEnhancement )
 
   60  if ( mGreenContrastEnhancement )
 
   64  if ( mBlueContrastEnhancement )
 
   79  delete mRedContrastEnhancement;
 
   80  mRedContrastEnhancement = ce;
 
   85  delete mGreenContrastEnhancement;
 
   86  mGreenContrastEnhancement = ce;
 
   91  delete mBlueContrastEnhancement;
 
   92  mBlueContrastEnhancement = ce;
 
  103  const int redBand = elem.attribute( QStringLiteral( 
"redBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
  104  const int greenBand = elem.attribute( QStringLiteral( 
"greenBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
  105  const int blueBand = elem.attribute( QStringLiteral( 
"blueBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
  109  const QDomElement redContrastElem = elem.firstChildElement( QStringLiteral( 
"redContrastEnhancement" ) );
 
  110  if ( !redContrastElem.isNull() )
 
  118  const QDomElement greenContrastElem = elem.firstChildElement( QStringLiteral( 
"greenContrastEnhancement" ) );
 
  119  if ( !greenContrastElem.isNull() )
 
  127  const QDomElement blueContrastElem = elem.firstChildElement( QStringLiteral( 
"blueContrastEnhancement" ) );
 
  128  if ( !blueContrastElem.isNull() )
 
  144  std::unique_ptr< QgsRasterBlock > outputBlock( 
new QgsRasterBlock() );
 
  147    return outputBlock.release();
 
  152                    && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
 
  160  if ( mGreenBand > 0 )
 
  172    return outputBlock.release();
 
  180  QMap<int, QgsRasterBlock *> bandBlocks;
 
  182  QList<int>::const_iterator bandIt = bands.constBegin();
 
  183  for ( ; bandIt != bands.constEnd(); ++bandIt )
 
  185    bandBlocks.insert( *bandIt, defaultPointer );
 
  193  bandIt = bands.constBegin();
 
  194  for ( ; bandIt != bands.constEnd(); ++bandIt )
 
  197    if ( !bandBlocks[*bandIt] )
 
  202      for ( ; bandIt != bands.constBegin(); --bandIt )
 
  204        delete bandBlocks[*bandIt];
 
  206      return outputBlock.release();
 
  212    redBlock = bandBlocks[mRedBand];
 
  214  if ( mGreenBand > 0 )
 
  216    greenBlock = bandBlocks[mGreenBand];
 
  220    blueBlock = bandBlocks[mBlueBand];
 
  229    for ( 
int i = 0; i < bandBlocks.size(); i++ )
 
  231      delete bandBlocks.
value( i );
 
  233    return outputBlock.release();
 
  236  QRgb *outputBlockColorData = outputBlock->colorData();
 
  240  const quint8 *redData = 
nullptr, *greenData = 
nullptr, *blueData = 
nullptr;
 
  265      hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
 
  267    if ( hasEnhancement )
 
  272  for ( 
qgssize i = 0; i < count; i++ )
 
  282          outputBlock->setColor( i, myDefaultColor );
 
  286          outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
 
  291        bool redIsNoData = 
false;
 
  292        bool greenIsNoData = 
false;
 
  293        bool blueIsNoData = 
false;
 
  303        if ( !redIsNoData && !greenIsNoData )
 
  310          outputBlock->setColor( i, myDefaultColor );
 
  314          outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
 
  320    bool isNoData = 
false;
 
  328    if ( !isNoData && mGreenBand > 0 )
 
  332    if ( !isNoData && mBlueBand > 0 )
 
  338      outputBlock->setColor( i, myDefaultColor );
 
  347      outputBlock->setColor( i, myDefaultColor );
 
  352    if ( mRedContrastEnhancement )
 
  356    if ( mGreenContrastEnhancement )
 
  360    if ( mBlueContrastEnhancement )
 
  373      const double alpha = alphaBlock->
value( i );
 
  376        outputBlock->setColor( i, myDefaultColor );
 
  381        currentOpacity *= alpha / 255.0;
 
  387      outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
 
  391      outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
 
  396  QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
 
  397  for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
 
  399    delete bandDelIt.value();
 
  402  return outputBlock.release();
 
  407  if ( parentElem.isNull() )
 
  412  QDomElement rasterRendererElem = doc.createElement( QStringLiteral( 
"rasterrenderer" ) );
 
  414  rasterRendererElem.setAttribute( QStringLiteral( 
"redBand" ), mRedBand );
 
  415  rasterRendererElem.setAttribute( QStringLiteral( 
"greenBand" ), mGreenBand );
 
  416  rasterRendererElem.setAttribute( QStringLiteral( 
"blueBand" ), mBlueBand );
 
  419  if ( mRedContrastEnhancement )
 
  421    QDomElement redContrastElem = doc.createElement( QStringLiteral( 
"redContrastEnhancement" ) );
 
  422    mRedContrastEnhancement->
writeXml( doc, redContrastElem );
 
  423    rasterRendererElem.appendChild( redContrastElem );
 
  425  if ( mGreenContrastEnhancement )
 
  427    QDomElement greenContrastElem = doc.createElement( QStringLiteral( 
"greenContrastEnhancement" ) );
 
  428    mGreenContrastEnhancement->
writeXml( doc, greenContrastElem );
 
  429    rasterRendererElem.appendChild( greenContrastElem );
 
  431  if ( mBlueContrastEnhancement )
 
  433    QDomElement blueContrastElem = doc.createElement( QStringLiteral( 
"blueContrastEnhancement" ) );
 
  434    mBlueContrastEnhancement->
writeXml( doc, blueContrastElem );
 
  435    rasterRendererElem.appendChild( blueContrastElem );
 
  437  parentElem.appendChild( rasterRendererElem );
 
  443  if ( mRedBand != -1 )
 
  445    bandList << mRedBand;
 
  447  if ( mGreenBand != -1 )
 
  449    bandList << mGreenBand;
 
  451  if ( mBlueBand != -1 )
 
  453    bandList << mBlueBand;
 
  460  QList<QgsLayerTreeModelLegendNode *> res;
 
  461  if ( mRedBand != -1 )
 
  465  if ( mGreenBand != -1 )
 
  469  if ( mBlueBand != -1 )
 
  492  bool isDefaultCombination = 
true;
 
  493  QList<int> defaultBandCombination( { 1, 2, 3 } );
 
  495  isDefaultCombination = isDefaultCombination && ( 
usesBands() == defaultBandCombination );
 
  496  isDefaultCombination = isDefaultCombination && (
 
  502  if ( isDefaultCombination )
 
  505    isDefaultCombination = isDefaultCombination && (
 
  510  if ( isDefaultCombination )
 
  513    isDefaultCombination = isDefaultCombination && (
 
  518  if ( isDefaultCombination )
 
  521    isDefaultCombination = isDefaultCombination && (
 
  526  if ( isDefaultCombination )
 
  531  QDomNodeList elements = element.elementsByTagName( QStringLiteral( 
"sld:RasterSymbolizer" ) );
 
  532  if ( elements.size() == 0 )
 
  536  QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
 
  541  QDomElement channelSelectionElem = doc.createElement( QStringLiteral( 
"sld:ChannelSelection" ) );
 
  542  elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Opacity" ) );
 
  543  if ( elements.size() != 0 )
 
  545    rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
 
  549    elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Geometry" ) );
 
  550    if ( elements.size() != 0 )
 
  552      rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
 
  556      rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
 
  561  static QStringList tags { QStringLiteral( 
"sld:RedChannel" ), QStringLiteral( 
"sld:GreenChannel" ), QStringLiteral( 
"sld:BlueChannel" ) };
 
  563  QList<QgsContrastEnhancement *> contrastEnhancements;
 
  564  contrastEnhancements.append( mRedContrastEnhancement );
 
  565  contrastEnhancements.append( mGreenContrastEnhancement );
 
  566  contrastEnhancements.append( mBlueContrastEnhancement );
 
  569  QList<int>::const_iterator bandIt = bands.constBegin();
 
  570  for ( 
int tagCounter = 0 ; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
 
  575    QDomElement channelElem = doc.createElement( tags[ tagCounter ] );
 
  576    channelSelectionElem.appendChild( channelElem );
 
  579    QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( 
"sld:SourceChannelName" ) );
 
  580    sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
 
  581    channelElem.appendChild( sourceChannelNameElem );
 
  586    if ( contrastEnhancements[ tagCounter ] )
 
  588      QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral( 
"sld:ContrastEnhancement" ) );
 
  589      contrastEnhancements[ tagCounter ]->toSld( doc, contrastEnhancementElem );
 
  590      channelElem.appendChild( contrastEnhancementElem );
 
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
 
DataType
Raster data types.
 
@ 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 * 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.
 
~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.
 
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.
 
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.
 
const quint8 * byteData() const
Gives direct access to the raster block data.
 
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 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.
 
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.
 
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.
 
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...
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
#define QgsDebugError(str)