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 currentAlpha *= alphaBlock->value( i ) / 255.0;
159 if ( mContrastEnhancement )
161 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
163 outputBlock->setColor( i, myDefaultColor );
166 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
171 grayVal = 255 - grayVal;
176 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
180 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
184 return outputBlock.release();
189 if ( parentElem.isNull() )
194 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
197 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
202 gradient = QStringLiteral(
"BlackToWhite" );
206 gradient = QStringLiteral(
"WhiteToBlack" );
208 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
210 if ( mContrastEnhancement )
212 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
213 mContrastEnhancement->writeXml( doc, contrastElem );
214 rasterRendererElem.appendChild( contrastElem );
217 if ( mLegendSettings )
220 parentElem.appendChild( rasterRendererElem );
225 QList<QPair<QString, QColor> > symbolItems;
228 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
229 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
230 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
231 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
238 QList<QgsLayerTreeModelLegendNode *> res;
242 if ( !name.isEmpty() )
247 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
248 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
251 mContrastEnhancement->minimumValue(),
252 mContrastEnhancement->maximumValue() );
260 if ( mGrayBand != -1 )
262 bandList << mGrayBand;
273 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
274 if ( elements.size() == 0 )
278 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
283 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
284 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
285 if ( elements.size() != 0 )
287 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
291 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
292 if ( elements.size() != 0 )
294 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
298 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
303 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
304 channelSelectionElem.appendChild( channelElem );
307 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
308 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
grayBand() ) ) );
309 channelElem.appendChild( sourceChannelNameElem );
314 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
315 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
321 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
333 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
334 for (
int i = 0; i < vendorOptions.size(); ++i )
336 QDomElement vendorOption = vendorOptions.at( i ).toElement();
337 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
341 vendorOption.removeChild( vendorOption.firstChild() );
342 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
355 channelElem.appendChild( contrastEnhancementElem );
363 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
364 rasterSymbolizerElem.appendChild( colorMapElem );
373 QList< QPair< QString, QColor > > colorMapping( classes );
379 const QString lowValue = classes[0].first;
380 QColor lowColor = classes[0].second;
381 lowColor.setAlpha( 0 );
382 const QString highValue = classes[1].first;
383 QColor highColor = classes[1].second;
384 highColor.setAlpha( 0 );
386 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
387 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
392 colorMapping[0].first = QStringLiteral(
"0" );
393 colorMapping[1].first = QStringLiteral(
"255" );
403 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
406 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
407 colorMapElem.appendChild( lowColorMapEntryElem );
408 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
409 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
410 if ( it->second.alphaF() == 0.0 )
412 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
419 return mLegendSettings.get();
424 if ( settings == mLegendSettings.get() )
426 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)