27 #include <QDomDocument>
28 #include <QDomElement>
35 , mGrayBand( grayBand )
36 , mGradient( BlackToWhite )
37 , mContrastEnhancement( nullptr )
48 if ( mContrastEnhancement )
63 const int grayBand = elem.attribute( QStringLiteral(
"grayBand" ), QStringLiteral(
"-1" ) ).toInt();
67 if ( elem.attribute( QStringLiteral(
"gradient" ) ) == QLatin1String(
"WhiteToBlack" ) )
72 const QDomElement contrastEnhancementElem = elem.firstChildElement( QStringLiteral(
"contrastEnhancement" ) );
73 if ( !contrastEnhancementElem.isNull() )
77 ce->
readXml( contrastEnhancementElem );
81 std::unique_ptr< QgsColorRampLegendNodeSettings >
legendSettings = std::make_unique< QgsColorRampLegendNodeSettings >();
90 mContrastEnhancement.reset( ce );
96 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
98 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
101 return outputBlock.release();
104 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand,
extent, width, height, feedback ) );
105 if ( !inputBlock || inputBlock->isEmpty() )
107 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
108 return outputBlock.release();
111 std::shared_ptr< QgsRasterBlock > alphaBlock;
116 if ( !alphaBlock || alphaBlock->isEmpty() )
119 return outputBlock.release();
124 alphaBlock = inputBlock;
129 return outputBlock.release();
133 bool isNoData =
false;
136 double grayVal = inputBlock->valueAndNoData( i, isNoData );
140 outputBlock->setColor( i, myDefaultColor );
151 currentAlpha *= alphaBlock->value( i ) / 255.0;
154 if ( mContrastEnhancement )
156 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
158 outputBlock->setColor( i, myDefaultColor );
161 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
166 grayVal = 255 - grayVal;
171 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
175 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
179 return outputBlock.release();
184 if ( parentElem.isNull() )
189 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
192 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
197 gradient = QStringLiteral(
"BlackToWhite" );
201 gradient = QStringLiteral(
"WhiteToBlack" );
203 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
205 if ( mContrastEnhancement )
207 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
208 mContrastEnhancement->writeXml( doc, contrastElem );
209 rasterRendererElem.appendChild( contrastElem );
212 if ( mLegendSettings )
215 parentElem.appendChild( rasterRendererElem );
220 QList<QPair<QString, QColor> > symbolItems;
223 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
224 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
225 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
226 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
233 QList<QgsLayerTreeModelLegendNode *> res;
237 if ( !name.isEmpty() )
242 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
243 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
246 mContrastEnhancement->minimumValue(),
247 mContrastEnhancement->maximumValue() );
255 if ( mGrayBand != -1 )
257 bandList << mGrayBand;
268 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
269 if ( elements.size() == 0 )
273 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
278 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
279 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
280 if ( elements.size() != 0 )
282 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
286 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
287 if ( elements.size() != 0 )
289 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
293 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
298 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
299 channelSelectionElem.appendChild( channelElem );
302 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
303 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
grayBand() ) ) );
304 channelElem.appendChild( sourceChannelNameElem );
309 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
310 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
316 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
328 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
329 for (
int i = 0; i < vendorOptions.size(); ++i )
331 QDomElement vendorOption = vendorOptions.at( i ).toElement();
332 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
336 vendorOption.removeChild( vendorOption.firstChild() );
337 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
350 channelElem.appendChild( contrastEnhancementElem );
358 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
359 rasterSymbolizerElem.appendChild( colorMapElem );
368 QList< QPair< QString, QColor > > colorMapping( classes );
374 const QString lowValue = classes[0].first;
375 QColor lowColor = classes[0].second;
376 lowColor.setAlpha( 0 );
377 const QString highValue = classes[1].first;
378 QColor highColor = classes[1].second;
379 highColor.setAlpha( 0 );
381 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
382 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
387 colorMapping[0].first = QStringLiteral(
"0" );
388 colorMapping[1].first = QStringLiteral(
"255" );
398 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
401 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
402 colorMapElem.appendChild( lowColorMapEntryElem );
403 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
404 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
405 if ( it->second.alphaF() == 0.0 )
407 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
414 return mLegendSettings.get();
419 if ( settings == mLegendSettings.get() )
421 mLegendSettings.reset( settings );
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 QgsRasterInterface * input() const
Current input.
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.
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.
Gradient gradient() const
void setContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
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.
const QgsContrastEnhancement * contrastEnhancement() const
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)