24 #include <QDomDocument>
25 #include <QDomElement>
32 , mGrayBand( grayBand )
33 , mGradient( BlackToWhite )
34 , mContrastEnhancement( nullptr )
45 if ( mContrastEnhancement )
60 int grayBand = elem.attribute( QStringLiteral(
"grayBand" ), QStringLiteral(
"-1" ) ).toInt();
64 if ( elem.attribute( QStringLiteral(
"gradient" ) ) == QLatin1String(
"WhiteToBlack" ) )
69 QDomElement contrastEnhancementElem = elem.firstChildElement( QStringLiteral(
"contrastEnhancement" ) );
70 if ( !contrastEnhancementElem.isNull() )
74 ce->
readXml( contrastEnhancementElem );
78 std::unique_ptr< QgsColorRampLegendNodeSettings >
legendSettings = qgis::make_unique< QgsColorRampLegendNodeSettings >();
87 mContrastEnhancement.reset( ce );
93 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
95 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
98 return outputBlock.release();
101 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand,
extent, width, height, feedback ) );
102 if ( !inputBlock || inputBlock->isEmpty() )
104 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
105 return outputBlock.release();
108 std::shared_ptr< QgsRasterBlock > alphaBlock;
113 if ( !alphaBlock || alphaBlock->isEmpty() )
116 return outputBlock.release();
121 alphaBlock = inputBlock;
126 return outputBlock.release();
130 bool isNoData =
false;
133 double grayVal = inputBlock->valueAndNoData( i, isNoData );
137 outputBlock->setColor( i, myDefaultColor );
148 currentAlpha *= alphaBlock->value( i ) / 255.0;
151 if ( mContrastEnhancement )
153 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
155 outputBlock->setColor( i, myDefaultColor );
158 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
163 grayVal = 255 - grayVal;
168 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
172 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
176 return outputBlock.release();
181 if ( parentElem.isNull() )
186 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
189 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
194 gradient = QStringLiteral(
"BlackToWhite" );
198 gradient = QStringLiteral(
"WhiteToBlack" );
200 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ),
gradient );
202 if ( mContrastEnhancement )
204 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
205 mContrastEnhancement->writeXml( doc, contrastElem );
206 rasterRendererElem.appendChild( contrastElem );
209 if ( mLegendSettings )
212 parentElem.appendChild( rasterRendererElem );
217 QList<QPair<QString, QColor> > symbolItems;
220 QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
221 QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
222 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
223 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
230 QList<QgsLayerTreeModelLegendNode *> res;
234 if ( !name.isEmpty() )
239 const QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
240 const QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
243 mContrastEnhancement->minimumValue(),
244 mContrastEnhancement->maximumValue() );
252 if ( mGrayBand != -1 )
254 bandList << mGrayBand;
265 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
266 if ( elements.size() == 0 )
270 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
275 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
276 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
277 if ( elements.size() != 0 )
279 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
283 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
284 if ( elements.size() != 0 )
286 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
290 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
295 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
296 channelSelectionElem.appendChild( channelElem );
299 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
300 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
grayBand() ) ) );
301 channelElem.appendChild( sourceChannelNameElem );
306 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
307 lContrastEnhancement->toSld( doc, contrastEnhancementElem );
313 switch ( lContrastEnhancement->contrastEnhancementAlgorithm() )
325 const QDomNodeList vendorOptions = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
326 for (
int i = 0; i < vendorOptions.size(); ++i )
328 QDomElement vendorOption = vendorOptions.at( i ).toElement();
329 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QLatin1String(
"minValue" ) )
333 vendorOption.removeChild( vendorOption.firstChild() );
334 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
347 channelElem.appendChild( contrastEnhancementElem );
355 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
356 rasterSymbolizerElem.appendChild( colorMapElem );
365 QList< QPair< QString, QColor > > colorMapping( classes );
371 QString lowValue = classes[0].first;
372 QColor lowColor = classes[0].second;
373 lowColor.setAlpha( 0 );
374 QString highValue = classes[1].first;
375 QColor highColor = classes[1].second;
376 highColor.setAlpha( 0 );
378 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
379 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
384 colorMapping[0].first = QStringLiteral(
"0" );
385 colorMapping[1].first = QStringLiteral(
"255" );
395 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
398 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
399 colorMapElem.appendChild( lowColorMapEntryElem );
400 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
401 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
402 if ( it->second.alphaF() == 0.0 )
404 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
411 return mLegendSettings.get();
416 if ( settings == mLegendSettings.get() )
418 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)