QGIS API Documentation  2.17.0-Master (973e4b0)
qgsrasterblock.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterblock.h - Class representing a block of raster data
3  --------------------------------------
4  Date : Oct 9, 2012
5  Copyright : (C) 2012 by Radim Blazek
6  email : radim dot blazek at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #ifndef QGSRASTERBLOCK_H
19 #define QGSRASTERBLOCK_H
20 
21 #include <limits>
22 #include <QImage>
23 #include "qgis.h"
24 #include "qgserror.h"
25 #include "qgslogger.h"
26 #include "qgsrasterrange.h"
27 #include "qgsrectangle.h"
28 
32 class CORE_EXPORT QgsRasterBlock
33 {
34  public:
36 
43  QgsRasterBlock( QGis::DataType theDataType, int theWidth, int theHeight );
44 
51  QgsRasterBlock( QGis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
52 
53  virtual ~QgsRasterBlock();
54 
62  bool reset( QGis::DataType theDataType, int theWidth, int theHeight );
63 
71  bool reset( QGis::DataType theDataType, int theWidth, int theHeight, double theNoDataValue );
72 
73  // TODO: consider if use isValid() at all, isEmpty() should be sufficient
74  // and works also if block is valid but empty - difference between valid and empty?
79  bool isValid() const { return mValid; }
80 
82  void setValid( bool valid ) { mValid = valid; }
83 
88  bool isEmpty() const;
89 
90  // Return data type size in bytes
91  static int typeSize( int dataType )
92  {
93  // Modified and extended copy from GDAL
94  switch ( dataType )
95  {
96  case QGis::Byte:
97  return 1;
98 
99  case QGis::UInt16:
100  case QGis::Int16:
101  return 2;
102 
103  case QGis::UInt32:
104  case QGis::Int32:
105  case QGis::Float32:
106  case QGis::CInt16:
107  return 4;
108 
109  case QGis::Float64:
110  case QGis::CInt32:
111  case QGis::CFloat32:
112  return 8;
113 
114  case QGis::CFloat64:
115  return 16;
116 
117  case QGis::ARGB32:
119  return 4;
120 
121  default:
122  return 0;
123  }
124  }
125 
126  // Data type in bytes
127  int dataTypeSize() const
128  {
129  return typeSize( mDataType );
130  }
131 
133  static bool typeIsNumeric( QGis::DataType type );
134 
136  static bool typeIsColor( QGis::DataType type );
137 
139  QGis::DataType dataType() const { return mDataType; }
140 
142  static QGis::DataType typeWithNoDataValue( QGis::DataType dataType, double *noDataValue );
143 
146  bool hasNoDataValue() const { return mHasNoDataValue; }
147 
152  bool hasNoData() const;
153 
157  double noDataValue() const { return mNoDataValue; }
158 
163  static QByteArray valueBytes( QGis::DataType theDataType, double theValue );
164 
170  double value( int row, int column ) const;
171 
176  double value( qgssize index ) const;
177 
182  QRgb color( int row, int column ) const;
183 
187  QRgb color( qgssize index ) const;
188 
193  bool isNoData( int row, int column );
194 
198  bool isNoData( qgssize index );
199 
205  bool setValue( int row, int column, double value );
206 
211  bool setValue( qgssize index, double value );
212 
218  bool setColor( int row, int column, QRgb color );
219 
224  bool setColor( qgssize index, QRgb color );
225 
230  bool setIsNoData( int row, int column );
231 
235  bool setIsNoData( qgssize index );
236 
239  bool setIsNoData();
240 
243  bool setIsNoDataExcept( QRect theExceptRect );
244 
252  void setIsData( int row, int column );
253 
260  void setIsData( qgssize index );
261 
268  char * bits( int row, int column );
269 
275  char * bits( qgssize index );
276 
281  char * bits();
282 
287  static QString printValue( double value );
288 
296  static QString printValue( float value );
297 
301  bool convert( QGis::DataType destDataType );
302 
305  QImage image() const;
306 
310  bool setImage( const QImage * image );
311 
313  inline static double readValue( void *data, QGis::DataType type, qgssize index );
314 
316  inline static void writeValue( void *data, QGis::DataType type, qgssize index, double value );
317 
318  void applyNoDataValues( const QgsRasterRangeList & rangeList );
319 
322  void applyScaleOffset( double scale, double offset );
323 
325  QgsError error() const { return mError; }
326 
328  void setError( const QgsError & theError ) { mError = theError;}
329 
330  QString toString() const;
331 
341  static QRect subRect( const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent );
342 
347  int width() const { return mWidth; }
348 
353  int height() const { return mHeight; }
354 
355  private:
356  static QImage::Format imageFormat( QGis::DataType theDataType );
357  static QGis::DataType dataType( QImage::Format theFormat );
358 
363  static bool isNoDataValue( double value, double noDataValue );
364 
368  bool isNoDataValue( double value ) const;
369 
372  bool createNoDataBitmap();
373 
381  static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, qgssize size );
382 
383  // Valid
384  bool mValid;
385 
386  // Data type
387  QGis::DataType mDataType;
388 
389  // Data type size in bytes, to make bits() fast
390  int mTypeSize;
391 
392  // Width
393  int mWidth;
394 
395  // Height
396  int mHeight;
397 
398  // Has no data value
399  bool mHasNoDataValue;
400 
401  // No data value
402  double mNoDataValue;
403 
404  static const QRgb mNoDataColor;
405 
406  // Data block for numerical data types, not used with image data types
407  // QByteArray does not seem to be intended for large data blocks, does it?
408  void * mData;
409 
410  // Image for image data types, not used with numerical data types
411  QImage *mImage;
412 
413  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
414  // Each row is represented by whole number of bytes (last bits may be unused)
415  // to make processing rows easy.
416  char *mNoDataBitmap;
417 
418  // number of bytes in mNoDataBitmap row
419  int mNoDataBitmapWidth;
420 
421  // total size in bytes of mNoDataBitmap
422  qgssize mNoDataBitmapSize;
423 
424  // Error
425  QgsError mError;
426 };
427 
428 inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, qgssize index )
429 {
430  if ( !data )
431  {
432  return std::numeric_limits<double>::quiet_NaN();
433  }
434 
435  switch ( type )
436  {
437  case QGis::Byte:
438  return static_cast< double >(( static_cast< quint8 * >( data ) )[index] );
439  break;
440  case QGis::UInt16:
441  return static_cast< double >(( static_cast< quint16 * >( data ) )[index] );
442  break;
443  case QGis::Int16:
444  return static_cast< double >(( static_cast< qint16 * >( data ) )[index] );
445  break;
446  case QGis::UInt32:
447  return static_cast< double >(( static_cast< quint32 * >( data ) )[index] );
448  break;
449  case QGis::Int32:
450  return static_cast< double >(( static_cast< qint32 * >( data ) )[index] );
451  break;
452  case QGis::Float32:
453  return static_cast< double >(( static_cast< float * >( data ) )[index] );
454  break;
455  case QGis::Float64:
456  return static_cast< double >(( static_cast< double * >( data ) )[index] );
457  break;
458  default:
459  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
460  break;
461  }
462 
463  return std::numeric_limits<double>::quiet_NaN();
464 }
465 
466 inline void QgsRasterBlock::writeValue( void *data, QGis::DataType type, qgssize index, double value )
467 {
468  if ( !data ) return;
469 
470  switch ( type )
471  {
472  case QGis::Byte:
473  ( static_cast< quint8 * >( data ) )[index] = static_cast< quint8 >( value );
474  break;
475  case QGis::UInt16:
476  ( static_cast< quint16 * >( data ) )[index] = static_cast< quint16 >( value );
477  break;
478  case QGis::Int16:
479  ( static_cast< qint16 * >( data ) )[index] = static_cast< qint16 >( value );
480  break;
481  case QGis::UInt32:
482  ( static_cast< quint32 * >( data ) )[index] = static_cast< quint32 >( value );
483  break;
484  case QGis::Int32:
485  ( static_cast< qint32 * >( data ) )[index] = static_cast< qint32 >( value );
486  break;
487  case QGis::Float32:
488  ( static_cast< float * >( data ) )[index] = static_cast< float >( value );
489  break;
490  case QGis::Float64:
491  ( static_cast< double * >( data ) )[index] = value;
492  break;
493  default:
494  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
495  break;
496  }
497 }
498 
499 inline double QgsRasterBlock::value( qgssize index ) const
500 {
501  if ( !mData )
502  {
503  QgsDebugMsg( "Data block not allocated" );
504  return std::numeric_limits<double>::quiet_NaN();
505  }
506  return readValue( mData, mDataType, index );
507 }
508 
509 inline bool QgsRasterBlock::isNoDataValue( double value ) const
510 {
511  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
512 }
513 
514 #endif
515 
516 
Eight bit unsigned integer (quint8)
Definition: qgis.h:136
static unsigned index
A rectangle specified with double values.
Definition: qgsrectangle.h:35
int height() const
Returns the height (number of rows) of the raster block.
bool isValid() const
Returns true if the block is valid (correctly filled with data).
void setError(const QgsError &theError)
Set error.
Complex Float32.
Definition: qgis.h:145
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
double noDataValue() const
Return no data value.
Complex Int32.
Definition: qgis.h:144
int width() const
Returns the width (number of columns) of the raster block.
Thirty two bit floating point (float)
Definition: qgis.h:141
QGis::DataType dataType() const
Returns data type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
Sixteen bit unsigned integer (quint16)
Definition: qgis.h:137
Sixty four bit floating point (double)
Definition: qgis.h:142
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32_Premultiplied.
Definition: qgis.h:150
Raster data container.
Thirty two bit signed integer (qint32)
Definition: qgis.h:140
double value(int row, int column) const
Read a single value if type of block is numeric.
Thirty two bit unsigned integer (quint32)
Definition: qgis.h:139
Color, alpha, red, green, blue, 4 bytes the same as QImage::Format_ARGB32.
Definition: qgis.h:148
static int typeSize(int dataType)
Sixteen bit signed integer (qint16)
Definition: qgis.h:138
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...
Definition: qgis.h:500
int dataTypeSize() const
static void writeValue(void *data, QGis::DataType type, qgssize index, double value)
void setValid(bool valid)
Mark block as valid or invalid.
bool hasNoDataValue() const
True if the block has no data value.
QgsError is container for error messages (report).
Definition: qgserror.h:80
DataType
Raster data types.
Definition: qgis.h:133
static double readValue(void *data, QGis::DataType type, qgssize index)
QgsError error() const
Get error.
Complex Int16.
Definition: qgis.h:143
Complex Float64.
Definition: qgis.h:146