31#include <QDomDocument>
36using namespace Qt::StringLiterals;
41 , mContrastEnhancement( nullptr )
51 if ( mContrastEnhancement )
71 const int grayBand = elem.attribute( u
"grayBand"_s, u
"-1"_s ).toInt();
75 if ( elem.attribute( u
"gradient"_s ) ==
"WhiteToBlack"_L1 )
80 const QDomElement contrastEnhancementElem = elem.firstChildElement( u
"contrastEnhancement"_s );
81 if ( !contrastEnhancementElem.isNull() )
84 ce->
readXml( contrastEnhancementElem );
88 auto legendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
97 mContrastEnhancement.reset( ce );
103 QgsDebugMsgLevel( u
"width = %1 height = %2"_s.arg( width ).arg( height ), 4 );
105 auto outputBlock = std::make_unique<QgsRasterBlock>();
108 return outputBlock.release();
111 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->block( mGrayBand,
extent, width, height, feedback ) );
112 if ( !inputBlock || inputBlock->isEmpty() )
115 return outputBlock.release();
118 std::shared_ptr< QgsRasterBlock > alphaBlock;
123 if ( !alphaBlock || alphaBlock->isEmpty() )
126 return outputBlock.release();
131 alphaBlock = inputBlock;
136 return outputBlock.release();
140 bool isNoData =
false;
143 double grayVal = inputBlock->valueAndNoData( i, isNoData );
147 outputBlock->setColor( i, myDefaultColor );
158 const double alpha = alphaBlock->value( i );
161 outputBlock->setColor( i, myDefaultColor );
166 currentAlpha *= alpha / 255.0;
170 if ( mContrastEnhancement )
172 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
174 outputBlock->setColor( i, myDefaultColor );
177 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
182 grayVal = 255 - grayVal;
187 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
191 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
195 return outputBlock.release();
215 else if ( band > 0 && band <= mInput->
bandCount() )
225 if ( parentElem.isNull() )
230 QDomElement rasterRendererElem = doc.createElement( u
"rasterrenderer"_s );
233 rasterRendererElem.setAttribute( u
"grayBand"_s, mGrayBand );
244 rasterRendererElem.setAttribute( u
"gradient"_s,
gradient );
246 if ( mContrastEnhancement )
248 QDomElement contrastElem = doc.createElement( u
"contrastEnhancement"_s );
249 mContrastEnhancement->writeXml( doc, contrastElem );
250 rasterRendererElem.appendChild( contrastElem );
253 if ( mLegendSettings )
256 parentElem.appendChild( rasterRendererElem );
261 QList<QPair<QString, QColor> > symbolItems;
264 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
265 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
266 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
267 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
274 QList<QgsLayerTreeModelLegendNode *> res;
278 if ( !name.isEmpty() )
283 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
284 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
289 mContrastEnhancement->minimumValue(),
290 mContrastEnhancement->maximumValue()
299 if ( mGrayBand != -1 )
301 bandList << mGrayBand;
310 toSld( doc, element, context );
319 QDomNodeList elements = element.elementsByTagName( u
"sld:RasterSymbolizer"_s );
320 if ( elements.size() == 0 )
324 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
329 QDomElement channelSelectionElem = doc.createElement( u
"sld:ChannelSelection"_s );
330 elements = rasterSymbolizerElem.elementsByTagName( u
"sld:Opacity"_s );
331 if ( elements.size() != 0 )
333 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
337 elements = rasterSymbolizerElem.elementsByTagName( u
"sld:Geometry"_s );
338 if ( elements.size() != 0 )
340 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
344 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
349 QDomElement channelElem = doc.createElement( u
"sld:GrayChannel"_s );
350 channelSelectionElem.appendChild( channelElem );
353 QDomElement sourceChannelNameElem = doc.createElement( u
"sld:SourceChannelName"_s );
354 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( mGrayBand ) ) );
355 channelElem.appendChild( sourceChannelNameElem );
360 QDomElement contrastEnhancementElem = doc.createElement( u
"sld:ContrastEnhancement"_s );
361 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
367 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
379 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( u
"sld:VendorOption"_s );
380 for (
int i = 0; i < vendorOptions.size(); ++i )
382 QDomElement vendorOption = vendorOptions.at( i ).toElement();
383 if ( vendorOption.attribute( u
"name"_s ) !=
"minValue"_L1 )
387 vendorOption.removeChild( vendorOption.firstChild() );
388 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
401 channelElem.appendChild( contrastEnhancementElem );
409 QDomElement colorMapElem = doc.createElement( u
"sld:ColorMap"_s );
410 rasterSymbolizerElem.appendChild( colorMapElem );
419 QList< QPair< QString, QColor > > colorMapping( classes );
425 const QString lowValue = classes[0].first;
426 QColor lowColor = classes[0].second;
427 lowColor.setAlpha( 0 );
428 const QString highValue = classes[1].first;
429 QColor highColor = classes[1].second;
430 highColor.setAlpha( 0 );
432 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
433 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
438 colorMapping[0].first = u
"0"_s;
439 colorMapping[1].first = u
"255"_s;
449 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd(); ++it )
452 QDomElement lowColorMapEntryElem = doc.createElement( u
"sld:ColorMapEntry"_s );
453 colorMapElem.appendChild( lowColorMapEntryElem );
454 lowColorMapEntryElem.setAttribute( u
"color"_s, it->second.name() );
455 lowColorMapEntryElem.setAttribute( u
"quantity"_s, it->first );
456 if ( it->second.alphaF() == 0.0 )
458 lowColorMapEntryElem.setAttribute( u
"opacity"_s, QString::number( it->second.alpha() ) );
466 return mLegendSettings.get();
471 if ( settings == mLegendSettings.get() )
473 mLegendSettings.reset( settings );
483 bool refreshed =
false;
487 mContrastEnhancement->setMinimumValue( min[0] );
488 mContrastEnhancement->setMaximumValue( max[0] );
QFlags< RasterRendererFlag > RasterRendererFlags
Flags which control behavior of raster renderers.
@ 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.
Settings for a color ramp legend node.
A legend node which renders a color ramp.
Handles contrast enhancement and clipping.
@ StretchToMinimumMaximum
Linear histogram.
@ StretchAndClipToMinimumMaximum
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
void readXml(const QDomElement &elem)
Gradient color ramp, which smoothly interpolates between two colors and also supports optional extra ...
Layer tree node points to a map layer.
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
Feedback object tailored for raster block reading.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
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.
QgsRasterRenderer(QgsRasterInterface *input=nullptr, const QString &type=QString())
Constructor for QgsRasterRenderer.
double mOpacity
Global alpha value (0-1).
int mAlphaBand
Read alpha value from band.
QgsRectangle mLastRectangleUsedByRefreshContrastEnhancementIfNeeded
To save computations and possible infinite cycle of notifications.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
std::unique_ptr< QgsRasterTransparency > mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses).
int bandCount() const override
Gets number of bands.
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
bool needsRefresh(const QgsRectangle &extent) const
Checks if the renderer needs to be refreshed according to extent.
virtual Q_DECL_DEPRECATED 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.
A container for the context for various read/write operations on objects.
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary labels with icons.
void setLegendSettings(QgsColorRampLegendNodeSettings *settings)
Sets the color ramp shader legend settings.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
const QgsContrastEnhancement * contrastEnhancement() const
Gradient gradient() const
void setContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Q_DECL_DEPRECATED 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.
bool setInputBand(int band) override
Attempts to set the input band for the renderer.
Q_DECL_DEPRECATED void setGrayBand(int band)
QgsSingleBandGrayRenderer(QgsRasterInterface *input, int grayBand)
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
const QgsColorRampLegendNodeSettings * legendSettings() const
Returns the color ramp shader legend settings.
QList< QPair< QString, QColor > > legendSymbologyItems() const override
Returns symbology items if provided by renderer.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
Q_DECL_DEPRECATED int grayBand() const
void setGradient(Gradient gradient)
int inputBand() const override
Returns the input band for the renderer, or -1 if no input band is available.
bool refresh(const QgsRectangle &extent, const QList< double > &min, const QList< double > &max, bool forceRefresh=false) override
Refreshes the renderer according to the min and max values associated with the extent.
QgsSingleBandGrayRenderer * clone() const override
Clone itself, create deep copy.
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
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 QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)