21 #include <QDomDocument> 22 #include <QDomElement> 29 , mGrayBand( grayBand )
30 , mGradient( BlackToWhite )
31 , mContrastEnhancement( nullptr )
41 if ( mContrastEnhancement )
55 int grayBand = elem.attribute( QStringLiteral(
"grayBand" ), QStringLiteral(
"-1" ) ).toInt();
59 if ( elem.attribute( QStringLiteral(
"gradient" ) ) == QLatin1String(
"WhiteToBlack" ) )
64 QDomElement contrastEnhancementElem = elem.firstChildElement( QStringLiteral(
"contrastEnhancement" ) );
65 if ( !contrastEnhancementElem.isNull() )
69 ce->
readXml( contrastEnhancementElem );
77 mContrastEnhancement.reset( ce );
83 QgsDebugMsgLevel( QStringLiteral(
"width = %1 height = %2" ).arg( width ).arg( height ), 4 );
85 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
88 return outputBlock.release();
91 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mGrayBand, extent, width, height, feedback ) );
92 if ( !inputBlock || inputBlock->isEmpty() )
95 return outputBlock.release();
98 std::shared_ptr< QgsRasterBlock > alphaBlock;
103 if ( !alphaBlock || alphaBlock->isEmpty() )
106 return outputBlock.release();
111 alphaBlock = inputBlock;
116 return outputBlock.release();
120 bool isNoData =
false;
123 double grayVal = inputBlock->valueAndNoData( i, isNoData );
127 outputBlock->setColor( i, myDefaultColor );
138 currentAlpha *= alphaBlock->value( i ) / 255.0;
141 if ( mContrastEnhancement )
143 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
145 outputBlock->setColor( i, myDefaultColor );
148 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
153 grayVal = 255 - grayVal;
158 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
162 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
166 return outputBlock.release();
171 if ( parentElem.isNull() )
176 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
179 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
184 gradient = QStringLiteral(
"BlackToWhite" );
188 gradient = QStringLiteral(
"WhiteToBlack" );
190 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ), gradient );
192 if ( mContrastEnhancement )
194 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
195 mContrastEnhancement->writeXml( doc, contrastElem );
196 rasterRendererElem.appendChild( contrastElem );
198 parentElem.appendChild( rasterRendererElem );
205 QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
206 QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
207 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
208 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
215 if ( mGrayBand != -1 )
217 bandList << mGrayBand;
228 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
229 if ( elements.size() == 0 )
233 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
238 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
239 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Opacity" ) );
240 if ( elements.size() != 0 )
242 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
246 elements = rasterSymbolizerElem.elementsByTagName( QStringLiteral(
"sld:Geometry" ) );
247 if ( elements.size() != 0 )
249 rasterSymbolizerElem.insertAfter( channelSelectionElem, elements.at( 0 ) );
253 rasterSymbolizerElem.insertBefore( channelSelectionElem, rasterSymbolizerElem.firstChild() );
258 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
259 channelSelectionElem.appendChild( channelElem );
262 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
263 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
grayBand() ) ) );
264 channelElem.appendChild( sourceChannelNameElem );
269 QDomElement contrastEnhancementElem = doc.createElement( QStringLiteral(
"sld:ContrastEnhancement" ) );
287 QDomNodeList elements = contrastEnhancementElem.elementsByTagName( QStringLiteral(
"sld:VendorOption" ) );
288 for (
int i = 0; i < elements.size(); ++i )
290 QDomElement vendorOption = elements.at( i ).toElement();
291 if ( vendorOption.attribute( QStringLiteral(
"name" ) ) != QStringLiteral(
"minValue" ) )
295 vendorOption.removeChild( vendorOption.firstChild() );
296 vendorOption.appendChild( doc.createTextNode( QString::number( myRasterBandStats.
minimumValue ) ) );
309 channelElem.appendChild( contrastEnhancementElem );
314 QList< QPair< QString, QColor > > classes;
318 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
319 rasterSymbolizerElem.appendChild( colorMapElem );
328 QList< QPair< QString, QColor > > colorMapping( classes );
334 QString lowValue = classes[0].first;
335 QColor lowColor = classes[0].second;
336 lowColor.setAlpha( 0 );
337 QString highValue = classes[1].first;
338 QColor highColor = classes[1].second;
339 highColor.setAlpha( 0 );
341 colorMapping.prepend( QPair< QString, QColor >( lowValue, lowColor ) );
342 colorMapping.append( QPair< QString, QColor >( highValue, highColor ) );
347 colorMapping[0].first = QStringLiteral(
"0" );
348 colorMapping[1].first = QStringLiteral(
"255" );
358 for (
auto it = colorMapping.constBegin(); it != colorMapping.constEnd() ; ++it )
361 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
362 colorMapElem.appendChild( lowColorMapEntryElem );
363 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
364 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
365 if ( it->second.alphaF() == 0.0 )
367 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
A rectangle specified with double values.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
virtual void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
QgsSingleBandGrayRenderer(QgsRasterInterface *input, int grayBand)
virtual QgsRectangle extent() const
Gets the extent of the interface.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
virtual QgsRasterInterface * input() const
Current input.
DataType
Raster data types.
const QgsContrastEnhancement * contrastEnhancement() const
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
QgsSingleBandGrayRenderer * clone() const override
Clone itself, create deep copy.
QMap< QString, QString > QgsStringMap
void toSld(QDomDocument &doc, QDomElement &element) const
Write ContrastEnhancement tags following SLD v1.0 specs SLD1.0 is limited to the parameters listed in...
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Gets symbology items if provided by renderer.
static const QRgb NODATA_COLOR
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
The RasterBandStats struct is a container for statistics about a single raster band.
#define QgsDebugMsgLevel(str, level)
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.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
void readXml(const QDomElement &elem)
Raster renderer pipe for single band gray.
void setGradient(Gradient gradient)
Gradient gradient() const
int mAlphaBand
Read alpha value from band.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Base class for processing filters like renderers, reprojector, resampler etc.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
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...
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
void setContrastEnhancement(QgsContrastEnhancement *ce)
Takes ownership.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props=QgsStringMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
double minimumValue
The minimum cell value in the raster band.
double mOpacity
Global alpha value (0-1)
Manipulates raster pixel values so that they enhanceContrast or clip into a specified numerical range...
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
QgsRasterInterface * mInput
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.