27#include <QDomDocument>
35 , mGrayBand( grayBand )
36 , mGradient( BlackToWhite )
37 , mContrastEnhancement( nullptr )
48 if ( mContrastEnhancement )
68 const int grayBand = elem.attribute( QStringLiteral(
"grayBand" ), QStringLiteral(
"-1" ) ).toInt();
72 if ( elem.attribute( QStringLiteral(
"gradient" ) ) == QLatin1String(
"WhiteToBlack" ) )
77 const QDomElement contrastEnhancementElem = elem.firstChildElement( QStringLiteral(
"contrastEnhancement" ) );
78 if ( !contrastEnhancementElem.isNull() )
82 ce->
readXml( contrastEnhancementElem );
86 auto legendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
95 mContrastEnhancement.reset( ce );
101 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
103 auto outputBlock = std::make_unique<QgsRasterBlock>();
106 return outputBlock.release();
109 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand,
extent, width, height, feedback ) );
110 if ( !inputBlock || inputBlock->isEmpty() )
113 return outputBlock.release();
116 std::shared_ptr< QgsRasterBlock > alphaBlock;
121 if ( !alphaBlock || alphaBlock->isEmpty() )
124 return outputBlock.release();
129 alphaBlock = inputBlock;
134 return outputBlock.release();
138 bool isNoData =
false;
141 double grayVal = inputBlock->valueAndNoData( i, isNoData );
145 outputBlock->setColor( i, myDefaultColor );
156 const double alpha = alphaBlock->value( i );
159 outputBlock->setColor( i, myDefaultColor );
164 currentAlpha *= alpha / 255.0;
168 if ( mContrastEnhancement )
170 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
172 outputBlock->setColor( i, myDefaultColor );
175 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
180 grayVal = 255 - grayVal;
185 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
189 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
193 return outputBlock.release();
213 else if ( band > 0 && band <= mInput->
bandCount() )
223 if ( parentElem.isNull() )
228 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
231 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
236 gradient = QStringLiteral(
"BlackToWhite" );
240 gradient = QStringLiteral(
"WhiteToBlack" );
242 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
244 if ( mContrastEnhancement )
246 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
247 mContrastEnhancement->writeXml( doc, contrastElem );
248 rasterRendererElem.appendChild( contrastElem );
251 if ( mLegendSettings )
254 parentElem.appendChild( rasterRendererElem );
259 QList<QPair<QString, QColor> > symbolItems;
262 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
263 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
264 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
265 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
272 QList<QgsLayerTreeModelLegendNode *> res;
276 if ( !name.isEmpty() )
281 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
282 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
285 mContrastEnhancement->minimumValue(),
286 mContrastEnhancement->maximumValue() );
294 if ( mGrayBand != -1 )
296 bandList << mGrayBand;
305 toSld( doc, element, context );
314 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
315 if ( elements.size() == 0 )
319 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
324 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
325 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
326 if ( elements.size() != 0 )
328 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
332 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
333 if ( elements.size() != 0 )
335 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
339 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
344 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
345 channelSelectionElem.appendChild( channelElem );
348 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
349 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( mGrayBand ) ) );
350 channelElem.appendChild( sourceChannelNameElem );
355 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
356 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
362 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
374 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
375 for (
int i = 0; i < vendorOptions.size(); ++i )
377 QDomElement vendorOption = vendorOptions.at( i ).toElement();
378 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
382 vendorOption.removeChild( vendorOption.firstChild() );
383 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
396 channelElem.appendChild( contrastEnhancementElem );
404 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
405 rasterSymbolizerElem.appendChild( colorMapElem );
414 QList< QPair< QString, QColor > > colorMapping( classes );
420 const QString lowValue = classes[0].first;
421 QColor lowColor = classes[0].second;
422 lowColor.setAlpha( 0 );
423 const QString highValue = classes[1].first;
424 QColor highColor = classes[1].second;
425 highColor.setAlpha( 0 );
427 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
428 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
433 colorMapping[0].first = QStringLiteral(
"0" );
434 colorMapping[1].first = QStringLiteral(
"255" );
444 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
447 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
448 colorMapElem.appendChild( lowColorMapEntryElem );
449 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
450 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
451 if ( it->second.alphaF() == 0.0 )
453 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
461 return mLegendSettings.get();
466 if ( settings == mLegendSettings.get() )
468 mLegendSettings.reset( settings );
478 bool refreshed =
false;
480 min.size() >= 1 && max.size() >= 1 )
483 mContrastEnhancement->setMinimumValue( min[0] );
484 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.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads settings from an XML element.
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.
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.
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, 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.
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.
Raster renderer pipe for single band gray.
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)