26#include <QDomDocument>
34 , mGrayBand( grayBand )
35 , mGradient( BlackToWhite )
36 , mContrastEnhancement( nullptr )
47 if ( mContrastEnhancement )
67 const int grayBand = elem.attribute( QStringLiteral(
"grayBand" ), QStringLiteral(
"-1" ) ).toInt();
71 if ( elem.attribute( QStringLiteral(
"gradient" ) ) == QLatin1String(
"WhiteToBlack" ) )
76 const QDomElement contrastEnhancementElem = elem.firstChildElement( QStringLiteral(
"contrastEnhancement" ) );
77 if ( !contrastEnhancementElem.isNull() )
81 ce->
readXml( contrastEnhancementElem );
85 std::unique_ptr< QgsColorRampLegendNodeSettings >
legendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
94 mContrastEnhancement.reset( ce );
100 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
102 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
105 return outputBlock.release();
108 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand,
extent, width, height, feedback ) );
109 if ( !inputBlock || inputBlock->isEmpty() )
112 return outputBlock.release();
115 std::shared_ptr< QgsRasterBlock > alphaBlock;
120 if ( !alphaBlock || alphaBlock->isEmpty() )
123 return outputBlock.release();
128 alphaBlock = inputBlock;
133 return outputBlock.release();
137 bool isNoData =
false;
140 double grayVal = inputBlock->valueAndNoData( i, isNoData );
144 outputBlock->setColor( i, myDefaultColor );
155 const double alpha = alphaBlock->value( i );
158 outputBlock->setColor( i, myDefaultColor );
163 currentAlpha *= alpha / 255.0;
167 if ( mContrastEnhancement )
169 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
171 outputBlock->setColor( i, myDefaultColor );
174 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
179 grayVal = 255 - grayVal;
184 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
188 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
192 return outputBlock.release();
212 else if ( band > 0 && band <= mInput->
bandCount() )
222 if ( parentElem.isNull() )
227 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
230 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
235 gradient = QStringLiteral(
"BlackToWhite" );
239 gradient = QStringLiteral(
"WhiteToBlack" );
241 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
243 if ( mContrastEnhancement )
245 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
246 mContrastEnhancement->writeXml( doc, contrastElem );
247 rasterRendererElem.appendChild( contrastElem );
250 if ( mLegendSettings )
253 parentElem.appendChild( rasterRendererElem );
258 QList<QPair<QString, QColor> > symbolItems;
261 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
262 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
263 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
264 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
271 QList<QgsLayerTreeModelLegendNode *> res;
275 if ( !name.isEmpty() )
280 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
281 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
284 mContrastEnhancement->minimumValue(),
285 mContrastEnhancement->maximumValue() );
293 if ( mGrayBand != -1 )
295 bandList << mGrayBand;
306 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
307 if ( elements.size() == 0 )
311 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
316 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
317 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
318 if ( elements.size() != 0 )
320 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
324 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
325 if ( elements.size() != 0 )
327 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
331 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
336 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
337 channelSelectionElem.appendChild( channelElem );
340 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
341 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number( mGrayBand ) ) );
342 channelElem.appendChild( sourceChannelNameElem );
347 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
348 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
354 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
366 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
367 for (
int i = 0; i < vendorOptions.size(); ++i )
369 QDomElement vendorOption = vendorOptions.at( i ).toElement();
370 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
374 vendorOption.removeChild( vendorOption.firstChild() );
375 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
388 channelElem.appendChild( contrastEnhancementElem );
396 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
397 rasterSymbolizerElem.appendChild( colorMapElem );
406 QList< QPair< QString, QColor > > colorMapping( classes );
412 const QString lowValue = classes[0].first;
413 QColor lowColor = classes[0].second;
414 lowColor.setAlpha( 0 );
415 const QString highValue = classes[1].first;
416 QColor highColor = classes[1].second;
417 highColor.setAlpha( 0 );
419 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
420 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
425 colorMapping[0].first = QStringLiteral(
"0" );
426 colorMapping[1].first = QStringLiteral(
"255" );
436 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
439 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
440 colorMapElem.appendChild( lowColorMapEntryElem );
441 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
442 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
443 if ( it->second.alphaF() == 0.0 )
445 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
452 return mLegendSettings.get();
457 if ( settings == mLegendSettings.get() )
459 mLegendSettings.reset( settings );
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.
Manipulates raster or point cloud pixel values so that they enhanceContrast or clip into a specified ...
@ 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.
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)
int bandCount() const override
Gets number of bands.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
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.
double opacityForValue(double value) const
Returns the opacity (as a value from 0 to 1) for a single value pixel.
The class is used as a container of context for various read/write operations on other objects.
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary label with icon.
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)
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.
QgsSingleBandGrayRenderer * clone() const override
Clone itself, create deep copy.
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)