24 #include <QDomDocument> 25 #include <QDomElement> 33 , mClassData( classes )
41 if ( mSourceColorRamp )
55 int bandNumber = elem.attribute( QStringLiteral(
"band" ), QStringLiteral(
"-1" ) ).toInt();
58 QDomElement paletteElem = elem.firstChildElement( QStringLiteral(
"colorPalette" ) );
59 if ( !paletteElem.isNull() )
61 QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral(
"paletteEntry" ) );
63 QDomElement entryElem;
66 for (
int i = 0; i < paletteEntries.size(); ++i )
70 entryElem = paletteEntries.at( i ).toElement();
71 value =
static_cast<int>( entryElem.attribute( QStringLiteral(
"value" ), QStringLiteral(
"0" ) ).toDouble() );
73 color = QColor( entryElem.attribute( QStringLiteral(
"color" ), QStringLiteral(
"#000000" ) ) );
74 color.setAlpha( entryElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt() );
75 label = entryElem.attribute( QStringLiteral(
"label" ) );
76 classData <<
Class( value, color, label );
84 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral(
"colorramp" ) );
85 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
100 Q_FOREACH (
const Class &
c, mClassData )
102 if ( c.
value == idx )
111 ClassData::iterator cIt = mClassData.begin();
112 for ( ; cIt != mClassData.end(); ++cIt )
114 if ( cIt->value == idx )
124 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
125 if ( !
mInput || mClassData.isEmpty() )
127 return outputBlock.release();
130 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mBand, extent, width, height, feedback ) );
132 if ( !inputBlock || inputBlock->isEmpty() )
134 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
135 return outputBlock.release();
143 std::shared_ptr< QgsRasterBlock > alphaBlock;
148 if ( !alphaBlock || alphaBlock->isEmpty() )
150 return outputBlock.release();
155 alphaBlock = inputBlock;
160 return outputBlock.release();
167 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
170 for (
qgssize i = 0; i < rasterSize; ++i )
172 if ( inputBlock->isNoData( i ) )
174 outputData[i] = myDefaultColor;
177 int val = ( int ) inputBlock->value( i );
178 if ( !mColors.contains( val ) )
180 outputData[i] = myDefaultColor;
184 if ( !hasTransparency )
186 outputData[i] = mColors.value( val );
197 currentOpacity *= alphaBlock->value( i ) / 255.0;
200 QRgb
c = mColors.value( val );
201 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
205 return outputBlock.release();
210 if ( parentElem.isNull() )
215 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
218 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
219 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
220 ClassData::const_iterator it = mClassData.constBegin();
221 for ( ; it != mClassData.constEnd(); ++it )
223 QColor color = it->color;
224 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
225 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
226 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
227 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
228 if ( !it->label.isEmpty() )
230 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
232 colorPaletteElem.appendChild( colorElem );
234 rasterRendererElem.appendChild( colorPaletteElem );
237 if ( mSourceColorRamp )
240 rasterRendererElem.appendChild( colorRampElem );
243 parentElem.appendChild( rasterRendererElem );
254 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
255 if ( elements.size() == 0 )
259 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
262 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
263 rasterSymbolizerElem.appendChild( channelSelectionElem );
266 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
267 channelSelectionElem.appendChild( channelElem );
270 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
271 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
272 channelElem.appendChild( sourceChannelNameElem );
275 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
276 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
277 if ( this->
classes().size() >= 255 )
278 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
279 rasterSymbolizerElem.appendChild( colorMapElem );
283 QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
284 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
285 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
287 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
288 colorMapElem.appendChild( colorMapEntryElem );
291 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
292 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
293 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
294 if ( classDataIt->color.alphaF() != 1.0 )
296 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
303 ClassData::const_iterator it = mClassData.constBegin();
304 for ( ; it != mClassData.constEnd(); ++it )
306 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
307 symbolItems << qMakePair( lab, it->color );
323 mSourceColorRamp.reset( ramp );
328 return mSourceColorRamp.get();
333 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
335 for ( ; colorIt != table.constEnd(); ++colorIt )
337 int idx = ( int )( colorIt->value );
347 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
349 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
350 Q_FOREACH (
const QString &part, parts )
352 QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
354 switch ( lineParts.count() )
358 int value = lineParts.at( 0 ).toInt( &ok );
362 classes <<
Class( value );
368 int value = lineParts.at( 0 ).toInt( &ok );
372 QColor
c( lineParts.at( 1 ) );
374 classes <<
Class( value,
c );
380 if ( lineParts.count() < 4 )
383 int value = lineParts.at( 0 ).toInt( &ok );
388 double r = lineParts.at( 1 ).toDouble( &rOk );
390 double g = lineParts.at( 2 ).toDouble( &gOk );
392 double b = lineParts.at( 3 ).toDouble( &bOk );
395 if ( rOk && gOk && bOk )
397 c = QColor( r, g, b );
400 if ( lineParts.count() >= 5 )
402 double alpha = lineParts.at( 4 ).toDouble( &ok );
408 if ( lineParts.count() > 5 )
410 label = lineParts.mid( 5 ).join(
' ' );
413 classes <<
Class( value, c, label );
424 QFile inputFile( path );
426 if ( inputFile.open( QIODevice::ReadOnly ) )
428 QTextStream in( &inputFile );
429 input = in.readAll();
440 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool 442 return a.
value < b.value;
445 Q_FOREACH (
const Class &
c, cd )
447 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg( c.
value ).arg( c.
color.red() )
450 return out.join(
'\n' );
466 int bins = std::ceil( max - min ) + 1;
478 double currentValue = histogram.
minimum;
479 double presentValues = 0;
480 for (
int idx = 0; idx < histogram.
binCount; ++idx )
485 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
488 currentValue += interval;
500 randomRamp->setTotalColorCount( data.count() );
503 if ( presentValues > 1 )
506 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
507 for ( ; cIt != data.end(); ++cIt )
509 cIt->color = ramp->
color( i / presentValues );
516 void QgsPalettedRasterRenderer::updateArrays()
520 ClassData::const_iterator it = mClassData.constBegin();
521 for ( ; it != mClassData.constEnd(); ++it )
523 mColors[it->value] = qPremultiply( it->color.rgba() );
void setSourceColorRamp(QgsColorRamp *ramp)
Set the source color ramp.
bool isCanceled() const
Tells whether the operation has been canceled already.
static QString classDataToString(const QgsPalettedRasterRenderer::ClassData &classes)
Converts classes to a string representation, using the .clr/gdal color table file format...
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
QString label(int idx) const
Returns optional category label.
QgsPalettedRasterRenderer(QgsRasterInterface *input, int bandNumber, const ClassData &classes)
Constructor for QgsPalettedRasterRenderer.
QColor color
Color to render value.
Renderer for paletted raster images.
QString label
Label for value.
Abstract base class for color ramps.
double minimum
The minimum histogram value.
Properties of a single value class.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
void setLabel(int idx, const QString &label)
Set category label.
double maximumValue
The maximum cell value in the raster band.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
virtual QgsRasterInterface * input() const
Current input.
virtual QgsRasterHistogram histogram(int bandNo, int binCount=0, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false, QgsRasterBlockFeedback *feedback=nullptr)
Returns a band histogram.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
QMap< QString, QString > QgsStringMap
bool usesTransparency() const
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.
int band() const
Returns the raster band used for rendering the raster.
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.
ClassData classes() const
Returns a map of value to classes (colors) used by the renderer.
QList< QgsPalettedRasterRenderer::Class > ClassData
Map of value to class properties.
static QgsPalettedRasterRenderer::ClassData classDataFromString(const QString &string)
Converts a string containing a color table or class data to to paletted renderer class data...
void copyCommonProperties(const QgsRasterRenderer *other, bool copyMinMaxOrigin=true)
Copies common properties like opacity / transparency data from other renderer.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
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...
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
Totally random color ramp.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
double maximum
The maximum histogram value.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
QgsPalettedRasterRenderer * clone() const override
Clone itself, create deep copy.
static QgsPalettedRasterRenderer::ClassData classDataFromFile(const QString &path)
Opens a color table file and returns corresponding paletted renderer class data.
static QgsPalettedRasterRenderer::ClassData classDataFromRaster(QgsRasterInterface *raster, int bandNumber, QgsColorRamp *ramp=nullptr, QgsRasterBlockFeedback *feedback=nullptr)
Generates class data from a raster, for the specified bandNumber.
virtual QgsRectangle extent() const
Gets the extent of the interface.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Gets symbology items if provided by renderer.
QgsColorRamp * sourceColorRamp() const
Gets the source color ramp.
double minimumValue
The minimum cell value in the raster band.
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.
The QgsRasterHistogram is a container for histogram of a single raster band.
int binCount
Number of bins (intervals,buckets) in histogram.
double mOpacity
Global alpha value (0-1)
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.
static QgsPalettedRasterRenderer::ClassData colorTableToClassData(const QList< QgsColorRampShader::ColorRampItem > &table)
Converts a raster color table to paletted renderer class data.
Raster renderer pipe that applies colors to a raster.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.