QGIS API Documentation  2.3.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 
295  QgsError error() const { return mError; }
296 
298  void setError( const QgsError & theError ) { mError = theError;}
299 
309  static QRect subRect( const QgsRectangle &theExtent, int theWidth, int theHeight, const QgsRectangle &theSubExtent );
310 
311  private:
312  static QImage::Format imageFormat( QGis::DataType theDataType );
313  static QGis::DataType dataType( QImage::Format theFormat );
314 
319  static bool isNoDataValue( double value, double noDataValue );
320 
324  bool isNoDataValue( double value ) const;
325 
328  bool createNoDataBitmap();
329 
337  static void * convert( void *srcData, QGis::DataType srcDataType, QGis::DataType destDataType, qgssize size );
338 
339  // Valid
340  bool mValid;
341 
342  // Data type
344 
345  // Data type size in bytes, to make bits() fast
347 
348  // Width
349  int mWidth;
350 
351  // Height
352  int mHeight;
353 
354  // Has no data value
356 
357  // No data value
358  double mNoDataValue;
359 
360  static const QRgb mNoDataColor;
361 
362  // Data block for numerical data types, not used with image data types
363  // QByteArray does not seem to be intended for large data blocks, does it?
364  void * mData;
365 
366  // Image for image data types, not used with numerical data types
367  QImage *mImage;
368 
369  // Bitmap of no data. One bit for each pixel. Bit is 1 if a pixels is no data.
370  // Each row is represented by whole number of bytes (last bits may be unused)
371  // to make processing rows easy.
373 
374  // number of bytes in mNoDataBitmap row
376 
377  // total size in bytes of mNoDataBitmap
379 
380  // Error
382 };
383 
384 inline double QgsRasterBlock::readValue( void *data, QGis::DataType type, qgssize index )
385 {
386  if ( !data )
387  {
388  return std::numeric_limits<double>::quiet_NaN();
389  }
390 
391  switch ( type )
392  {
393  case QGis::Byte:
394  return ( double )(( quint8 * )data )[index];
395  break;
396  case QGis::UInt16:
397  return ( double )(( quint16 * )data )[index];
398  break;
399  case QGis::Int16:
400  return ( double )(( qint16 * )data )[index];
401  break;
402  case QGis::UInt32:
403  return ( double )(( quint32 * )data )[index];
404  break;
405  case QGis::Int32:
406  return ( double )(( qint32 * )data )[index];
407  break;
408  case QGis::Float32:
409  return ( double )(( float * )data )[index];
410  break;
411  case QGis::Float64:
412  return ( double )(( double * )data )[index];
413  break;
414  default:
415  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
416  break;
417  }
418 
419  return std::numeric_limits<double>::quiet_NaN();
420 }
421 
422 inline void QgsRasterBlock::writeValue( void *data, QGis::DataType type, qgssize index, double value )
423 {
424  if ( !data ) return;
425 
426  switch ( type )
427  {
428  case QGis::Byte:
429  (( quint8 * )data )[index] = ( quint8 ) value;
430  break;
431  case QGis::UInt16:
432  (( quint16 * )data )[index] = ( quint16 ) value;
433  break;
434  case QGis::Int16:
435  (( qint16 * )data )[index] = ( qint16 ) value;
436  break;
437  case QGis::UInt32:
438  (( quint32 * )data )[index] = ( quint32 ) value;
439  break;
440  case QGis::Int32:
441  (( qint32 * )data )[index] = ( qint32 ) value;
442  break;
443  case QGis::Float32:
444  (( float * )data )[index] = ( float ) value;
445  break;
446  case QGis::Float64:
447  (( double * )data )[index] = value;
448  break;
449  default:
450  QgsDebugMsg( QString( "Data type %1 is not supported" ).arg( type ) );
451  break;
452  }
453 }
454 
455 inline double QgsRasterBlock::value( qgssize index ) const
456 {
457  if ( !mData )
458  {
459  QgsDebugMsg( "Data block not allocated" );
460  return std::numeric_limits<double>::quiet_NaN();
461  }
462  return readValue( mData, mDataType, index );
463 }
464 
465 inline bool QgsRasterBlock::isNoDataValue( double value ) const
466 {
467  return qIsNaN( value ) || qgsDoubleNear( value, mNoDataValue );
468 }
469 
470 #endif
471 
472 
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