QGIS API Documentation  2.99.0-Master (53aba61)
qgsrasterdataprovider.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrasterdataprovider.cpp - DataProvider Interface for raster layers
3  --------------------------------------
4  Date : Mar 11, 2005
5  Copyright : (C) 2005 by Brendan Morley
6  email : morb at ozemail dot com dot au
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 #include "qgsproviderregistry.h"
19 #include "qgsrasterdataprovider.h"
21 #include "qgsrasterprojector.h"
22 #include "qgslogger.h"
23 #include "qgsapplication.h"
24 
25 #include <QTime>
26 #include <QMap>
27 #include <QByteArray>
28 #include <QVariant>
29 
30 #define ERR(message) QgsError(message, "Raster provider")
31 
33 {
34  if ( mUseSrcNoDataValue.size() < bandNo )
35  {
36  for ( int i = mUseSrcNoDataValue.size(); i < bandNo; i++ )
37  {
38  mUseSrcNoDataValue.append( false );
39  }
40  }
41  mUseSrcNoDataValue[bandNo - 1] = use;
42 }
43 
44 QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback )
45 {
46  QgsDebugMsgLevel( QString( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
47  QgsDebugMsgLevel( QString( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 );
48 
49  QgsRasterBlock *block = new QgsRasterBlock( dataType( bandNo ), width, height );
50  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
51  {
52  block->setNoDataValue( sourceNoDataValue( bandNo ) );
53  }
54 
55  if ( block->isEmpty() )
56  {
57  QgsDebugMsg( "Couldn't create raster block" );
58  return block;
59  }
60 
61  // Read necessary extent only
62  QgsRectangle tmpExtent = extent().intersect( &boundingBox );
63 
64  if ( tmpExtent.isEmpty() )
65  {
66  QgsDebugMsg( "Extent outside provider extent" );
67  block->setIsNoData();
68  return block;
69  }
70 
71  double xRes = boundingBox.width() / width;
72  double yRes = boundingBox.height() / height;
73  double tmpXRes, tmpYRes;
74  double providerXRes = 0;
75  double providerYRes = 0;
76  if ( capabilities() & Size )
77  {
78  providerXRes = extent().width() / xSize();
79  providerYRes = extent().height() / ySize();
80  tmpXRes = std::max( providerXRes, xRes );
81  tmpYRes = std::max( providerYRes, yRes );
82  if ( qgsDoubleNear( tmpXRes, xRes ) ) tmpXRes = xRes;
83  if ( qgsDoubleNear( tmpYRes, yRes ) ) tmpYRes = yRes;
84  }
85  else
86  {
87  tmpXRes = xRes;
88  tmpYRes = yRes;
89  }
90 
91  if ( tmpExtent != boundingBox ||
92  tmpXRes > xRes || tmpYRes > yRes )
93  {
94  // Read smaller extent or lower resolution
95 
96  if ( !extent().contains( boundingBox ) )
97  {
98  QRect subRect = QgsRasterBlock::subRect( boundingBox, width, height, extent() );
99  block->setIsNoDataExcept( subRect );
100  }
101 
102  // Calculate row/col limits (before tmpExtent is aligned)
103  int fromRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMaximum() ) / yRes );
104  int toRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1;
105  int fromCol = std::round( ( tmpExtent.xMinimum() - boundingBox.xMinimum() ) / xRes );
106  int toCol = std::round( ( tmpExtent.xMaximum() - boundingBox.xMinimum() ) / xRes ) - 1;
107 
108  QgsDebugMsgLevel( QString( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
109 
110  if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
111  fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
112  {
113  // Should not happen
114  QgsDebugMsg( "Row or column limits out of range" );
115  return block;
116  }
117 
118  // If lower source resolution is used, the extent must beS aligned to original
119  // resolution to avoid possible shift due to resampling
120  if ( tmpXRes > xRes )
121  {
122  int col = std::floor( ( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes );
123  tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes );
124  col = std::ceil( ( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes );
125  tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes );
126  }
127  if ( tmpYRes > yRes )
128  {
129  int row = std::floor( ( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes );
130  tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes );
131  row = std::ceil( ( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes );
132  tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes );
133  }
134  int tmpWidth = std::round( tmpExtent.width() / tmpXRes );
135  int tmpHeight = std::round( tmpExtent.height() / tmpYRes );
136  tmpXRes = tmpExtent.width() / tmpWidth;
137  tmpYRes = tmpExtent.height() / tmpHeight;
138 
139  QgsDebugMsgLevel( QString( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
140  QgsDebugMsgLevel( QString( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 );
141 
142  QgsRasterBlock *tmpBlock = new QgsRasterBlock( dataType( bandNo ), tmpWidth, tmpHeight );
143  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
144  {
145  tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) );
146  }
147 
148  readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback );
149 
150  int pixelSize = dataTypeSize( bandNo );
151 
152  double xMin = boundingBox.xMinimum();
153  double yMax = boundingBox.yMaximum();
154  double tmpXMin = tmpExtent.xMinimum();
155  double tmpYMax = tmpExtent.yMaximum();
156 
157  for ( int row = fromRow; row <= toRow; row++ )
158  {
159  double y = yMax - ( row + 0.5 ) * yRes;
160  int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
161 
162  for ( int col = fromCol; col <= toCol; col++ )
163  {
164  double x = xMin + ( col + 0.5 ) * xRes;
165  int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
166 
167  if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
168  {
169  QgsDebugMsg( "Source row or column limits out of range" );
170  block->setIsNoData(); // so that the problem becomes obvious and fixed
171  delete tmpBlock;
172  return block;
173  }
174 
175  qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
176  qgssize index = row * static_cast< qgssize >( width ) + col;
177 
178  char *tmpBits = tmpBlock->bits( tmpIndex );
179  char *bits = block->bits( index );
180  if ( !tmpBits )
181  {
182  QgsDebugMsg( QString( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
183  continue;
184  }
185  if ( !bits )
186  {
187  QgsDebugMsg( "Cannot set output block data." );
188  continue;
189  }
190  memcpy( bits, tmpBits, pixelSize );
191  }
192  }
193 
194  delete tmpBlock;
195  }
196  else
197  {
198  readBlock( bandNo, boundingBox, width, height, block->bits(), feedback );
199  }
200 
201  // apply scale and offset
202  block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
203  // apply user no data values
204  block->applyNoDataValues( userNoDataValues( bandNo ) );
205  return block;
206 }
207 
209  : QgsRasterInterface( nullptr )
210  , mDpi( -1 )
211 {
212 }
213 
215  : QgsDataProvider( uri )
216  , QgsRasterInterface( nullptr )
217  , mDpi( -1 )
218 {
219 }
220 
221 //
222 //Random Static convenience function
223 //
225 // convenience function for building metadata() HTML table cells
226 // convenience function for creating a string list from a C style string list
227 QStringList QgsRasterDataProvider::cStringList2Q_( char **stringList )
228 {
229  QStringList strings;
230 
231  // presume null terminated string list
232  for ( qgssize i = 0; stringList[i]; ++i )
233  {
234  strings.append( QString::fromUtf8( stringList[i] ) );
235  }
236 
237  return strings;
238 
239 } // cStringList2Q_
240 
241 QString QgsRasterDataProvider::makeTableCell( QString const &value )
242 {
243  return "<p>\n" + value + "</p>\n";
244 } // makeTableCell_
245 
246 // convenience function for building metadata() HTML table cells
247 QString QgsRasterDataProvider::makeTableCells( QStringList const &values )
248 {
249  QString s( QStringLiteral( "<tr>" ) );
250 
251  for ( QStringList::const_iterator i = values.begin();
252  i != values.end();
253  ++i )
254  {
256  }
257 
258  s += QLatin1String( "</tr>" );
259 
260  return s;
261 } // makeTableCell_
262 
264 {
265  QString s;
266  return s;
267 }
268 
269 // Default implementation for values
270 QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox, int width, int height, int /*dpi*/ )
271 {
272  QgsDebugMsgLevel( "Entered", 4 );
273  QMap<int, QVariant> results;
274 
275  if ( format != QgsRaster::IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
276  {
277  QgsDebugMsg( "Format not supported" );
278  return QgsRasterIdentifyResult( ERR( tr( "Format not supported" ) ) );
279  }
280 
281  if ( !extent().contains( point ) )
282  {
283  // Outside the raster
284  for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
285  {
286  results.insert( bandNo, QVariant() );
287  }
289  }
290 
291  QgsRectangle finalExtent = boundingBox;
292  if ( finalExtent.isEmpty() )
293  finalExtent = extent();
294 
295  if ( width == 0 )
296  {
297  width = capabilities() & Size ? xSize() : 1000;
298  }
299  if ( height == 0 )
300  {
301  height = capabilities() & Size ? ySize() : 1000;
302  }
303 
304  // Calculate the row / column where the point falls
305  double xres = ( finalExtent.width() ) / width;
306  double yres = ( finalExtent.height() ) / height;
307 
308  int col = static_cast< int >( std::floor( ( point.x() - finalExtent.xMinimum() ) / xres ) );
309  int row = static_cast< int >( std::floor( ( finalExtent.yMaximum() - point.y() ) / yres ) );
310 
311  double xMin = finalExtent.xMinimum() + col * xres;
312  double xMax = xMin + xres;
313  double yMax = finalExtent.yMaximum() - row * yres;
314  double yMin = yMax - yres;
315  QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );
316 
317  for ( int i = 1; i <= bandCount(); i++ )
318  {
319  QgsRasterBlock *myBlock = block( i, pixelExtent, 1, 1 );
320 
321  if ( myBlock )
322  {
323  double value = myBlock->value( 0 );
324 
325  results.insert( i, value );
326  delete myBlock;
327  }
328  else
329  {
330  results.insert( i, QVariant() );
331  }
332  }
334 }
335 
337 {
338  return QStringLiteral( "text/plain" );
339 }
340 
341 bool QgsRasterDataProvider::writeBlock( QgsRasterBlock *block, int band, int xOffset, int yOffset )
342 {
343  if ( !block )
344  return false;
345  if ( !isEditable() )
346  {
347  QgsDebugMsg( "writeBlock() called on read-only provider." );
348  return false;
349  }
350  return write( block->bits(), band, block->width(), block->height(), xOffset, yOffset );
351 }
352 
353 typedef QList<QPair<QString, QString> > *pyramidResamplingMethods_t();
354 QList<QPair<QString, QString> > QgsRasterDataProvider::pyramidResamplingMethods( const QString &providerKey )
355 {
356  pyramidResamplingMethods_t *pPyramidResamplingMethods = reinterpret_cast< pyramidResamplingMethods_t * >( cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "pyramidResamplingMethods" ) ) );
357  if ( pPyramidResamplingMethods )
358  {
359  QList<QPair<QString, QString> > *methods = pPyramidResamplingMethods();
360  if ( !methods )
361  {
362  QgsDebugMsg( "provider pyramidResamplingMethods returned no methods" );
363  }
364  else
365  {
366  return *methods;
367  }
368  }
369  else
370  {
371  QgsDebugMsg( "Could not resolve pyramidResamplingMethods provider library" );
372  }
373  return QList<QPair<QString, QString> >();
374 }
375 
377 {
378  QList<QgsRasterPyramid> myPyramidList = buildPyramidList();
379 
380  if ( myPyramidList.isEmpty() )
381  return false;
382 
383  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
384  for ( myRasterPyramidIterator = myPyramidList.begin();
385  myRasterPyramidIterator != myPyramidList.end();
386  ++myRasterPyramidIterator )
387  {
388  if ( myRasterPyramidIterator->exists )
389  {
390  return true;
391  }
392  }
393  return false;
394 }
395 
397 {
398  if ( bandNo >= mUserNoDataValue.size() )
399  {
400  for ( int i = mUserNoDataValue.size(); i < bandNo; i++ )
401  {
403  }
404  }
405  QgsDebugMsgLevel( QString( "set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
406 
407  if ( mUserNoDataValue[bandNo - 1] != noData )
408  {
409  // Clear statistics
410  int i = 0;
411  while ( i < mStatistics.size() )
412  {
413  if ( mStatistics.value( i ).bandNumber == bandNo )
414  {
415  mStatistics.removeAt( i );
416  mHistograms.removeAt( i );
417  }
418  else
419  {
420  i++;
421  }
422  }
423  mUserNoDataValue[bandNo - 1] = noData;
424  }
425 }
426 
427 typedef QgsRasterDataProvider *createFunction_t( const QString &,
428  const QString &, int,
430  int, int, double *,
432  QStringList );
433 
435  const QString &uri,
436  const QString &format, int nBands,
437  Qgis::DataType type,
438  int width, int height, double *geoTransform,
440  const QStringList &createOptions )
441 {
442  createFunction_t *createFn = reinterpret_cast< createFunction_t * >( cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "create" ) ) );
443  if ( !createFn )
444  {
445  QgsDebugMsg( "Cannot resolve 'create' function in " + providerKey + " provider" );
446  // TODO: it would be good to return invalid QgsRasterDataProvider
447  // with QgsError set, but QgsRasterDataProvider has pure virtual methods
448  return nullptr;
449  }
450  return createFn( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
451 }
452 
454 {
455  switch ( format )
456  {
458  return QStringLiteral( "Value" );
460  return QStringLiteral( "Text" );
462  return QStringLiteral( "Html" );
464  return QStringLiteral( "Feature" );
465  default:
466  return QStringLiteral( "Undefined" );
467  }
468 }
469 
471 {
472  switch ( format )
473  {
475  return tr( "Value" );
477  return tr( "Text" );
479  return tr( "Html" );
481  return tr( "Feature" );
482  default:
483  return QStringLiteral( "Undefined" );
484  }
485 }
486 
488 {
489  if ( formatName == QLatin1String( "Value" ) ) return QgsRaster::IdentifyFormatValue;
490  if ( formatName == QLatin1String( "Text" ) ) return QgsRaster::IdentifyFormatText;
491  if ( formatName == QLatin1String( "Html" ) ) return QgsRaster::IdentifyFormatHtml;
492  if ( formatName == QLatin1String( "Feature" ) ) return QgsRaster::IdentifyFormatFeature;
494 }
495 
497 {
498  switch ( format )
499  {
501  return IdentifyValue;
503  return IdentifyText;
505  return IdentifyHtml;
507  return IdentifyFeature;
508  default:
509  return NoCapabilities;
510  }
511 }
512 
513 bool QgsRasterDataProvider::userNoDataValuesContains( int bandNo, double value ) const
514 {
515  QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
516  return QgsRasterRange::contains( value, rangeList );
517 }
518 
520 {
521  mDpi = other.mDpi;
526  mExtent = other.mExtent;
527 }
528 
529 // ENDS
virtual QgsRectangle extent() const override=0
Returns the extent of the layer.
bool hasPyramids()
Returns true if raster has at least one populated histogram.
virtual int bandCount() const =0
Get number of bands.
void setNoDataValue(double noDataValue)
Sets cell value that will be considered as "no data".
virtual void readBlock(int bandNo, int xBlock, int yBlock, void *data)
Read block of data.
IdentifyFormat
Definition: qgsraster.h:56
A rectangle specified with double values.
Definition: qgsrectangle.h:38
void copyBaseSettings(const QgsRasterDataProvider &other)
Copy member variables from other raster data provider. Useful for implementation of clone() method in...
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Set source nodata value usage.
static bool contains(double value, const QgsRasterRangeList &rangeList)
Test if value is within the list of ranges.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:75
#define QgsDebugMsg(str)
Definition: qgslogger.h:37
virtual double bandOffset(int bandNo) const
Read band offset for raster value.
bool userNoDataValuesContains(int bandNo, double value) const
Returns true if user no data contains value.
double y
Definition: qgspointxy.h:47
void applyNoDataValues(const QgsRasterRangeList &rangeList)
bool setIsNoDataExcept(QRect exceptRect)
Set the whole block to no data except specified rectangle.
A class to represent a 2D point.
Definition: qgspointxy.h:42
int height() const
Returns the height (number of rows) of the raster block.
static QString makeTableCell(const QString &value)
DataType
Raster data types.
Definition: qgis.h:74
virtual int ySize() const
Capability
If you add to this, please also add to capabilitiesString()
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
QgsRectangle intersect(const QgsRectangle *rect) const
Return the intersection with the given rectangle.
Abstract base class for spatial data provider implementations.
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
Definition: qgis.h:210
static QRect subRect(const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent)
For extent and width, height find rectangle covered by subextent.
static QString identifyFormatName(QgsRaster::IdentifyFormat format)
QgsRasterDataProvider * createFunction_t(const QString &, const QString &, int, Qgis::DataType, int, int, double *, const QgsCoordinateReferenceSystem &, QStringList)
bool setIsNoData(int row, int column)
Set no data on pixel.
virtual QString lastErrorFormat()
Returns the format of the error text for the last error in this provider.
Raster identify results container.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
virtual Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:38
bool isEmpty() const
Returns true if the rectangle is empty.
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Accessor for the raster layers pyramid list.
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:123
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:80
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
QgsDataSourceUri uri() const
Get the data source specification.
QList< bool > mSrcHasNoDataValue
Source no data value exists.
bool isEmpty() const
Returns true if block is empty, i.e.
#define cast_to_fptr(f)
Definition: qgis.h:136
Base class for processing filters like renderers, reprojector, resampler etc.
virtual bool isEditable() const
Checks whether the provider is in editing mode, i.e.
virtual bool sourceHasNoDataValue(int bandNo) const
Return true if source band has no data value.
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:374
double x
Definition: qgspointxy.h:46
QList< double > mSrcNoDataValue
Source no data value is available and is set to be used or internal no data is available.
int width() const
Returns the width (number of columns) of the raster block.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:111
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:96
QList< QPair< QString, QString > > * pyramidResamplingMethods_t()
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
char * bits(int row, int column)
Get pointer to data.
QList< QgsRasterRange > QgsRasterRangeList
void applyScaleOffset(double scale, double offset)
Apply band scale and offset to raster block values.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:85
virtual QString metadata()=0
Get metadata in a format suitable for feeding directly into a subset of the GUI raster properties "Me...
static QString makeTableCells(const QStringList &values)
This class represents a coordinate reference system (CRS).
virtual QgsRasterIdentifyResult identify(const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Identify raster value(s) found on the point position.
double value(int row, int column) const
Read a single value if type of block is numeric.
int dataTypeSize(int bandNo)
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:101
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Get list of user no data value ranges.
static QStringList cStringList2Q_(char **stringList)
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:106
virtual bool write(void *data, int band, int width, int height, int xOffset, int yOffset)
Writes into the provider datasource.
virtual bool useSourceNoDataValue(int bandNo) const
Get source nodata value usage.
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
bool writeBlock(QgsRasterBlock *block, int band, int xOffset=0, int yOffset=0)
Writes pixel data from a raster block into the provider data source.
Feedback object tailored for raster block reading.
static QString identifyFormatLabel(QgsRaster::IdentifyFormat format)
virtual int xSize() const
Get raster size.
#define ERR(message)
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:70
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:130
Base class for raster data providers.
static QgsRasterDataProvider * create(const QString &providerKey, const QString &uri, const QString &format, int nBands, Qgis::DataType type, int width, int height, double *geoTransform, const QgsCoordinateReferenceSystem &crs, const QStringList &createOptions=QStringList())
Creates a new dataset with mDataSourceURI.
QList< QgsRasterRangeList > mUserNoDataValue
List of lists of user defined additional no data values for each band, indexed from 0...
QList< bool > mUseSrcNoDataValue
Use source nodata value.
virtual double bandScale(int bandNo) const
Read band scale for raster value.