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();
122 if ( inputBlock->isNoData( i ) )
124 outputBlock->setColor( i, myDefaultColor );
127 double grayVal = inputBlock->value( i );
136 currentAlpha *= alphaBlock->value( i ) / 255.0;
139 if ( mContrastEnhancement )
141 if ( !mContrastEnhancement->isValueInDisplayableRange( grayVal ) )
143 outputBlock->setColor( i, myDefaultColor );
146 grayVal = mContrastEnhancement->enhanceContrast( grayVal );
151 grayVal = 255 - grayVal;
156 outputBlock->setColor( i, qRgba( grayVal, grayVal, grayVal, 255 ) );
160 outputBlock->setColor( i, qRgba( currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * grayVal, currentAlpha * 255 ) );
164 return outputBlock.release();
169 if ( parentElem.isNull() )
174 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
177 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), mGrayBand );
182 gradient = QStringLiteral(
"BlackToWhite" );
186 gradient = QStringLiteral(
"WhiteToBlack" );
188 rasterRendererElem.setAttribute( QStringLiteral(
"gradient" ), gradient );
190 if ( mContrastEnhancement )
192 QDomElement contrastElem = doc.createElement( QStringLiteral(
"contrastEnhancement" ) );
193 mContrastEnhancement->writeXml( doc, contrastElem );
194 rasterRendererElem.appendChild( contrastElem );
196 parentElem.appendChild( rasterRendererElem );
203 QColor minColor = ( mGradient ==
BlackToWhite ) ? Qt::black : Qt::white;
204 QColor maxColor = ( mGradient ==
BlackToWhite ) ? Qt::white : Qt::black;
205 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->minimumValue() ), minColor ) );
206 symbolItems.push_back( qMakePair( QString::number( mContrastEnhancement->maximumValue() ), maxColor ) );
213 if ( mGrayBand != -1 )
215 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 QList< QPair< QString, QColor > >::ConstIterator it;
359 for ( it = colorMapping.begin(); it != colorMapping.constEnd() ; ++it )
362 QDomElement lowColorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
363 colorMapElem.appendChild( lowColorMapEntryElem );
364 lowColorMapEntryElem.setAttribute( QStringLiteral(
"color" ), it->second.name() );
365 lowColorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), it->first );
366 if ( it->second.alphaF() == 0.0 )
368 lowColorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( it->second.alpha() ) );
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
QgsSingleBandGrayRenderer(QgsRasterInterface *input, int grayBand)
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)
const QgsContrastEnhancement * contrastEnhancement() const
DataType
Raster data types.
virtual QgsRasterInterface * input() const
Current input.
Gradient gradient() 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
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.
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.
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 toSld(QDomDocument &doc, QDomElement &element) const
Write ContrastEnhancement tags following SLD v1.0 specs SLD1.0 is limited to the parameters listed in...
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)
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.
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.
virtual QgsRectangle extent() const
Gets the extent of the interface.
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
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
Feedback object tailored for raster block reading.
Raster renderer pipe that applies colors to a raster.