25 #include <QDomDocument> 26 #include <QDomElement> 34 , mClassData( classes )
42 if ( mSourceColorRamp )
56 int bandNumber = elem.attribute( QStringLiteral(
"band" ), QStringLiteral(
"-1" ) ).toInt();
59 QDomElement paletteElem = elem.firstChildElement( QStringLiteral(
"colorPalette" ) );
60 if ( !paletteElem.isNull() )
62 QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral(
"paletteEntry" ) );
64 QDomElement entryElem;
67 for (
int i = 0; i < paletteEntries.size(); ++i )
71 entryElem = paletteEntries.at( i ).toElement();
72 value =
static_cast<int>( entryElem.attribute( QStringLiteral(
"value" ), QStringLiteral(
"0" ) ).toDouble() );
74 color = QColor( entryElem.attribute( QStringLiteral(
"color" ), QStringLiteral(
"#000000" ) ) );
75 color.setAlpha( entryElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt() );
76 label = entryElem.attribute( QStringLiteral(
"label" ) );
77 classData <<
Class( value, color, label );
85 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral(
"colorramp" ) );
86 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
101 const auto constMClassData = mClassData;
102 for (
const Class &
c : constMClassData )
104 if (
c.value == idx )
113 ClassData::iterator cIt = mClassData.begin();
114 for ( ; cIt != mClassData.end(); ++cIt )
116 if ( cIt->value == idx )
126 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
127 if ( !
mInput || mClassData.isEmpty() )
129 return outputBlock.release();
132 std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mBand, extent, width, height, feedback ) );
134 if ( !inputBlock || inputBlock->isEmpty() )
136 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
137 return outputBlock.release();
145 std::shared_ptr< QgsRasterBlock > alphaBlock;
150 if ( !alphaBlock || alphaBlock->isEmpty() )
152 return outputBlock.release();
157 alphaBlock = inputBlock;
162 return outputBlock.release();
169 Q_ASSERT( outputBlock );
170 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
173 bool isNoData =
false;
174 for (
qgssize i = 0; i < rasterSize; ++i )
176 const double value = inputBlock->valueAndNoData( i, isNoData );
179 outputData[i] = myDefaultColor;
182 int val =
static_cast< int >( value );
183 if ( !mColors.contains( val ) )
185 outputData[i] = myDefaultColor;
189 if ( !hasTransparency )
191 outputData[i] = mColors.value( val );
202 currentOpacity *= alphaBlock->value( i ) / 255.0;
205 QRgb
c = mColors.value( val );
206 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
210 return outputBlock.release();
215 if ( parentElem.isNull() )
220 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
223 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
224 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
225 ClassData::const_iterator it = mClassData.constBegin();
226 for ( ; it != mClassData.constEnd(); ++it )
228 QColor color = it->color;
229 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
230 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
231 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
232 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
233 if ( !it->label.isEmpty() )
235 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
237 colorPaletteElem.appendChild( colorElem );
239 rasterRendererElem.appendChild( colorPaletteElem );
242 if ( mSourceColorRamp )
245 rasterRendererElem.appendChild( colorRampElem );
248 parentElem.appendChild( rasterRendererElem );
257 QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
258 if ( elements.size() == 0 )
262 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
265 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
266 rasterSymbolizerElem.appendChild( channelSelectionElem );
269 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
270 channelSelectionElem.appendChild( channelElem );
273 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
274 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
275 channelElem.appendChild( sourceChannelNameElem );
278 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
279 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
280 if ( this->
classes().size() >= 255 )
281 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
282 rasterSymbolizerElem.appendChild( colorMapElem );
286 QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
287 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt = classes.constBegin();
288 for ( ; classDataIt != classes.constEnd(); ++classDataIt )
290 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
291 colorMapElem.appendChild( colorMapEntryElem );
294 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
295 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
296 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
297 if ( classDataIt->color.alphaF() != 1.0 )
299 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
306 if ( mSourceColorRamp )
318 ClassData::const_iterator it = mClassData.constBegin();
319 for ( ; it != mClassData.constEnd(); ++it )
321 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
322 symbolItems << qMakePair( lab, it->color );
338 mSourceColorRamp.reset( ramp );
343 return mSourceColorRamp.get();
348 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
350 for ( ; colorIt != table.constEnd(); ++colorIt )
352 int idx = ( int )( colorIt->value );
362 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
364 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
365 const auto constParts = parts;
366 for (
const QString &part : constParts )
368 QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
370 switch ( lineParts.count() )
374 int value = lineParts.at( 0 ).toInt( &ok );
378 classes <<
Class( value );
384 int value = lineParts.at( 0 ).toInt( &ok );
388 QColor
c( lineParts.at( 1 ) );
390 classes <<
Class( value,
c );
396 if ( lineParts.count() < 4 )
399 int value = lineParts.at( 0 ).toInt( &ok );
404 double r = lineParts.at( 1 ).toDouble( &rOk );
406 double g = lineParts.at( 2 ).toDouble( &gOk );
408 double b = lineParts.at( 3 ).toDouble( &bOk );
411 if ( rOk && gOk && bOk )
413 c = QColor( r, g, b );
416 if ( lineParts.count() >= 5 )
418 double alpha = lineParts.at( 4 ).toDouble( &ok );
424 if ( lineParts.count() > 5 )
426 label = lineParts.mid( 5 ).join(
' ' );
429 classes <<
Class( value, c, label );
440 QFile inputFile( path );
442 if ( inputFile.open( QIODevice::ReadOnly ) )
444 QTextStream in( &inputFile );
445 input = in.readAll();
456 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool 458 return a.
value < b.value;
461 const auto constCd = cd;
462 for (
const Class &
c : constCd )
464 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg(
c.value ).arg(
c.color.red() )
465 .arg(
c.color.green() ).arg(
c.color.blue() ).arg(
c.color.alpha() ).arg(
c.label );
467 return out.join(
'\n' );
483 int bins = std::ceil( max - min ) + 1;
495 double currentValue = histogram.
minimum;
496 double presentValues = 0;
497 for (
int idx = 0; idx < histogram.
binCount; ++idx )
502 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
505 currentValue += interval;
517 randomRamp->setTotalColorCount( data.count() );
520 if ( presentValues > 1 )
523 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
524 for ( ; cIt != data.end(); ++cIt )
526 cIt->color = ramp->
color( i / presentValues );
533 void QgsPalettedRasterRenderer::updateArrays()
537 ClassData::const_iterator it = mClassData.constBegin();
538 for ( ; it != mClassData.constEnd(); ++it )
540 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.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
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.
An interface for classes which can visit style entity (e.g.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
QMap< QString, QString > QgsStringMap
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
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
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.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
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)
A color ramp entity for QgsStyle databases.
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.
Contains information relating to the style entity currently being visited.
QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.