QGIS API Documentation  2.17.0-Master (eef6f05)
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
void setError(const QgsError &theError)
Set error.
bool isValid() const
Returns true if the block is valid (correctly filled with data).
Complex Float32.
Definition: qgis.h:145
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
int height() const
Returns the height (number of rows) of the raster block.
Complex Int32.
Definition: qgis.h:144
Thirty two bit floating point (float)
Definition: qgis.h:141
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:353
QgsError error() const
Get error.
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
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 width() const
Returns the width (number of columns) of the raster block.
static void writeValue(void *data, QGis::DataType type, qgssize index, double value)
void setValid(bool valid)
Mark block as valid or invalid.
QGis::DataType dataType() const
Returns data type.
QgsError is container for error messages (report).
Definition: qgserror.h:80
DataType
Raster data types.
Definition: qgis.h:133
double value(int row, int column) const
Read a single value if type of block is numeric.
bool hasNoDataValue() const
True if the block has no data value.
int dataTypeSize() const
static double readValue(void *data, QGis::DataType type, qgssize index)
double noDataValue() const
Return no data value.
Complex Int16.
Definition: qgis.h:143
Complex Float64.
Definition: qgis.h:146