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 std::unique_ptr< QgsColorRampLegendNodeSettings >
legendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
95 mContrastEnhancement.reset( ce );
101 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
103 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
106 return outputBlock.release();
109 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand,
extent, width, height, feedback ) );
110 if ( !inputBlock || inputBlock->isEmpty() )
112 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
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();
198 if ( parentElem.isNull() )
203 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
206 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
211 gradient = QStringLiteral(
"BlackToWhite" );
215 gradient = QStringLiteral(
"WhiteToBlack" );
217 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
219 if ( mContrastEnhancement )
221 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
222 mContrastEnhancement->writeXml( doc, contrastElem );
223 rasterRendererElem.appendChild( contrastElem );
226 if ( mLegendSettings )
229 parentElem.appendChild( rasterRendererElem );
234 QList<QPair<QString, QColor> > symbolItems;
237 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
238 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
239 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
240 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
247 QList<QgsLayerTreeModelLegendNode *> res;
251 if ( !name.isEmpty() )
256 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
257 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
260 mContrastEnhancement->minimumValue(),
261 mContrastEnhancement->maximumValue() );
269 if ( mGrayBand != -1 )
271 bandList << mGrayBand;
282 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
283 if ( elements.size() == 0 )
287 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
292 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
293 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
294 if ( elements.size() != 0 )
296 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
300 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
301 if ( elements.size() != 0 )
303 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
307 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
312 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
313 channelSelectionElem.appendChild( channelElem );
316 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
317 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
grayBand() ) ) );
318 channelElem.appendChild( sourceChannelNameElem );
323 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
324 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
330 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
342 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
343 for (
int i = 0; i < vendorOptions.size(); ++i )
345 QDomElement vendorOption = vendorOptions.at( i ).toElement();
346 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
350 vendorOption.removeChild( vendorOption.firstChild() );
351 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
364 channelElem.appendChild( contrastEnhancementElem );
372 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
373 rasterSymbolizerElem.appendChild( colorMapElem );
382 QList< QPair< QString, QColor > > colorMapping( classes );
388 const QString lowValue = classes[0].first;
389 QColor lowColor = classes[0].second;
390 lowColor.setAlpha( 0 );
391 const QString highValue = classes[1].first;
392 QColor highColor = classes[1].second;
393 highColor.setAlpha( 0 );
395 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
396 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
401 colorMapping[0].first = QStringLiteral(
"0" );
402 colorMapping[1].first = QStringLiteral(
"255" );
412 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
415 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
416 colorMapElem.appendChild( lowColorMapEntryElem );
417 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
418 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
419 if ( it->second.alphaF() == 0.0 )
421 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
428 return mLegendSettings.get();
433 if ( settings == mLegendSettings.get() )
435 mLegendSettings.reset( settings );
@ 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.
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.
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)
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.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value 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.
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.
void setGradient(Gradient gradient)
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)