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 const auto constMClassData = mClassData;
101 for (
const Class &
c : constMClassData )
103 if (
c.value == idx )
112 ClassData::iterator cIt = mClassData.begin();
113 for ( ; cIt != mClassData.end(); ++cIt )
115 if ( cIt->value == idx )
125 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
126 if ( !
mInput || mClassData.isEmpty() )
128 return outputBlock.release();
131 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mBand, extent, width, height, feedback ) );
133 if ( !inputBlock || inputBlock->isEmpty() )
135 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
136 return outputBlock.release();
144 std::shared_ptr< QgsRasterBlock > alphaBlock;
149 if ( !alphaBlock || alphaBlock->isEmpty() )
151 return outputBlock.release();
156 alphaBlock = inputBlock;
161 return outputBlock.release();
168 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
171 bool isNoData =
false;
172 for (
qgssize i = 0; i < rasterSize; ++i )
174 const double value = inputBlock->valueAndNoData( i, isNoData );
177 outputData[i] = myDefaultColor;
180 int val =
static_cast< int >( value );
181 if ( !mColors.contains( val ) )
183 outputData[i] = myDefaultColor;
187 if ( !hasTransparency )
189 outputData[i] = mColors.value( val );
200 currentOpacity *= alphaBlock->value( i ) / 255.0;
203 QRgb
c = mColors.value( val );
204 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
208 return outputBlock.release();
213 if ( parentElem.isNull() )
218 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
221 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
222 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
223 ClassData::const_iterator it = mClassData.constBegin();
224 for ( ; it != mClassData.constEnd(); ++it )
226 QColor color = it->color;
227 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
228 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
229 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
230 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
231 if ( !it->label.isEmpty() )
233 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
235 colorPaletteElem.appendChild( colorElem );
237 rasterRendererElem.appendChild( colorPaletteElem );
240 if ( mSourceColorRamp )
243 rasterRendererElem.appendChild( colorRampElem );
246 parentElem.appendChild( rasterRendererElem );
255 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
256 if ( elements.size() == 0 )
260 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
263 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
264 rasterSymbolizerElem.appendChild( channelSelectionElem );
267 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
268 channelSelectionElem.appendChild( channelElem );
271 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
272 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
273 channelElem.appendChild( sourceChannelNameElem );
276 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
277 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
278 if ( this->
classes().size() >= 255 )
279 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
280 rasterSymbolizerElem.appendChild( colorMapElem );
284 QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
285 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
286 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
288 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
289 colorMapElem.appendChild( colorMapEntryElem );
292 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
293 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
294 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
295 if ( classDataIt->color.alphaF() != 1.0 )
297 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
304 ClassData::const_iterator it = mClassData.constBegin();
305 for ( ; it != mClassData.constEnd(); ++it )
307 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
308 symbolItems << qMakePair( lab, it->color );
324 mSourceColorRamp.reset( ramp );
329 return mSourceColorRamp.get();
334 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
336 for ( ; colorIt != table.constEnd(); ++colorIt )
338 int idx = ( int )( colorIt->value );
348 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
350 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
351 const auto constParts = parts;
352 for (
const QString &part : constParts )
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 const auto constCd = cd;
448 for (
const Class &
c : constCd )
450 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg(
c.value ).arg(
c.color.red() )
451 .arg(
c.color.green() ).arg(
c.color.blue() ).arg(
c.color.alpha() ).arg(
c.label );
453 return out.join(
'\n' );
469 int bins = std::ceil( max - min ) + 1;
481 double currentValue = histogram.
minimum;
482 double presentValues = 0;
483 for (
int idx = 0; idx < histogram.
binCount; ++idx )
488 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
491 currentValue += interval;
503 randomRamp->setTotalColorCount( data.count() );
506 if ( presentValues > 1 )
509 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
510 for ( ; cIt != data.end(); ++cIt )
512 cIt->color = ramp->
color( i / presentValues );
519 void QgsPalettedRasterRenderer::updateArrays()
523 ClassData::const_iterator it = mClassData.constBegin();
524 for ( ; it != mClassData.constEnd(); ++it )
526 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.
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.
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.