18 #ifndef QGSRASTERBLOCK_H
19 #define QGSRASTERBLOCK_H
21 #include "qgis_core.h"
123 return typeSize( mDataType );
153 return mHasNoDataValue || mNoDataBitmap;
161 void setNoDataValue(
double noDataValue )
SIP_HOLDGIL;
185 static QByteArray valueBytes(
Qgis::DataType dataType,
double value );
197 return value(
static_cast< qgssize >( row ) * mWidth + column );
214 return valueAndNoData(
static_cast< qgssize >( row ) * mWidth + column, isNoData );
238 inline double valueAndNoData(
qgssize index,
bool &isNoData )
const SIP_SKIP;
251 return static_cast< const quint8 *
>( mData );
262 if ( !mImage )
return NO_DATA_COLOR;
264 return mImage->pixel( column, row );
274 int row =
static_cast< int >( std::floor(
static_cast< double >( index ) / mWidth ) );
275 int column = index % mWidth;
276 return color( row, column );
288 return isNoData(
static_cast< qgssize >( row ) * mWidth + column );
300 return isNoData( row *
static_cast< qgssize >( mWidth ) + column );
311 if ( !mHasNoDataValue && !mNoDataBitmap )
313 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
315 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
318 if ( mHasNoDataValue )
320 double value = readValue( mData, mDataType, index );
321 return isNoDataValue( value );
324 if ( !mNoDataBitmap )
330 int row =
static_cast< int >( index ) / mWidth;
331 int column = index % mWidth;
332 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
333 int bit = column % 8;
334 int mask = 0x80 >> bit;
337 return mNoDataBitmap[byte] & mask;
349 return setValue(
static_cast< qgssize >( row ) * mWidth + column, value );
362 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
365 if ( index >=
static_cast< qgssize >( mWidth ) *mHeight )
367 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
370 writeValue( mData, mDataType, index, value );
383 return setColor(
static_cast< qgssize >( row ) * mWidth + column, color );
396 QgsDebugMsg( QStringLiteral(
"Image not allocated" ) );
400 if ( index >=
static_cast< qgssize >( mImage->width() ) * mImage->height() )
402 QgsDebugMsg( QStringLiteral(
"index %1 out of range" ).arg( index ) );
407 QRgb *bits =
reinterpret_cast< QRgb *
>( mImage->bits() );
423 return reinterpret_cast< QRgb *
>( mImage->bits() );
434 return setIsNoData(
static_cast< qgssize >( row ) * mWidth + column );
444 if ( mHasNoDataValue )
446 return setValue( index, mNoDataValue );
450 if ( !mNoDataBitmap )
452 if ( !createNoDataBitmap() )
458 int row =
static_cast< int >( index ) / mWidth;
459 int column = index % mWidth;
460 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
461 int bit = column % 8;
462 int nodata = 0x80 >> bit;
464 mNoDataBitmap[byte] = mNoDataBitmap[byte] | nodata;
479 bool setIsNoDataExcept( QRect exceptRect );
492 setIsData(
static_cast< qgssize >( row )*mWidth + column );
505 if ( mHasNoDataValue )
511 if ( !mNoDataBitmap )
517 int row =
static_cast< int >( index ) / mWidth;
518 int column = index % mWidth;
519 qgssize byte =
static_cast< qgssize >( row ) * mNoDataBitmapWidth + column / 8;
520 int bit = column % 8;
521 int nodata = 0x80 >> bit;
522 mNoDataBitmap[byte] = mNoDataBitmap[byte] & ~nodata;
534 QByteArray data()
const;
545 void setData(
const QByteArray &data,
int offset = 0 );
553 char *bits(
int row,
int column )
SIP_SKIP;
574 static QString printValue(
double value );
584 static QString printValue(
float value )
SIP_SKIP;
591 bool convert(
Qgis::DataType destDataType );
596 QImage image() const;
602 bool setImage( const QImage *image );
608 inline static
void writeValue(
void *data,
Qgis::DataType type,
qgssize index,
double value )
SIP_SKIP;
616 void applyScaleOffset(
double scale,
double offset );
624 QString toString()
const;
662 static bool isNoDataValue(
double value,
double noDataValue )
667 return std::isnan( value ) ||
676 inline bool isNoDataValue(
double value )
const;
682 bool createNoDataBitmap();
711 bool mHasNoDataValue =
false;
716 static const QRgb NO_DATA_COLOR;
720 void *mData =
nullptr;
723 QImage *mImage =
nullptr;
728 char *mNoDataBitmap =
nullptr;
731 int mNoDataBitmapWidth = 0;
744 return std::numeric_limits<double>::quiet_NaN();
750 return static_cast< double >( (
static_cast< quint8 *
>( data ) )[index] );
752 return static_cast< double >( (
static_cast< quint16 *
>( data ) )[index] );
754 return static_cast< double >( (
static_cast< qint16 *
>( data ) )[index] );
756 return static_cast< double >( (
static_cast< quint32 *
>( data ) )[index] );
758 return static_cast< double >( (
static_cast< qint32 *
>( data ) )[index] );
760 return static_cast< double >( (
static_cast< float *
>( data ) )[index] );
762 return static_cast< double >( (
static_cast< double *
>( data ) )[index] );
764 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
768 return std::numeric_limits<double>::quiet_NaN();
778 (
static_cast< quint8 *
>( data ) )[index] =
static_cast< quint8
>( value );
781 (
static_cast< quint16 *
>( data ) )[index] =
static_cast< quint16
>( value );
784 (
static_cast< qint16 *
>( data ) )[index] =
static_cast< qint16
>( value );
787 (
static_cast< quint32 *
>( data ) )[index] =
static_cast< quint32
>( value );
790 (
static_cast< qint32 *
>( data ) )[index] =
static_cast< qint32
>( value );
793 (
static_cast< float *
>( data ) )[index] =
static_cast< float >( value );
796 (
static_cast< double *
>( data ) )[index] = value;
799 QgsDebugMsg( QStringLiteral(
"Data type %1 is not supported" ).arg( qgsEnumValueToKey< Qgis::DataType >( type ) ) );
808 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
809 return std::numeric_limits<double>::quiet_NaN();
811 return readValue( mData, mDataType, index );
818 QgsDebugMsg( QStringLiteral(
"Data block not allocated" ) );
820 return std::numeric_limits<double>::quiet_NaN();
822 if ( index >=
static_cast< qgssize >( mWidth )*mHeight )
824 QgsDebugMsg( QStringLiteral(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg( mWidth ).arg( mHeight ) );
826 return std::numeric_limits<double>::quiet_NaN();
829 const double val = readValue( mData, mDataType, index );
831 if ( !mHasNoDataValue && !mNoDataBitmap )
837 if ( mHasNoDataValue )
839 isNoData = isNoDataValue( val );
843 if ( !mNoDataBitmap )
855 inline bool QgsRasterBlock::isNoDataValue(
double value )
const SIP_SKIP
857 return std::isnan( value ) ||
qgsDoubleNear( value, mNoDataValue );
The Qgis class provides global constants for use throughout the application.
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.
@ 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)
QgsError is container for error messages (report).
QRgb * colorData()
Gives direct read/write access to the raster RGB data.
void setIsData(qgssize index) SIP_HOLDGIL
Remove no data flag on pixel.
bool setValue(qgssize index, double value) SIP_HOLDGIL
Set value on index (indexed line by line)
void setValid(bool valid) SIP_HOLDGIL
Mark block as valid or invalid.
int width() const SIP_HOLDGIL
Returns the width (number of columns) of the raster block.
const quint8 * byteData() const
Gives direct access to the raster block data.
static int typeSize(Qgis::DataType dataType) SIP_HOLDGIL
Returns the size in bytes for the specified dataType.
bool isValid() const SIP_HOLDGIL
Returns true if the block is valid (correctly filled with data).
double valueAndNoData(int row, int column, bool &isNoData) const
Reads a single value from the pixel at row and column, if type of block is numeric.
Qgis::DataType dataType() const SIP_HOLDGIL
Returns data type.
bool isNoData(qgssize row, qgssize column) const SIP_HOLDGIL
Check if value at position is no data.
double value(int row, int column) const SIP_HOLDGIL
Read a single value if type of block is numeric.
QRgb color(int row, int column) const SIP_HOLDGIL
Read a single color.
int dataTypeSize() const SIP_HOLDGIL
Data type size in bytes.
bool hasNoDataValue() const SIP_HOLDGIL
true if the block has no data value.
bool setColor(qgssize index, QRgb color) SIP_HOLDGIL
Set color on index (indexed line by line)
bool setColor(int row, int column, QRgb color) SIP_HOLDGIL
Set color on position.
static void writeValue(void *data, Qgis::DataType type, qgssize index, double value)
bool setIsNoData(qgssize index) SIP_HOLDGIL
Set no data on pixel.
bool isNoData(int row, int column) const SIP_HOLDGIL
Checks if value at position is no data.
bool isNoData(qgssize index) const SIP_HOLDGIL
Check if value at position is no data.
bool hasNoData() const SIP_HOLDGIL
Returns true if the block may contain no data.
bool setValue(int row, int column, double value) SIP_HOLDGIL
Set value on position.
void setError(const QgsError &error)
Sets the last error.
int height() const SIP_HOLDGIL
Returns the height (number of rows) of the raster block.
static double readValue(void *data, Qgis::DataType type, qgssize index)
bool setIsNoData(int row, int column) SIP_HOLDGIL
Set no data on pixel.
QRgb color(qgssize index) const SIP_HOLDGIL
Read a single value.
void setIsData(int row, int column) SIP_HOLDGIL
Remove no data flag on pixel.
A rectangle specified with double values.
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...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QList< QgsRasterRange > QgsRasterRangeList