23 #include <QDomDocument> 24 #include <QDomElement> 34 , mGreenBand( greenBand )
35 , mBlueBand( blueBand )
36 , mRedContrastEnhancement( redEnhancement )
37 , mGreenContrastEnhancement( greenEnhancement )
38 , mBlueContrastEnhancement( blueEnhancement )
44 delete mRedContrastEnhancement;
45 delete mGreenContrastEnhancement;
46 delete mBlueContrastEnhancement;
54 if ( mRedContrastEnhancement )
58 if ( mGreenContrastEnhancement )
62 if ( mBlueContrastEnhancement )
72 delete mRedContrastEnhancement;
73 mRedContrastEnhancement = ce;
78 delete mGreenContrastEnhancement;
79 mGreenContrastEnhancement = ce;
84 delete mBlueContrastEnhancement;
85 mBlueContrastEnhancement = ce;
96 int redBand = elem.attribute( QStringLiteral(
"redBand" ), QStringLiteral(
"-1" ) ).toInt();
97 int greenBand = elem.attribute( QStringLiteral(
"greenBand" ), QStringLiteral(
"-1" ) ).toInt();
98 int blueBand = elem.attribute( QStringLiteral(
"blueBand" ), QStringLiteral(
"-1" ) ).toInt();
102 QDomElement redContrastElem = elem.firstChildElement( QStringLiteral(
"redContrastEnhancement" ) );
103 if ( !redContrastElem.isNull() )
107 redContrastEnhancement->
readXml( redContrastElem );
111 QDomElement greenContrastElem = elem.firstChildElement( QStringLiteral(
"greenContrastEnhancement" ) );
112 if ( !greenContrastElem.isNull() )
116 greenContrastEnhancement->
readXml( greenContrastElem );
120 QDomElement blueContrastElem = elem.firstChildElement( QStringLiteral(
"blueContrastEnhancement" ) );
121 if ( !blueContrastElem.isNull() )
125 blueContrastEnhancement->
readXml( blueContrastElem );
129 greenContrastEnhancement, blueContrastEnhancement );
137 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
140 return outputBlock.release();
145 && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
153 if ( mGreenBand > 0 )
165 return outputBlock.release();
173 QMap<int, QgsRasterBlock *> bandBlocks;
175 QSet<int>::const_iterator bandIt = bands.constBegin();
176 for ( ; bandIt != bands.constEnd(); ++bandIt )
178 bandBlocks.insert( *bandIt, defaultPointer );
186 bandIt = bands.constBegin();
187 for ( ; bandIt != bands.constEnd(); ++bandIt )
189 bandBlocks[*bandIt] =
mInput->
block( *bandIt, extent, width, height, feedback );
190 if ( !bandBlocks[*bandIt] )
195 for ( ; bandIt != bands.constBegin(); --bandIt )
197 delete bandBlocks[*bandIt];
199 return outputBlock.release();
205 redBlock = bandBlocks[mRedBand];
207 if ( mGreenBand > 0 )
209 greenBlock = bandBlocks[mGreenBand];
213 blueBlock = bandBlocks[mBlueBand];
222 for (
int i = 0; i < bandBlocks.size(); i++ )
224 delete bandBlocks.
value( i );
226 return outputBlock.release();
229 QRgb *outputBlockColorData = outputBlock->colorData();
233 const quint8 *redData =
nullptr, *greenData =
nullptr, *blueData =
nullptr;
258 hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
260 if ( hasEnhancement )
265 for (
qgssize i = 0; i < count; i++ )
273 outputBlock->setColor( i, myDefaultColor );
279 outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
283 int redVal =
static_cast<int>( redBlock->
value( i ) );
284 int greenVal =
static_cast<int>( greenBlock->
value( i ) );
285 int blueVal =
static_cast<int>( blueBlock->
value( i ) );
286 outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
292 bool isNoData =
false;
298 redVal = redBlock->
value( i );
299 if ( redBlock->
isNoData( i ) ) isNoData =
true;
301 if ( !isNoData && mGreenBand > 0 )
303 greenVal = greenBlock->
value( i );
304 if ( greenBlock->
isNoData( i ) ) isNoData =
true;
306 if ( !isNoData && mBlueBand > 0 )
308 blueVal = blueBlock->
value( i );
309 if ( blueBlock->
isNoData( i ) ) isNoData =
true;
313 outputBlock->setColor( i, myDefaultColor );
322 outputBlock->setColor( i, myDefaultColor );
327 if ( mRedContrastEnhancement )
331 if ( mGreenContrastEnhancement )
335 if ( mBlueContrastEnhancement )
348 currentOpacity *= alphaBlock->
value( i ) / 255.0;
353 outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
357 outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
362 QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
363 for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
365 delete bandDelIt.value();
368 return outputBlock.release();
373 if ( parentElem.isNull() )
378 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
380 rasterRendererElem.setAttribute( QStringLiteral(
"redBand" ), mRedBand );
381 rasterRendererElem.setAttribute( QStringLiteral(
"greenBand" ), mGreenBand );
382 rasterRendererElem.setAttribute( QStringLiteral(
"blueBand" ), mBlueBand );
385 if ( mRedContrastEnhancement )
387 QDomElement redContrastElem = doc.createElement( QStringLiteral(
"redContrastEnhancement" ) );
388 mRedContrastEnhancement->
writeXml( doc, redContrastElem );
389 rasterRendererElem.appendChild( redContrastElem );
391 if ( mGreenContrastEnhancement )
393 QDomElement greenContrastElem = doc.createElement( QStringLiteral(
"greenContrastEnhancement" ) );
394 mGreenContrastEnhancement->
writeXml( doc, greenContrastElem );
395 rasterRendererElem.appendChild( greenContrastElem );
397 if ( mBlueContrastEnhancement )
399 QDomElement blueContrastElem = doc.createElement( QStringLiteral(
"blueContrastEnhancement" ) );
400 mBlueContrastEnhancement->
writeXml( doc, blueContrastElem );
401 rasterRendererElem.appendChild( blueContrastElem );
403 parentElem.appendChild( rasterRendererElem );
409 if ( mRedBand != -1 )
411 bandList << mRedBand;
413 if ( mGreenBand != -1 )
415 bandList << mGreenBand;
417 if ( mBlueBand != -1 )
419 bandList << mBlueBand;
441 bool isDefaultCombination =
true;
442 QList<int> defaultBandCombination( { 1, 2, 3 } );
444 isDefaultCombination = isDefaultCombination && (
usesBands() == defaultBandCombination );
445 isDefaultCombination = isDefaultCombination && (
451 if ( isDefaultCombination )
454 isDefaultCombination = isDefaultCombination && (
459 if ( isDefaultCombination )
462 isDefaultCombination = isDefaultCombination && (
467 if ( isDefaultCombination )
470 isDefaultCombination = isDefaultCombination && (
475 if ( isDefaultCombination ):
480 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
481 if ( elements.size() == 0 )
485 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
490 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
491 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
492 if ( elements.size() != 0 )
494 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
498 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
499 if ( elements.size() != 0 )
501 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
505 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
510 static QStringList tags { QStringLiteral(
"sld:RedChannel" ), QStringLiteral(
"sld:GreenChannel" ), QStringLiteral(
"sld:BlueChannel" ) };
512 QList<QgsContrastEnhancement *> contrastEnhancements;
513 contrastEnhancements.append( mRedContrastEnhancement );
514 contrastEnhancements.append( mGreenContrastEnhancement );
515 contrastEnhancements.append( mBlueContrastEnhancement );
518 QList<int>::const_iterator bandIt = bands.constBegin();
519 for (
int tagCounter = 0 ; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
524 QDomElement channelElem = doc.createElement( tags[ tagCounter ] );
525 channelSelectionElem.appendChild( channelElem );
528 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
529 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
530 channelElem.appendChild( sourceChannelNameElem );
535 if ( contrastEnhancements[ tagCounter ] )
537 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
538 contrastEnhancements[ tagCounter ]->toSld( doc, contrastEnhancementElem );
539 channelElem.appendChild( contrastEnhancementElem );
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
Qgis::DataType dataType() const
Returns data type.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
~QgsMultiBandColorRenderer() override
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
const QgsContrastEnhancement * greenContrastEnhancement() const
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
DataType
Raster data types.
double maximumValue
The maximum cell value in the raster band.
virtual QgsRasterInterface * input() const
Current input.
const QgsContrastEnhancement * redContrastEnhancement() const
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
QgsMultiBandColorRenderer * clone() const override
Clone itself, create deep copy.
QMap< QString, QString > QgsStringMap
void setGreenContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
bool usesTransparency() const
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
static const QRgb NODATA_COLOR
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
The RasterBandStats struct is a container for statistics about a single raster band.
void setRedContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
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.
double value(int row, int column) const
Read a single value if type of block is numeric.
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
bool isValueInDisplayableRange(double value)
Returns true if a pixel value is in displayable range, false if pixel is outside of range (i...
void readXml(const QDomElement &elem)
const quint8 * byteData() const
Gives direct access to the raster block data.
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
int mAlphaBand
Read alpha value from band.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Base class for processing filters like renderers, reprojector, resampler etc.
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...
const QgsContrastEnhancement * blueContrastEnhancement() const
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual QgsRectangle extent() const
Gets the extent of the interface.
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
void setBlueContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
double minimumValue
The minimum cell value in the raster band.
Renderer for multiband images with the color components.
bool isNoData(int row, int column) const
Check if value at position is no data.
double mOpacity
Global alpha value (0-1)
Manipulates raster pixel values so that they enhanceContrast or clip into a specified numerical range...
QgsMultiBandColorRenderer(QgsRasterInterface *input, int redBand, int greenBand, int blueBand, QgsContrastEnhancement *redEnhancement=nullptr, QgsContrastEnhancement *greenEnhancement=nullptr, QgsContrastEnhancement *blueEnhancement=nullptr)
QgsRasterInterface * mInput
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.
Eight bit unsigned integer (quint8)
int enhanceContrast(double value)
Applies the contrast enhancement to a value.