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 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
172 bool isNoData =
false;
173 for (
qgssize i = 0; i < rasterSize; ++i )
175 const double value = inputBlock->valueAndNoData( i, isNoData );
178 outputData[i] = myDefaultColor;
181 int val =
static_cast< int >( value );
182 if ( !mColors.contains( val ) )
184 outputData[i] = myDefaultColor;
188 if ( !hasTransparency )
190 outputData[i] = mColors.value( val );
201 currentOpacity *= alphaBlock->value( i ) / 255.0;
204 QRgb
c = mColors.value( val );
205 outputData[i] = qRgba( currentOpacity * qRed( c ), currentOpacity * qGreen( c ), currentOpacity * qBlue( c ), currentOpacity * qAlpha( c ) );
209 return outputBlock.release();
214 if ( parentElem.isNull() )
219 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
222 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
223 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
224 ClassData::const_iterator it = mClassData.constBegin();
225 for ( ; it != mClassData.constEnd(); ++it )
227 QColor color = it->color;
228 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
229 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
230 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
231 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
232 if ( !it->label.isEmpty() )
234 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
236 colorPaletteElem.appendChild( colorElem );
238 rasterRendererElem.appendChild( colorPaletteElem );
241 if ( mSourceColorRamp )
244 rasterRendererElem.appendChild( colorRampElem );
247 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 if ( mSourceColorRamp )
317 ClassData::const_iterator it = mClassData.constBegin();
318 for ( ; it != mClassData.constEnd(); ++it )
320 QString lab = it->label.isEmpty() ? QString::number( it->value ) : it->label;
321 symbolItems << qMakePair( lab, it->color );
337 mSourceColorRamp.reset( ramp );
342 return mSourceColorRamp.get();
347 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
349 for ( ; colorIt != table.constEnd(); ++colorIt )
351 int idx = ( int )( colorIt->value );
361 QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
363 QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
364 const auto constParts = parts;
365 for (
const QString &part : constParts )
367 QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
369 switch ( lineParts.count() )
373 int value = lineParts.at( 0 ).toInt( &ok );
377 classes <<
Class( value );
383 int value = lineParts.at( 0 ).toInt( &ok );
387 QColor
c( lineParts.at( 1 ) );
389 classes <<
Class( value,
c );
395 if ( lineParts.count() < 4 )
398 int value = lineParts.at( 0 ).toInt( &ok );
403 double r = lineParts.at( 1 ).toDouble( &rOk );
405 double g = lineParts.at( 2 ).toDouble( &gOk );
407 double b = lineParts.at( 3 ).toDouble( &bOk );
410 if ( rOk && gOk && bOk )
412 c = QColor( r, g, b );
415 if ( lineParts.count() >= 5 )
417 double alpha = lineParts.at( 4 ).toDouble( &ok );
423 if ( lineParts.count() > 5 )
425 label = lineParts.mid( 5 ).join(
' ' );
428 classes <<
Class( value, c, label );
439 QFile inputFile( path );
441 if ( inputFile.open( QIODevice::ReadOnly ) )
443 QTextStream in( &inputFile );
444 input = in.readAll();
455 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool 457 return a.
value < b.value;
460 const auto constCd = cd;
461 for (
const Class &
c : constCd )
463 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg(
c.value ).arg(
c.color.red() )
464 .arg(
c.color.green() ).arg(
c.color.blue() ).arg(
c.color.alpha() ).arg(
c.label );
466 return out.join(
'\n' );
482 int bins = std::ceil( max - min ) + 1;
494 double currentValue = histogram.
minimum;
495 double presentValues = 0;
496 for (
int idx = 0; idx < histogram.
binCount; ++idx )
501 data <<
Class( currentValue, QColor(), QString::number( currentValue ) );
504 currentValue += interval;
516 randomRamp->setTotalColorCount( data.count() );
519 if ( presentValues > 1 )
522 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
523 for ( ; cIt != data.end(); ++cIt )
525 cIt->color = ramp->
color( i / presentValues );
532 void QgsPalettedRasterRenderer::updateArrays()
536 ClassData::const_iterator it = mClassData.constBegin();
537 for ( ; it != mClassData.constEnd(); ++it )
539 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
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)
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.