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 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.
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)