QGIS API Documentation  2.5.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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( const QRect & theExceptRect );
244 
251  char * bits( int row, int column );
252 
258  char * bits( qgssize index );
259 
264  char * bits();
265 
270  static QString printValue( double value );
271 
275  bool convert( QGis::DataType destDataType );
276 
279  QImage image() const;
280 
284  bool setImage( const QImage * image );
285 
286  // @note not available in python bindings
287  inline static double readValue( void *data, QGis::DataType type, qgssize index );
288 
289  // @note not available in python bindings
290  inline static void writeValue( void *data, QGis::DataType type, qgssize index, double value );
291 
292  void applyNoDataValues( const QgsRasterRangeList & rangeList );
293 
296  void applyScaleOffset( double scale, double offset );
297 
299  QgsError error() const { return mError; }
300 
302  void setError( const QgsError & theError ) { mError = theError;}
303 
313  static QRect subRect( const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent );
314 
315  private:
316  static QImage::Format imageFormat( QGis::DataType theDataType );
317  static QGis::DataType dataType( QImage::Format theFormat );
318 
323  static bool isNoDataValue( double value, double noDataValue );
324 
328  bool isNoDataValue( double value ) const;
329 
332  bool createNoDataBitmap();
333 
341  static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, qgssize size );
342 
343  // Valid
344  bool mValid;
345 
346  // Data type
348 
349  // Data type size in bytes, to make bits() fast
351 
352  // Width
353  int mWidth;
354 
355  // Height
356  int mHeight;
357 
358  // Has no data value
360 
361  // No data value
362  double mNoDataValue;
363 
364  static const QRgb mNoDataColor;
365 
366  // Data block for numerical data types, not used with image data types
367  // QByteArray does not seem to be intended for large data blocks, does it?
368  void * mData;
369 
370  // Image for image data types, not used with numerical data types
371  QImage *mImage;
372 
373  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
374  // Each row is represented by whole number of bytes (last bits may be unused)
375  // to make processing rows easy.
377 
378  // number of bytes in mNoDataBitmap row
380 
381  // total size in bytes of mNoDataBitmap
383 
384  // Error
386 };
387 
388 inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, qgssize index )
389 {
390  if ( !data )
391  {
392  return std::numeric_limits<double>::quiet_NaN();
393  }
394 
395  switch ( type )
396  {
397  case QGis::Byte:
398  return ( double )(( quint8 * )data )[index];
399  break;
400  case QGis::UInt16:
401  return ( double )(( quint16 * )data )[index];
402  break;
403  case QGis::Int16:
404  return ( double )(( qint16 * )data )[index];
405  break;
406  case QGis::UInt32:
407  return ( double )(( quint32 * )data )[index];
408  break;
409  case QGis::Int32:
410  return ( double )(( qint32 * )data )[index];
411  break;
412  case QGis::Float32:
413  return ( double )(( float * )data )[index];
414  break;
415  case QGis::Float64:
416  return ( double )(( double * )data )[index];
417  break;
418  default:
419  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
420  break;
421  }
422 
423  return std::numeric_limits<double>::quiet_NaN();
424 }
425 
426 inline void QgsRasterBlock::writeValue( void *data, QGis::DataType type, qgssize index, double value )
427 {
428  if ( !data ) return;
429 
430  switch ( type )
431  {
432  case QGis::Byte:
433  (( quint8 * )data )[index] = ( quint8 ) value;
434  break;
435  case QGis::UInt16:
436  (( quint16 * )data )[index] = ( quint16 ) value;
437  break;
438  case QGis::Int16:
439  (( qint16 * )data )[index] = ( qint16 ) value;
440  break;
441  case QGis::UInt32:
442  (( quint32 * )data )[index] = ( quint32 ) value;
443  break;
444  case QGis::Int32:
445  (( qint32 * )data )[index] = ( qint32 ) value;
446  break;
447  case QGis::Float32:
448  (( float * )data )[index] = ( float ) value;
449  break;
450  case QGis::Float64:
451  (( double * )data )[index] = value;
452  break;
453  default:
454  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
455  break;
456  }
457 }
458 
459 inline double QgsRasterBlock::value( qgssize index ) const
460 {
461  if ( !mData )
462  {
463  QgsDebugMsg( "Data block not allocated" );
464  return std::numeric_limits<double>::quiet_NaN();
465  }
466  return readValue( mData, mDataType, index );
467 }
468 
469 inline bool QgsRasterBlock::isNoDataValue( double value ) const
470 {
471  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
472 }
473 
474 #endif
475 
476 
static const QRgb mNoDataColor
static unsigned index
A rectangle specified with double values.
Definition: qgsrectangle.h:35
bool isValid() const
Returns true if the block is valid (correctly filled with data).
void setError(const QgsError &theError)
Set error.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
double noDataValue() const
Return no data value.
QGis::DataType dataType() const
Returns data type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:324
Raster data container.
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 int typeSize(int dataType)
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:424
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.
QList< QgsRasterRange > QgsRasterRangeList
QgsError is container for error messages (report).
Definition: qgserror.h:77
DataType
Raster data types.
Definition: qgis.h:204
QGis::DataType mDataType
qgssize mNoDataBitmapSize
static double readValue(void *data, QGis::DataType type, qgssize index)
QgsError error() const
Get error.
double size
Definition: qgssvgcache.cpp:77