30#include <QDomDocument>
36#include <QRegularExpression>
39const int QgsPalettedRasterRenderer::MAX_FLOAT_CLASSES = 65536;
47 MultiValueClassData::iterator it = std::find_if( mMultiValueClassData.begin(), mMultiValueClassData.end(), [&klass](
const MultiValueClass & val ) ->
bool
49 return val.label == klass.label && val.color == klass.color ;
51 if ( it != mMultiValueClassData.end() )
53 it->values.push_back( klass.value );
66 , mMultiValueClassData( classes )
74 std::unique_ptr< QgsPalettedRasterRenderer > renderer = std::make_unique< QgsPalettedRasterRenderer >(
nullptr, mBand, mMultiValueClassData );
76 if ( mSourceColorRamp )
77 renderer->setSourceColorRamp( mSourceColorRamp->clone() );
79 renderer->copyCommonProperties(
this );
81 return renderer.release();
96 const int bandNumber = elem.attribute( QStringLiteral(
"band" ), QStringLiteral(
"-1" ) ).toInt();
99 const QDomElement paletteElem = elem.firstChildElement( QStringLiteral(
"colorPalette" ) );
100 if ( !paletteElem.isNull() )
102 const QDomNodeList paletteEntries = paletteElem.elementsByTagName( QStringLiteral(
"paletteEntry" ) );
104 QDomElement entryElem;
107 for (
int i = 0; i < paletteEntries.size(); ++i )
111 entryElem = paletteEntries.at( i ).toElement();
112 value = entryElem.attribute( QStringLiteral(
"value" ), QStringLiteral(
"0" ) ).toDouble();
113 color = QColor( entryElem.attribute( QStringLiteral(
"color" ), QStringLiteral(
"#000000" ) ) );
114 color.setAlpha( entryElem.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"255" ) ).toInt() );
115 label = entryElem.attribute( QStringLiteral(
"label" ) );
116 QgsDebugMsgLevel( QStringLiteral(
"Value: %1, label: %2, color: %3" ).arg( value ).arg(
label, entryElem.attribute( QStringLiteral(
"color" ) ) ), 4 );
125 QDomElement sourceColorRampElem = elem.firstChildElement( QStringLiteral(
"colorramp" ) );
126 if ( !sourceColorRampElem.isNull() && sourceColorRampElem.attribute( QStringLiteral(
"name" ) ) == QLatin1String(
"[source]" ) )
141 return mMultiValueClassData;
146 mMultiValueClassData =
classes;
152 if ( ! mMultiValueClassData.isEmpty() )
154 const auto constMClassData = mMultiValueClassData;
157 if (
c.values.contains( idx ) )
167 MultiValueClassData::iterator cMvIt = mMultiValueClassData.begin();
168 for ( ; cMvIt != mMultiValueClassData.end(); ++cMvIt )
170 if ( cMvIt->values.contains( idx ) )
172 cMvIt->label =
label;
180 std::unique_ptr< QgsRasterBlock > outputBlock(
new QgsRasterBlock() );
181 if ( !
mInput || mMultiValueClassData.isEmpty() )
183 return outputBlock.release();
186 const std::shared_ptr< QgsRasterBlock > inputBlock(
mInput->
block( mBand,
extent, width, height, feedback ) );
188 if ( !inputBlock || inputBlock->isEmpty() )
190 QgsDebugMsg( QStringLiteral(
"No raster data!" ) );
191 return outputBlock.release();
197 std::shared_ptr< QgsRasterBlock > alphaBlock;
202 if ( !alphaBlock || alphaBlock->isEmpty() )
204 return outputBlock.release();
209 alphaBlock = inputBlock;
214 return outputBlock.release();
221 Q_ASSERT( outputBlock );
222 unsigned int *outputData = (
unsigned int * )( outputBlock->bits() );
225 bool isNoData =
false;
226 for (
qgssize i = 0; i < rasterSize; ++i )
228 const double value = inputBlock->valueAndNoData( i, isNoData );
231 outputData[i] = myDefaultColor;
234 if ( !mColors.contains( value ) )
236 outputData[i] = myDefaultColor;
240 if ( !hasTransparency )
242 outputData[i] = mColors.value( value );
253 const double alpha = alphaBlock->value( i );
256 outputBlock->setColor( i, myDefaultColor );
261 currentOpacity *= alpha / 255.0;
265 const QRgb
c = mColors.value( value );
266 outputData[i] = qRgba( currentOpacity * qRed(
c ), currentOpacity * qGreen(
c ), currentOpacity * qBlue(
c ), currentOpacity * qAlpha(
c ) );
270 return outputBlock.release();
275 return mMultiValueClassData.size();
280 if ( parentElem.isNull() )
285 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
288 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), mBand );
289 QDomElement colorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
290 const ClassData klassData { classData() };
291 ClassData::const_iterator it = klassData.constBegin();
292 for ( ; it != klassData.constEnd(); ++it )
294 const QColor color = it->color;
295 QDomElement colorElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
296 colorElem.setAttribute( QStringLiteral(
"value" ), it->value );
297 colorElem.setAttribute( QStringLiteral(
"color" ), color.name() );
298 colorElem.setAttribute( QStringLiteral(
"alpha" ), color.alpha() );
299 if ( !it->label.isEmpty() )
301 colorElem.setAttribute( QStringLiteral(
"label" ), it->label );
303 colorPaletteElem.appendChild( colorElem );
305 rasterRendererElem.appendChild( colorPaletteElem );
308 if ( mSourceColorRamp )
311 rasterRendererElem.appendChild( colorRampElem );
314 parentElem.appendChild( rasterRendererElem );
323 const QDomNodeList elements = element.elementsByTagName( QStringLiteral(
"sld:RasterSymbolizer" ) );
324 if ( elements.size() == 0 )
328 QDomElement rasterSymbolizerElem = elements.at( 0 ).toElement();
331 QDomElement channelSelectionElem = doc.createElement( QStringLiteral(
"sld:ChannelSelection" ) );
332 rasterSymbolizerElem.appendChild( channelSelectionElem );
335 QDomElement channelElem = doc.createElement( QStringLiteral(
"sld:GrayChannel" ) );
336 channelSelectionElem.appendChild( channelElem );
339 QDomElement sourceChannelNameElem = doc.createElement( QStringLiteral(
"sld:SourceChannelName" ) );
340 sourceChannelNameElem.appendChild( doc.createTextNode( QString::number(
band() ) ) );
341 channelElem.appendChild( sourceChannelNameElem );
344 QDomElement colorMapElem = doc.createElement( QStringLiteral(
"sld:ColorMap" ) );
345 colorMapElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"values" ) );
346 if ( this->
classes().size() >= 255 )
347 colorMapElem.setAttribute( QStringLiteral(
"extended" ), QStringLiteral(
"true" ) );
348 rasterSymbolizerElem.appendChild( colorMapElem );
352 const QList<QgsPalettedRasterRenderer::Class>
classes = this->
classes();
353 QList<QgsPalettedRasterRenderer::Class>::const_iterator classDataIt =
classes.constBegin();
354 for ( ; classDataIt !=
classes.constEnd(); ++classDataIt )
356 QDomElement colorMapEntryElem = doc.createElement( QStringLiteral(
"sld:ColorMapEntry" ) );
357 colorMapElem.appendChild( colorMapEntryElem );
360 colorMapEntryElem.setAttribute( QStringLiteral(
"color" ), classDataIt->color.name() );
361 colorMapEntryElem.setAttribute( QStringLiteral(
"quantity" ), QString::number( classDataIt->value ) );
362 colorMapEntryElem.setAttribute( QStringLiteral(
"label" ), classDataIt->label );
363 if ( classDataIt->color.alphaF() != 1.0 )
365 colorMapEntryElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( classDataIt->color.alphaF() ) );
372 if ( mSourceColorRamp )
384 QList< QPair< QString, QColor > > symbolItems;
387 QString lab { classData.label };
391 for (
const QVariant &val : std::as_const( classData.values ) )
395 const double numericValue { val.toDouble( &ok ) };
398 values.push_back( QLocale().toString( numericValue ) );
402 values.push_back( val.toString() );
405 lab = values.join( QChar(
' ' ) );
407 symbolItems << qMakePair( lab, classData.color );
415 QList<QgsLayerTreeModelLegendNode *> res;
418 if ( !name.isEmpty() )
424 res.reserve( res.size() + items.size() );
425 for (
const QPair< QString, QColor > &item : items )
446 mSourceColorRamp.reset( ramp );
451 return mSourceColorRamp.get();
456 QList<QgsColorRampShader::ColorRampItem>::const_iterator colorIt = table.constBegin();
458 for ( ; colorIt != table.constEnd(); ++colorIt )
467 if ( ! attributeTable || ! attributeTable->
isValid() )
474 const QList<QgsRasterAttributeTable::MinMaxClass> minMaxClasses { attributeTable->
minMaxClasses( classificationColumn ) };
475 if ( minMaxClasses.empty() )
480 QVector<QVariant> values;
481 for (
const double val : std::as_const( minMaxClass.minMaxValues ) )
483 values.push_back( QVariant( val ) );
485 classData.push_back( { values, minMaxClass.color, minMaxClass.name } );
488 int numClasses {
static_cast<int>( classData.count( ) ) };
491 if ( ramp && numClasses > 0 )
499 randomRamp->setTotalColorCount( numClasses );
502 if ( numClasses > 1 )
505 QgsPalettedRasterRenderer::MultiValueClassData::iterator cIt = classData.begin();
506 for ( ; cIt != classData.end(); ++cIt )
508 cIt->color = ramp->
color( i /
static_cast<double>( numClasses ) );
520 const QRegularExpression linePartRx( QStringLiteral(
"[\\s,:]+" ) );
522#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
523 const QStringList parts =
string.split(
'\n', QString::SkipEmptyParts );
525 const QStringList parts =
string.split(
'\n', Qt::SkipEmptyParts );
527 for (
const QString &part : parts )
529#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
530 const QStringList lineParts = part.split( linePartRx, QString::SkipEmptyParts );
532 const QStringList lineParts = part.split( linePartRx, Qt::SkipEmptyParts );
535 switch ( lineParts.count() )
539 const int value = lineParts.at( 0 ).toInt( &ok );
549 const int value = lineParts.at( 0 ).toInt( &ok );
553 const QColor
c( lineParts.at( 1 ) );
561 if ( lineParts.count() < 4 )
564 const int value = lineParts.at( 0 ).toInt( &ok );
569 const double r = lineParts.at( 1 ).toDouble( &rOk );
571 const double g = lineParts.at( 2 ).toDouble( &gOk );
573 const double b = lineParts.at( 3 ).toDouble( &bOk );
576 if ( rOk && gOk && bOk )
578 c = QColor( r, g, b );
581 if ( lineParts.count() >= 5 )
583 const double alpha = lineParts.at( 4 ).toDouble( &ok );
589 if ( lineParts.count() > 5 )
591 label = lineParts.mid( 5 ).join(
' ' );
605 QFile inputFile( path );
607 if ( inputFile.open( QIODevice::ReadOnly ) )
609 QTextStream in( &inputFile );
610 input = in.readAll();
621 std::sort( cd.begin(), cd.end(), [](
const Class & a,
const Class & b ) ->
bool
623 return a.value < b.value;
626 const auto constCd = cd;
627 for (
const Class &
c : constCd )
629 out << QStringLiteral(
"%1 %2 %3 %4 %5 %6" ).arg(
c.value ).arg(
c.color.red() )
630 .arg(
c.color.green() ).arg(
c.color.blue() ).arg(
c.color.alpha() ).arg(
c.label );
632 return out.join(
'\n' );
642 if ( bandNumber > 0 && bandNumber <= raster->
bandCount() )
644 qlonglong numClasses = 0;
658 std::set<double> values;
666 const int nbBlocksWidth =
static_cast< int >( std::ceil( 1.0 * raster->
xSize() / maxWidth ) );
667 const int nbBlocksHeight =
static_cast< int >( std::ceil( 1.0 * raster->
ySize() / maxHeight ) );
668 const int nbBlocks = nbBlocksWidth * nbBlocksHeight;
674 std::unique_ptr< QgsRasterBlock > rasterBlock;
676 bool isNoData =
false;
677 while ( iter.
readNextRasterPart( bandNumber, iterCols, iterRows, rasterBlock, iterLeft, iterTop, &blockExtent ) )
680 feedback->
setProgress( 100 * ( ( iterTop / maxHeight * nbBlocksWidth ) + iterLeft / maxWidth ) / nbBlocks );
685 for (
int row = 0; row < iterRows; row++ )
690 for (
int column = 0; column < iterCols; column++ )
695 const double currentValue = rasterBlock->valueAndNoData( row, column, isNoData );
696 if ( numClasses >= MAX_FLOAT_CLASSES )
698 QgsMessageLog::logMessage( QStringLiteral(
"Number of classes exceeded maximum (%1)." ).arg( MAX_FLOAT_CLASSES ), QStringLiteral(
"Raster" ) );
701 if ( !isNoData && values.find( currentValue ) == values.end() )
703 values.insert( currentValue );
704 data.push_back(
Class( currentValue, QColor(), QLocale().toString( currentValue ) ) );
711 std::sort( data.begin(), data.end(), [](
const Class & a,
const Class & b ) ->
bool
713 return a.value < b.value;
726 const int bins = std::ceil( max - min ) + 1;
744 data <<
Class( currentValue, QColor(), QLocale().toString( currentValue ) );
747 currentValue += interval;
758 if ( ramp && numClasses > 0 )
766 randomRamp->setTotalColorCount( data.count() );
769 if ( numClasses > 1 )
772 QgsPalettedRasterRenderer::ClassData::iterator cIt = data.begin();
773 for ( ; cIt != data.end(); ++cIt )
778 feedback->
setProgress( std::max<int>( 1, 100 * ( i + 1 ) / numClasses ) );
780 cIt->color = ramp->
color( i /
static_cast<double>( numClasses ) );
791 for (
const MultiValueClass &klass : std::as_const( mMultiValueClassData ) )
793 for (
const QVariant &entry : std::as_const( klass.values ) )
796 const double value { entry.toDouble( &ok )};
799 data.push_back( { value, klass.color, klass.label } );
803 QgsDebugMsgLevel( QStringLiteral(
"Could not convert class value '%1' to double when creating classes." ).arg( entry.toString() ), 2 );
810void QgsPalettedRasterRenderer::updateArrays()
814 MultiValueClassData::const_iterator it = mMultiValueClassData.constBegin();
815 for ( ; it != mMultiValueClassData.constEnd(); ++it )
817 for (
const QVariant &entry : std::as_const( it->values ) )
820 const double value { entry.toDouble( &ok )};
823 mColors[value] = qPremultiply( it->color.rgba() );
827 QgsDebugMsgLevel( QStringLiteral(
"Could not convert class value '%1' to double for color lookup." ).arg( entry.toString() ), 2 );
@ InternalLayerOpacityHandling
The renderer internally handles the raster layer's opacity, so the default layer level opacity handli...
@ Float32
Thirty two bit floating point (float)
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Float64
Sixty four bit floating point (double)
Abstract base class for color ramps.
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
bool isCanceled() const SIP_HOLDGIL
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Layer tree node points to a map layer.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Properties of a multi value class: a class that contains multiple values.
QColor color
Color to render values.
MultiValueClass(const QVector< QVariant > &values, const QColor &color=QColor(), const QString &label=QString())
Constructor for MultiValueClass from a list of values.
Renderer for paletted raster images.
int band() const
Returns the raster band used for rendering the 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.
QList< QgsLayerTreeModelLegendNode * > createLegendNodes(QgsLayerTreeLayer *nodeLayer) override
Creates a set of legend nodes representing the renderer.
static QgsPalettedRasterRenderer::MultiValueClassData rasterAttributeTableToClassData(const QgsRasterAttributeTable *attributeTable, int classificationColumn=-1, QgsColorRamp *ramp=nullptr)
Reads and returns classes from the Raster Attribute Table attributeTable, optionally classifying the ...
QgsColorRamp * sourceColorRamp() const
Gets the source color ramp.
static QgsPalettedRasterRenderer::ClassData classDataFromString(const QString &string)
Converts a string containing a color table or class data to to paletted renderer class data.
QString label(double idx) const
Returns optional category label.
void setSourceColorRamp(QgsColorRamp *ramp)
Set the source color ramp.
QList< int > usesBands() const override
Returns a list of band numbers used by the renderer.
bool canCreateRasterAttributeTable() const override
Returns true if the renderer is suitable for attribute table creation.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
QList< QgsPalettedRasterRenderer::Class > ClassData
Map of value to class properties.
bool accept(QgsStyleEntityVisitorInterface *visitor) const override
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
Qgis::RasterRendererFlags flags() const override
Returns flags which dictate renderer behavior.
int nColors() const
Returns number of colors.
QList< QgsPalettedRasterRenderer::MultiValueClass > MultiValueClassData
Map of multi value to class properties.
static QgsPalettedRasterRenderer::ClassData classDataFromFile(const QString &path)
Opens a color table file and returns corresponding paletted renderer class data.
static QgsRasterRenderer * create(const QDomElement &elem, QgsRasterInterface *input)
void setMultiValueClasses(const MultiValueClassData &classes)
Sets the multi value classes to setMultiValueClasses.
static QgsPalettedRasterRenderer::ClassData colorTableToClassData(const QList< QgsColorRampShader::ColorRampItem > &table)
Converts a raster color table to paletted renderer class data.
ClassData classes() const
Returns a map of value to classes (colors) used by the renderer.
QList< QPair< QString, QColor > > legendSymbologyItems() const override
Returns symbology items if provided by renderer.
QgsPalettedRasterRenderer * clone() const override
Clone itself, create deep copy.
void setLabel(double idx, const QString &label)
Set category label.
static QgsPalettedRasterRenderer::ClassData classDataFromRaster(QgsRasterInterface *raster, int bandNumber, QgsColorRamp *ramp=nullptr, QgsRasterBlockFeedback *feedback=nullptr)
Generates class data from a raster, for the specified bandNumber.
static QString classDataToString(const QgsPalettedRasterRenderer::ClassData &classes)
Converts classes to a string representation, using the .clr/gdal color table file format.
MultiValueClassData multiValueClasses() const
Returns a map of multi value to classes (colors) used by the renderer.
void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const override
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
QgsPalettedRasterRenderer(QgsRasterInterface *input, int bandNumber, const ClassData &classes)
Constructor for QgsPalettedRasterRenderer.
Totally random color ramp.
The Field class represents a Raster Attribute Table classification entry for a thematic Raster Attrib...
The QgsRasterAttributeTable class represents a Raster Attribute Table (RAT).
QList< QgsRasterAttributeTable::MinMaxClass > minMaxClasses(const int classificationColumn=-1) const
Returns the classes for a thematic Raster Attribute Table, classified by classificationColumn,...
bool isValid(QString *errorMessage=nullptr) const
Returns true if the Raster Attribute Table is valid, optionally reporting validity checks results in ...
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
Feedback object tailored for raster block reading.
The QgsRasterHistogram is a container for histogram of a single raster band.
double minimum
The minimum histogram value.
double maximum
The maximum histogram value.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
bool valid
Histogram is valid.
int binCount
Number of bins (intervals,buckets) in histogram.
Base class for processing filters like renderers, reprojector, resampler etc.
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.
virtual Qgis::DataType dataType(int bandNo) const =0
Returns data type for the band specified by number.
virtual int xSize() const
Gets raster size.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
QgsRasterInterface * mInput
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
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.
Iterator for sequentially processing raster cells.
static const int DEFAULT_MAXIMUM_TILE_WIDTH
Default maximum tile width.
bool readNextRasterPart(int bandNumber, int &nCols, int &nRows, QgsRasterBlock **block, int &topLeftCol, int &topLeftRow)
Fetches next part of raster data, caller takes ownership of the block and caller should delete the bl...
static const int DEFAULT_MAXIMUM_TILE_HEIGHT
Default maximum tile height.
void startRasterRead(int bandNumber, qgssize nCols, qgssize nRows, const QgsRectangle &extent, QgsRasterBlockFeedback *feedback=nullptr)
Start reading of raster band.
Raster renderer pipe that applies colors to a raster.
double mOpacity
Global alpha value (0-1)
int mAlphaBand
Read alpha value from band.
QRgb renderColorForNodataPixel() const
Returns the color for the renderer to use to represent nodata pixels.
void _writeXml(QDomDocument &doc, QDomElement &rasterRendererElem) const
Write upper class info into rasterrenderer element (called by writeXml method of subclasses)
int bandCount() const override
Gets number of bands.
QgsRasterTransparency * mRasterTransparency
Raster transparency per color or value. Overwrites global alpha value.
bool usesTransparency() const
virtual void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props=QVariantMap()) const
Used from subclasses to create SLD Rule elements following SLD v1.0 specs.
void readXml(const QDomElement &rendererElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
Implementation of legend node interface for displaying raster legend entries.
int alphaValue(double value, int globalTransparency=255) const
Returns the transparency value for a single value pixel.
A rectangle specified with double values.
Implementation of legend node interface for displaying arbitrary label with icon.
A color ramp entity for QgsStyle databases.
An interface for classes which can visit style entity (e.g.
virtual bool visit(const QgsStyleEntityVisitorInterface::StyleLeaf &entity)
Called when the visitor will visit a style entity.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
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
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...
#define QgsDebugMsgLevel(str, level)
Properties of a single value class.
Contains information relating to the style entity currently being visited.