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( bandNo, 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 bool isNoData =
false;
171 for (
qgssize i = 0; i < rasterSize; ++i )
173 const double value = inputBlock->valueAndNoData( i, isNoData );
176 outputData[i] = myDefaultColor;
179 int val =
static_cast< int >( value );
180 if ( !mColors.contains( val ) )
182 outputData[i] = myDefaultColor;
186 if ( !hasTransparency )
188 outputData[i] = mColors.value( val );
199 currentOpacity *= alphaBlock->value( i ) / 255.0;
202 QRgb
c = mColors.value( val );
203 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
207 return outputBlock.release();
212 if ( parentElem.isNull() )
217 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
220 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
221 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
222 ClassData::const_iterator it = mClassData.constBegin();
223 for ( ; it != mClassData.constEnd(); ++it )
225 QColor color = it->color;
226 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
227 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
228 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
229 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
230 if ( !it->label.isEmpty() )
232 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
234 colorPaletteElem.appendChild( colorElem );
236 rasterRendererElem.appendChild( colorPaletteElem );
239 if ( mSourceColorRamp )
242 rasterRendererElem.appendChild( colorRampElem );
245 parentElem.appendChild( rasterRendererElem );
256 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
257 if ( elements.size() == 0 )
261 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
264 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
265 rasterSymbolizerElem.appendChild( channelSelectionElem );
268 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
269 channelSelectionElem.appendChild( channelElem );
272 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
273 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
274 channelElem.appendChild( sourceChannelNameElem );
277 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
278 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
279 if ( this->
classes().size() >= 255 )
280 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
281 rasterSymbolizerElem.appendChild( colorMapElem );
285 QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
286 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
287 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
289 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
290 colorMapElem.appendChild( colorMapEntryElem );
293 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
294 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
295 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
296 if ( classDataIt->color.alphaF() != 1.0 )
298 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
305 ClassData::const_iterator it = mClassData.constBegin();
306 for ( ; it != mClassData.constEnd(); ++it )
308 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
309 symbolItems << qMakePair( lab, it->color );
325 mSourceColorRamp.reset( ramp );
330 return mSourceColorRamp.get();
335 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
337 for ( ; colorIt != table.constEnd(); ++colorIt )
339 int idx = ( int )( colorIt->value );
349 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
351 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
352 Q_FOREACH (
const QString &part, parts )
354 QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
356 switch ( lineParts.count() )
360 int value = lineParts.at( 0 ).toInt( &ok );
364 classes <<
Class( value );
370 int value = lineParts.at( 0 ).toInt( &ok );
374 QColor
c( lineParts.at( 1 ) );
376 classes <<
Class( value,
c );
382 if ( lineParts.count() < 4 )
385 int value = lineParts.at( 0 ).toInt( &ok );
390 double r = lineParts.at( 1 ).toDouble( &rOk );
392 double g = lineParts.at( 2 ).toDouble( &gOk );
394 double b = lineParts.at( 3 ).toDouble( &bOk );
397 if ( rOk && gOk && bOk )
399 c = QColor( r, g, b );
402 if ( lineParts.count() >= 5 )
404 double alpha = lineParts.at( 4 ).toDouble( &ok );
410 if ( lineParts.count() > 5 )
412 label = lineParts.mid( 5 ).join(
' ' );
415 classes <<
Class( value, c, label );
426 QFile inputFile( path );
428 if ( inputFile.open( QIODevice::ReadOnly ) )
430 QTextStream in( &inputFile );
431 input = in.readAll();
442 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool 444 return a.
value < b.value;
447 Q_FOREACH (
const Class &
c, cd )
449 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg( c.
value ).arg( c.
color.red() )
452 return out.join(
'\n' );
468 int bins = std::ceil( max - min ) + 1;
480 double currentValue = histogram.
minimum;
481 double presentValues = 0;
482 for (
int idx = 0; idx < histogram.
binCount; ++idx )
487 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
490 currentValue += interval;
502 randomRamp->setTotalColorCount( data.count() );
505 if ( presentValues > 1 )
508 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
509 for ( ; cIt != data.end(); ++cIt )
511 cIt->color = ramp->
color( i / presentValues );
518 void QgsPalettedRasterRenderer::updateArrays()
522 ClassData::const_iterator it = mClassData.constBegin();
523 for ( ; it != mClassData.constEnd(); ++it )
525 mColors[it->value] = qPremultiply( it->color.rgba() );
void setSourceColorRamp(QgsColorRamp *ramp)
Set the source color ramp.
static QString classDataToString(const QgsPalettedRasterRenderer::ClassData &classes)
Converts classes to a string representation, using the .clr/gdal color table file format...
A rectangle specified with double values.
QgsPalettedRasterRenderer(QgsRasterInterface *input, int bandNumber, const ClassData &classes)
Constructor for QgsPalettedRasterRenderer.
QColor color
Color to render value.
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.
Renderer for paletted raster images.
virtual QgsRectangle extent() const
Gets the extent of the interface.
QString label
Label for value.
Abstract base class for color ramps.
double minimum
The minimum histogram value.
virtual QgsRasterInterface * input() const
Current input.
ClassData classes() const
Returns a map of value to classes (colors) used by the renderer.
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 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
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.
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.
QList< QgsPalettedRasterRenderer::Class > ClassData
Map of value to class properties.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses) ...
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.
bool usesTransparency() const
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.
QString label(int idx) const
Returns optional category label.
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...
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.
QgsColorRamp * sourceColorRamp() const
Gets the source color ramp.
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.
bool isCanceled() const
Tells whether the operation has been canceled already.
void legendSymbologyItems(QList< QPair< QString, QColor > > &symbolItems) const override
Gets symbology items if provided by renderer.
int band() const
Returns the raster band used for rendering the raster.
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
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.