32#include <QDomDocument>
36using namespace Qt::StringLiterals;
41 , mRasterDataType( dataType )
42 , mRasterDataTypeRange( mMaximumValue - mMinimumValue )
43 , mLookupTableOffset( mMinimumValue * -1 )
45 mContrastEnhancementFunction = std::make_unique<QgsContrastEnhancementFunction>( mRasterDataType, mMinimumValue, mMaximumValue );
48 if ( mRasterDataTypeRange <= 65535.0 )
50 mLookupTable = std::make_unique<int[]>(
static_cast<int>( mRasterDataTypeRange + 1 ) );
55 : mEnhancementDirty( true )
56 , mMinimumValue( ce.mMinimumValue )
57 , mMaximumValue( ce.mMaximumValue )
58 , mRasterDataType( ce.mRasterDataType )
59 , mRasterDataTypeRange( ce.mRasterDataTypeRange )
67 if ( mRasterDataTypeRange <= 65535.0 )
69 mLookupTable = std::make_unique<int[]>(
static_cast<int>( mRasterDataTypeRange + 1 ) );
78 if ( mEnhancementDirty )
80 generateLookupTable();
83 if ( mLookupTable &&
NoEnhancement != mContrastEnhancementAlgorithm )
85 const double shiftedValue = value + mLookupTableOffset;
86 if ( shiftedValue >= 0 && shiftedValue < mRasterDataTypeRange + 1 )
87 return mLookupTable[
static_cast<int>( shiftedValue )];
95 return mContrastEnhancementFunction->enhance( value );
99bool QgsContrastEnhancement::generateLookupTable()
101 mEnhancementDirty =
false;
103 if ( !mContrastEnhancementFunction )
108 switch ( mRasterDataType )
136 QgsDebugMsgLevel( u
"***mLookupTableOffset : %1"_s.arg( mLookupTableOffset ), 4 );
137 QgsDebugMsgLevel( u
"***mRasterDataTypeRange : %1"_s.arg( mRasterDataTypeRange ), 4 );
139 for (
int myIterator = 0; myIterator <= mRasterDataTypeRange; myIterator++ )
141 mLookupTable[myIterator] = mContrastEnhancementFunction->enhance(
static_cast< double >( myIterator ) - mLookupTableOffset );
149 if ( mContrastEnhancementFunction )
151 return mContrastEnhancementFunction->isValueInDisplayableRange( value );
162 mContrastEnhancementFunction = std::make_unique<QgsLinearMinMaxEnhancement>( mRasterDataType, mMinimumValue, mMaximumValue );
165 mContrastEnhancementFunction = std::make_unique<QgsLinearMinMaxEnhancementWithClip>( mRasterDataType, mMinimumValue, mMaximumValue );
168 mContrastEnhancementFunction = std::make_unique<QgsClipToMinMaxEnhancement>( mRasterDataType, mMinimumValue, mMaximumValue );
174 mContrastEnhancementFunction = std::make_unique<QgsContrastEnhancementFunction>( mRasterDataType, mMinimumValue, mMaximumValue );
178 mEnhancementDirty =
true;
179 mContrastEnhancementAlgorithm =
algorithm;
183 generateLookupTable();
193 mContrastEnhancementFunction.reset( function );
195 generateLookupTable();
201 QgsDebugMsgLevel(
"called value: " + QString::number( value ) +
" generate lookup table: " + QString::number(
static_cast< int >( generateTable ) ), 4 );
209 mMaximumValue = value;
212 if ( mContrastEnhancementFunction )
214 mContrastEnhancementFunction->setMaximumValue( value );
217 mEnhancementDirty =
true;
221 generateLookupTable();
227 QgsDebugMsgLevel(
"called value: " + QString::number( value ) +
" generate lookup table: " + QString::number(
static_cast< int >( generateTable ) ), 4 );
235 mMinimumValue = value;
238 if ( mContrastEnhancementFunction )
240 mContrastEnhancementFunction->setMinimumValue( value );
243 mEnhancementDirty =
true;
247 generateLookupTable();
254 QDomElement minElem = doc.createElement( u
"minValue"_s );
256 minElem.appendChild( minText );
257 parentElem.appendChild( minElem );
260 QDomElement maxElem = doc.createElement( u
"maxValue"_s );
262 maxElem.appendChild( maxText );
263 parentElem.appendChild( maxElem );
266 QDomElement algorithmElem = doc.createElement( u
"algorithm"_s );
268 algorithmElem.appendChild( algorithmText );
269 parentElem.appendChild( algorithmElem );
274 const QDomElement minValueElem = elem.firstChildElement( u
"minValue"_s );
275 if ( !minValueElem.isNull() )
277 mMinimumValue = minValueElem.text().toDouble();
279 const QDomElement maxValueElem = elem.firstChildElement( u
"maxValue"_s );
280 if ( !maxValueElem.isNull() )
282 mMaximumValue = maxValueElem.text().toDouble();
284 const QDomElement algorithmElem = elem.firstChildElement( u
"algorithm"_s );
285 if ( !algorithmElem.isNull() )
287 const QString algorithmString = algorithmElem.text();
290 if ( algorithmString ==
"0"_L1 )
294 else if ( algorithmString ==
"1"_L1 )
298 else if ( algorithmString ==
"2"_L1 )
302 else if ( algorithmString ==
"3"_L1 )
306 else if ( algorithmString ==
"4"_L1 )
321 if ( doc.isNull() || element.isNull() )
328 algName = u
"StretchToMinimumMaximum"_s;
333 algName = u
"ClipToMinimumMaximum"_s;
336 algName = u
"ClipToMinimumMaximum"_s;
342 QgsDebugError( u
"No SLD1.0 conversion yet for stretch algorithm %1"_s.arg( algName ) );
349 QDomElement normalizeElem = doc.createElement( u
"sld:Normalize"_s );
350 element.appendChild( normalizeElem );
352 QDomElement vendorOptionAlgorithmElem = doc.createElement( u
"sld:VendorOption"_s );
353 vendorOptionAlgorithmElem.setAttribute( u
"name"_s, u
"algorithm"_s );
354 vendorOptionAlgorithmElem.appendChild( doc.createTextNode( algName ) );
355 normalizeElem.appendChild( vendorOptionAlgorithmElem );
357 QDomElement vendorOptionMinValueElem = doc.createElement( u
"sld:VendorOption"_s );
358 vendorOptionMinValueElem.setAttribute( u
"name"_s, u
"minValue"_s );
359 vendorOptionMinValueElem.appendChild( doc.createTextNode( QString::number(
minimumValue() ) ) );
360 normalizeElem.appendChild( vendorOptionMinValueElem );
362 QDomElement vendorOptionMaxValueElem = doc.createElement( u
"sld:VendorOption"_s );
363 vendorOptionMaxValueElem.setAttribute( u
"name"_s, u
"maxValue"_s );
364 vendorOptionMaxValueElem.appendChild( doc.createTextNode( QString::number(
maximumValue() ) ) );
365 normalizeElem.appendChild( vendorOptionMaxValueElem );
373 return u
"NoEnhancement"_s;
375 return u
"StretchToMinimumMaximum"_s;
377 return u
"StretchAndClipToMinimumMaximum"_s;
379 return u
"ClipToMinimumMaximum"_s;
381 return u
"UserDefinedEnhancement"_s;
383 return u
"NoEnhancement"_s;
388 if ( contrastEnhancementString ==
"StretchToMinimumMaximum"_L1 )
392 else if ( contrastEnhancementString ==
"StretchAndClipToMinimumMaximum"_L1 )
396 else if ( contrastEnhancementString ==
"ClipToMinimumMaximum"_L1 )
400 else if ( contrastEnhancementString ==
"UserDefinedEnhancement"_L1 )
DataType
Raster data types.
@ Float32
Thirty two bit floating point (float).
@ CFloat64
Complex Float64.
@ Int16
Sixteen bit signed integer (qint16).
@ ARGB32_Premultiplied
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
@ Int8
Eight bit signed integer (qint8) (added in QGIS 3.30).
@ UInt16
Sixteen bit unsigned integer (quint16).
@ Byte
Eight bit unsigned integer (quint8).
@ UnknownDataType
Unknown or unspecified type.
@ ARGB32
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
@ Int32
Thirty two bit signed integer (qint32).
@ Float64
Sixty four bit floating point (double).
@ CFloat32
Complex Float32.
@ UInt32
Thirty two bit unsigned integer (quint32).
A contrast enhancement function is the base class for all raster contrast enhancements.
ContrastEnhancementAlgorithm
This enumerator describes the types of contrast enhancement algorithms that can be used.
@ StretchToMinimumMaximum
Linear histogram.
@ StretchAndClipToMinimumMaximum
@ NoEnhancement
Default color scaling algorithm, no scaling is applied.
QgsContrastEnhancement(Qgis::DataType datatype=Qgis::DataType::Byte)
Constructor for QgsContrastEnhancement, for the specified data type.
void setMinimumValue(double value, bool generateTable=true)
Sets the minimum value for the contrast enhancement range.
static QString contrastEnhancementAlgorithmString(ContrastEnhancementAlgorithm algorithm)
Returns a string to serialize ContrastEnhancementAlgorithm.
static ContrastEnhancementAlgorithm contrastEnhancementAlgorithmFromString(const QString &contrastEnhancementString)
Deserialize ContrastEnhancementAlgorithm.
static double maximumValuePossible(Qgis::DataType dataType)
Helper function that returns the maximum possible value for a data type.
void setContrastEnhancementAlgorithm(ContrastEnhancementAlgorithm algorithm, bool generateTable=true)
Sets the contrast enhancement algorithm.
bool isValueInDisplayableRange(double value)
Returns true if a pixel value is in displayable range, false if pixel is outside of range (i....
int enhanceContrast(double value)
Applies the contrast enhancement to a value.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const
void readXml(const QDomElement &elem)
double minimumValue() const
Returns the minimum value for the contrast enhancement range.
static double minimumValuePossible(Qgis::DataType dataType)
Helper function that returns the minimum possible value for a data type.
void setContrastEnhancementFunction(QgsContrastEnhancementFunction *function)
Allows the user to set their own custom contrast enhancement function.
void toSld(QDomDocument &doc, QDomElement &element) const
Write ContrastEnhancement tags following SLD v1.0 specs SLD1.0 is limited to the parameters listed in...
~QgsContrastEnhancement()
ContrastEnhancementAlgorithm contrastEnhancementAlgorithm() const
void setMaximumValue(double value, bool generateTable=true)
Sets the maximum value for the contrast enhancement range.
double maximumValue() const
Returns the maximum value for the contrast enhancement range.
static QString printValue(double value, bool localized=false)
Print double value with all necessary significant digits.
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 allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)