25 #include <QDomDocument> 
   26 #include <QDomElement> 
   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 )
 
   74   delete mRedContrastEnhancement;
 
   75   mRedContrastEnhancement = ce;
 
   80   delete mGreenContrastEnhancement;
 
   81   mGreenContrastEnhancement = ce;
 
   86   delete mBlueContrastEnhancement;
 
   87   mBlueContrastEnhancement = ce;
 
   98   int redBand = elem.attribute( QStringLiteral( 
"redBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
   99   int greenBand = elem.attribute( QStringLiteral( 
"greenBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
  100   int blueBand = elem.attribute( QStringLiteral( 
"blueBand" ), QStringLiteral( 
"-1" ) ).toInt();
 
  104   QDomElement redContrastElem = elem.firstChildElement( QStringLiteral( 
"redContrastEnhancement" ) );
 
  105   if ( !redContrastElem.isNull() )
 
  113   QDomElement greenContrastElem = elem.firstChildElement( QStringLiteral( 
"greenContrastEnhancement" ) );
 
  114   if ( !greenContrastElem.isNull() )
 
  122   QDomElement blueContrastElem = elem.firstChildElement( QStringLiteral( 
"blueContrastEnhancement" ) );
 
  123   if ( !blueContrastElem.isNull() )
 
  139   std::unique_ptr< QgsRasterBlock > outputBlock( 
new QgsRasterBlock() );
 
  142     return outputBlock.release();
 
  147                     && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0
 
  155   if ( mGreenBand > 0 )
 
  167     return outputBlock.release();
 
  175   QMap<int, QgsRasterBlock *> bandBlocks;
 
  177   QList<int>::const_iterator bandIt = bands.constBegin();
 
  178   for ( ; bandIt != bands.constEnd(); ++bandIt )
 
  180     bandBlocks.insert( *bandIt, defaultPointer );
 
  188   bandIt = bands.constBegin();
 
  189   for ( ; bandIt != bands.constEnd(); ++bandIt )
 
  192     if ( !bandBlocks[*bandIt] )
 
  197       for ( ; bandIt != bands.constBegin(); --bandIt )
 
  199         delete bandBlocks[*bandIt];
 
  201       return outputBlock.release();
 
  207     redBlock = bandBlocks[mRedBand];
 
  209   if ( mGreenBand > 0 )
 
  211     greenBlock = bandBlocks[mGreenBand];
 
  215     blueBlock = bandBlocks[mBlueBand];
 
  224     for ( 
int i = 0; i < bandBlocks.size(); i++ )
 
  226       delete bandBlocks.
value( i );
 
  228     return outputBlock.release();
 
  231   QRgb *outputBlockColorData = outputBlock->colorData();
 
  235   const quint8 *redData = 
nullptr, *greenData = 
nullptr, *blueData = 
nullptr;
 
  260       hasEnhancement = mRedContrastEnhancement || mGreenContrastEnhancement || mBlueContrastEnhancement;
 
  262     if ( hasEnhancement )
 
  267   for ( 
qgssize i = 0; i < count; i++ )
 
  277           outputBlock->setColor( i, myDefaultColor );
 
  281           outputBlockColorData[i] = qRgb( redData[i], greenData[i], blueData[i] );
 
  286         bool redIsNoData = 
false;
 
  287         bool greenIsNoData = 
false;
 
  288         bool blueIsNoData = 
false;
 
  298         if ( !redIsNoData && !greenIsNoData )
 
  305           outputBlock->setColor( i, myDefaultColor );
 
  309           outputBlockColorData[i] = qRgb( redVal, greenVal, blueVal );
 
  315     bool isNoData = 
false;
 
  323     if ( !isNoData && mGreenBand > 0 )
 
  327     if ( !isNoData && mBlueBand > 0 )
 
  333       outputBlock->setColor( i, myDefaultColor );
 
  342       outputBlock->setColor( i, myDefaultColor );
 
  347     if ( mRedContrastEnhancement )
 
  351     if ( mGreenContrastEnhancement )
 
  355     if ( mBlueContrastEnhancement )
 
  368       currentOpacity *= alphaBlock->
value( i ) / 255.0;
 
  373       outputBlock->setColor( i, qRgba( redVal, greenVal, blueVal, 255 ) );
 
  377       outputBlock->setColor( i, qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ) );
 
  382   QMap<int, QgsRasterBlock *>::const_iterator bandDelIt = bandBlocks.constBegin();
 
  383   for ( ; bandDelIt != bandBlocks.constEnd(); ++bandDelIt )
 
  385     delete bandDelIt.value();
 
  388   return outputBlock.release();
 
  393   if ( parentElem.isNull() )
 
  398   QDomElement rasterRendererElem = doc.createElement( QStringLiteral( 
"rasterrenderer" ) );
 
  400   rasterRendererElem.setAttribute( QStringLiteral( 
"redBand" ), mRedBand );
 
  401   rasterRendererElem.setAttribute( QStringLiteral( 
"greenBand" ), mGreenBand );
 
  402   rasterRendererElem.setAttribute( QStringLiteral( 
"blueBand" ), mBlueBand );
 
  405   if ( mRedContrastEnhancement )
 
  407     QDomElement redContrastElem = doc.createElement( QStringLiteral( 
"redContrastEnhancement" ) );
 
  408     mRedContrastEnhancement->
writeXml( doc, redContrastElem );
 
  409     rasterRendererElem.appendChild( redContrastElem );
 
  411   if ( mGreenContrastEnhancement )
 
  413     QDomElement greenContrastElem = doc.createElement( QStringLiteral( 
"greenContrastEnhancement" ) );
 
  414     mGreenContrastEnhancement->
writeXml( doc, greenContrastElem );
 
  415     rasterRendererElem.appendChild( greenContrastElem );
 
  417   if ( mBlueContrastEnhancement )
 
  419     QDomElement blueContrastElem = doc.createElement( QStringLiteral( 
"blueContrastEnhancement" ) );
 
  420     mBlueContrastEnhancement->
writeXml( doc, blueContrastElem );
 
  421     rasterRendererElem.appendChild( blueContrastElem );
 
  423   parentElem.appendChild( rasterRendererElem );
 
  429   if ( mRedBand != -1 )
 
  431     bandList << mRedBand;
 
  433   if ( mGreenBand != -1 )
 
  435     bandList << mGreenBand;
 
  437   if ( mBlueBand != -1 )
 
  439     bandList << mBlueBand;
 
  446   QList<QgsLayerTreeModelLegendNode *> res;
 
  447   if ( mRedBand != -1 )
 
  451   if ( mGreenBand != -1 )
 
  455   if ( mBlueBand != -1 )
 
  478   bool isDefaultCombination = 
true;
 
  479   QList<int> defaultBandCombination( { 1, 2, 3 } );
 
  481   isDefaultCombination = isDefaultCombination && ( 
usesBands() == defaultBandCombination );
 
  482   isDefaultCombination = isDefaultCombination && (
 
  488   if ( isDefaultCombination )
 
  491     isDefaultCombination = isDefaultCombination && (
 
  496   if ( isDefaultCombination )
 
  499     isDefaultCombination = isDefaultCombination && (
 
  504   if ( isDefaultCombination )
 
  507     isDefaultCombination = isDefaultCombination && (
 
  512   if ( isDefaultCombination )
 
  517   QDomNodeList elements = element.elementsByTagName( QStringLiteral( 
"sld:RasterSymbolizer" ) );
 
  518   if ( elements.size() == 0 )
 
  522   QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
 
  527   QDomElement channelSelectionElem = doc.createElement( QStringLiteral( 
"sld:ChannelSelection" ) );
 
  528   elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Opacity" ) );
 
  529   if ( elements.size() != 0 )
 
  531     rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
 
  535     elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral( 
"sld:Geometry" ) );
 
  536     if ( elements.size() != 0 )
 
  538       rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
 
  542       rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
 
  547   static QStringList tags { QStringLiteral( 
"sld:RedChannel" ), QStringLiteral( 
"sld:GreenChannel" ), QStringLiteral( 
"sld:BlueChannel" ) };
 
  549   QList<QgsContrastEnhancement *> contrastEnhancements;
 
  550   contrastEnhancements.append( mRedContrastEnhancement );
 
  551   contrastEnhancements.append( mGreenContrastEnhancement );
 
  552   contrastEnhancements.append( mBlueContrastEnhancement );
 
  555   QList<int>::const_iterator bandIt = bands.constBegin();
 
  556   for ( 
int tagCounter = 0 ; bandIt != bands.constEnd(); ++bandIt, ++tagCounter )
 
  561     QDomElement channelElem = doc.createElement( tags[ tagCounter ] );
 
  562     channelSelectionElem.appendChild( channelElem );
 
  565     QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral( 
"sld:SourceChannelName" ) );
 
  566     sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( *bandIt ) ) );
 
  567     channelElem.appendChild( sourceChannelNameElem );
 
  572     if ( contrastEnhancements[ tagCounter ] )
 
  574       QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral( 
"sld:ContrastEnhancement" ) );
 
  575       contrastEnhancements[ tagCounter ]->toSld( doc, contrastEnhancementElem );
 
  576       channelElem.appendChild( contrastEnhancementElem );
 
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 * 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.
~QgsMultiBandColorRenderer() override
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.
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.
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)