28 , mDataType(
QGis::UnknownDataType )
32 , mHasNoDataValue( false )
33 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
37 , mNoDataBitmapWidth( 0 )
38 , mNoDataBitmapSize( 0 )
44 , mDataType( theDataType )
47 , mHeight( theHeight )
48 , mHasNoDataValue( false )
49 , mNoDataValue( std::numeric_limits<double>::quiet_NaN() )
53 , mNoDataBitmapWidth( 0 )
54 , mNoDataBitmapSize( 0 )
61 , mDataType( theDataType )
64 , mHeight( theHeight )
65 , mHasNoDataValue( true )
66 , mNoDataValue( theNoDataValue )
70 , mNoDataBitmapWidth( 0 )
71 , mNoDataBitmapSize( 0 )
86 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3" ).arg( theWidth ).arg( theHeight ).arg( theDataType ) );
87 if ( !
reset( theDataType, theWidth, theHeight, std::numeric_limits<double>::quiet_NaN() ) )
98 QgsDebugMsg( QString(
"theWidth= %1 theHeight = %2 theDataType = %3 theNoDataValue = %4" ).arg( theWidth ).arg( theHeight ).arg( theDataType ).arg( theNoDataValue ) );
111 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
117 size_t tSize =
typeSize( theDataType );
118 QgsDebugMsg( QString(
"allocate %1 bytes" ).arg( tSize * theWidth * theHeight ) );
122 QgsDebugMsg( QString(
"Couldn't allocate data memory of %1 bytes" ).arg( tSize * theWidth * theHeight ) );
129 QImage::Format format =
imageFormat( theDataType );
130 mImage =
new QImage( theWidth, theHeight, format );
153 return QImage::Format_ARGB32;
157 return QImage::Format_ARGB32_Premultiplied;
159 return QImage::Format_Invalid;
164 if ( theFormat == QImage::Format_ARGB32 )
168 else if ( theFormat == QImage::Format_ARGB32_Premultiplied )
244 *noDataValue = -32768.0;
248 *noDataValue = -2147483648.0;
252 *noDataValue = -2147483648.0;
262 QgsDebugMsg( QString(
"Unknow data type %1" ).arg( dataType ) );
266 QgsDebugMsg( QString(
"newDataType = %1 noDataValue = %2" ).arg( newDataType ).arg( *noDataValue ) );
280 if ( qIsNaN( value ) ||
295 int row = floor((
double )index /
mWidth );
296 int column = index %
mWidth;
297 return color( row, column );
302 if ( !
mImage )
return qRgba( 255, 255, 255, 0 );
304 return mImage->pixel( column, row );
312 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
328 int column = index %
mWidth;
330 int bit = column % 8;
331 int mask = 0x80 >> bit;
351 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
376 if ( index >= (
size_t )
mImage->width()*
mImage->height() )
378 QgsDebugMsg( QString(
"index %1 out of range" ).arg( index ) );
410 int column = index %
mWidth;
412 int bit = column % 8;
413 int nodata = 0x80 >> bit;
437 char *nodata = noDataByteArray.data();
440 memcpy((
char* )
mData + i*dataTypeSize, nodata, dataTypeSize );
467 mImage->fill( qRgba( 0, 0, 0, 0 ) );
474 int top = theExceptRect.top();
475 int bottom = theExceptRect.bottom();
476 int left = theExceptRect.left();
477 int right = theExceptRect.right();
478 top = qMin( qMax( top, 0 ),
mHeight - 1 );
479 left = qMin( qMax( left, 0 ),
mWidth - 1 );
480 bottom = qMax( 0, qMin( bottom,
mHeight - 1 ) );
481 right = qMax( 0, qMin( right,
mWidth - 1 ) );
498 char *nodata = noDataByteArray.data();
500 for (
int c = 0; c <
mWidth; c++ )
502 memcpy( nodataRow + c*dataTypeSize, nodata, dataTypeSize );
506 for (
int r = 0; r <
mHeight; r++ )
508 if ( r >= top && r <= bottom )
continue;
509 size_t i = ( size_t )r * mWidth;
510 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*mWidth );
513 for (
int r = top; r <= bottom; r++ )
515 size_t i = ( size_t )r * mWidth;
517 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*left );
520 int w = mWidth - right - 1;
521 memcpy((
char* )
mData + i*dataTypeSize, nodataRow, dataTypeSize*w );
539 for (
int c = 0; c <
mWidth; c ++ )
543 int nodata = 0x80 >> bit;
544 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
548 for (
int r = 0; r <
mHeight; r++ )
550 if ( r >= top && r <= bottom )
continue;
556 for (
int c = 0; c <
mWidth; c ++ )
558 if ( c >= left && c <= right )
continue;
561 int nodata = 0x80 >> bit;
562 memset( nodataRow + byte, nodataRow[byte] | nodata, 1 );
564 for (
int r = top; r <= bottom; r++ )
582 QRgb nodataRgba = qRgba( 0, 0, 0, 0 );
583 QRgb *nodataRow =
new QRgb[
mWidth];
584 int rgbSize =
sizeof( QRgb );
585 for (
int c = 0; c <
mWidth; c ++ )
587 nodataRow[c] = nodataRgba;
591 for (
int r = 0; r <
mHeight; r++ )
593 if ( r >= top && r <= bottom )
continue;
594 size_t i = ( size_t )r * mWidth;
595 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*mWidth );
598 for (
int r = top; r <= bottom; r++ )
602 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*left );
605 int w = mWidth - right;
606 memcpy((
void * )(
mImage->bits() + rgbSize*i ), nodataRow, rgbSize*w );
618 QgsDebugMsg( QString(
"Index %1 out of range (%2 x %3)" ).arg( index ).arg(
mWidth ).arg( mHeight ) );
627 return (
char* )(
mImage->bits() + index * 4 );
642 return (
char* )
mData;
646 return (
char* )(
mImage->bits() );
655 if ( destDataType ==
mDataType )
return true;
673 QImage::Format format =
imageFormat( destDataType );
689 if ( rangeList.isEmpty() )
695 for (
size_t i = 0; i <
size; ++i )
697 double val =
value( i );
721 mImage =
new QImage( *image );
726 mNoDataValue = std::numeric_limits<double>::quiet_NaN();
756 for (
int i = 15; i <= 17; i++ )
758 s.setNum( value,
'g', i );
759 if ( s.toDouble() ==
value )
765 QgsDebugMsg(
"Cannot correctly parse printed value" );
771 int destDataTypeSize =
typeSize( destDataType );
772 void *destData =
qgsMalloc( destDataTypeSize * size );
773 for (
size_t i = 0; i <
size; i++ )
776 writeValue( destData, destDataType, i, value );
787 ba.resize((
int )size );
788 char * data = ba.data();
796 switch ( theDataType )
799 uc = ( quint8 )theValue;
800 memcpy( data, &uc, size );
803 us = ( quint16 )theValue;
804 memcpy( data, &us, size );
807 s = ( qint16 )theValue;
808 memcpy( data, &s, size );
811 ui = ( quint32 )theValue;
812 memcpy( data, &ui, size );
815 i = ( qint32 )theValue;
816 memcpy( data, &i, size );
819 f = ( float )theValue;
820 memcpy( data, &f, size );
823 d = ( double )theValue;
824 memcpy( data, &d, size );
851 double xRes = theExtent.
width() / theWidth;
852 double yRes = theExtent.
height() / theHeight;
854 QgsDebugMsg( QString(
"theWidth = %1 theHeight = %2 xRes = %3 yRes = %4" ).arg( theWidth ).arg( theHeight ).arg( xRes ).arg( yRes ) );
857 int bottom = theHeight - 1;
859 int right = theWidth - 1;
867 bottom = qRound(( theExtent.
yMaximum() - theSubExtent.
yMinimum() ) / yRes ) - 1;
876 right = qRound(( theSubExtent.
xMaximum() - theExtent.
xMinimum() ) / xRes ) - 1;
878 QRect
subRect = QRect( left, top, right - left + 1, bottom - top + 1 );
879 QgsDebugMsg( QString(
"subRect: %1 %2 %3 %4" ).arg( subRect.x() ).arg( subRect.y() ).arg( subRect.width() ).arg( subRect.height() ) );
static QImage::Format imageFormat(QGis::DataType theDataType)
A rectangle specified with double values.
bool convert(QGis::DataType destDataType)
Convert data to different type.
static QString printValue(double value)
Print double value with all necessary significant digits.
void * qgsMalloc(size_t size)
Allocates size bytes and returns a pointer to the allocated memory.
bool setIsNoData()
Set the whole block to no data.
static bool contains(double value, const QgsRasterRangeList &rangeList)
Test if value is within the list of ranges.
double yMaximum() const
Get the y maximum value (top side of rectangle)
static bool typeIsNumeric(QGis::DataType type)
Returns true if data type is numeric.
void applyNoDataValues(const QgsRasterRangeList &rangeList)
bool setValue(int row, int column, double value)
Set value on position.
static void writeValue(void *data, QGis::DataType type, size_t index, double value)
QGis::DataType dataType() const
Returns data type.
The QGis class provides global constants for use throughout the application.
bool isNoData(int row, int column)
Check if value at position is no data.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
bool setColor(int row, int column, QRgb color)
Set color on position.
virtual ~QgsRasterBlock()
static QGis::DataType typeWithNoDataValue(QGis::DataType dataType, double *noDataValue)
For given data type returns wider type and sets no data value.
bool setIsNoDataExcept(const QRect &theExceptRect)
Set the whole block to no data except specified rectangle.
bool hasNoData() const
Returns true if the block may contain no data.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double xMaximum() const
Get the x maximum value (right side of rectangle)
bool setImage(const QImage *image)
set image.
double value(int row, int column) const
Read a single value if type of block is numeric.
static bool isNoDataValue(double value, double noDataValue)
Test if value is nodata comparing to noDataValue.
static bool typeIsColor(QGis::DataType type)
Returns true if data type is color.
char * bits()
Get pointer to data.
static int typeSize(int dataType)
static double readValue(void *data, QGis::DataType type, size_t index)
bool reset(QGis::DataType theDataType, int theWidth, int theHeight)
Reset block.
QList< QgsRasterRange > QgsRasterRangeList
static QByteArray valueBytes(QGis::DataType theDataType, double theValue)
Get byte array representing a value.
DataType
Raster data types.
QImage image() const
Get image if type is color.
QRgb color(int row, int column) const
Read a single color.
bool createNoDataBitmap()
Allocate no data bitmap.
static QRect subRect(const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent)
For theExtent and theWidht, theHeight find rectangle covered by subextent.
double width() const
Width of the rectangle.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
double xMinimum() const
Get the x minimum value (left side of rectangle)
void qgsFree(void *ptr)
Frees the memory space pointed to by ptr.
double height() const
Height of the rectangle.
bool isEmpty() const
Returns true if block is empty, i.e.