QGIS API Documentation  3.8.0-Zanzibar (11aff65)
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( QStringLiteral( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
47  QgsDebugMsgLevel( QStringLiteral( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 );
48 
49  std::unique_ptr< QgsRasterBlock > block = qgis::make_unique< 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( QStringLiteral( "Couldn't create raster block" ) );
58  return block.release();
59  }
60 
61  // Read necessary extent only
62  QgsRectangle tmpExtent = extent().intersect( boundingBox );
63 
64  if ( tmpExtent.isEmpty() )
65  {
66  QgsDebugMsg( QStringLiteral( "Extent outside provider extent" ) );
67  block->setIsNoData();
68  return block.release();
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( QStringLiteral( "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( QStringLiteral( "Row or column limits out of range" ) );
115  return block.release();
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( QStringLiteral( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
140  QgsDebugMsgLevel( QStringLiteral( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 );
141 
142  std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), tmpWidth, tmpHeight );
143  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
144  {
145  tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) );
146  }
147 
148  if ( !readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
149  {
150  QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
151  block->setIsNoData();
152  return block.release();
153  }
154 
155  int pixelSize = dataTypeSize( bandNo );
156 
157  double xMin = boundingBox.xMinimum();
158  double yMax = boundingBox.yMaximum();
159  double tmpXMin = tmpExtent.xMinimum();
160  double tmpYMax = tmpExtent.yMaximum();
161 
162  for ( int row = fromRow; row <= toRow; row++ )
163  {
164  double y = yMax - ( row + 0.5 ) * yRes;
165  int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
166 
167  for ( int col = fromCol; col <= toCol; col++ )
168  {
169  double x = xMin + ( col + 0.5 ) * xRes;
170  int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
171 
172  if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
173  {
174  QgsDebugMsg( QStringLiteral( "Source row or column limits out of range" ) );
175  block->setIsNoData(); // so that the problem becomes obvious and fixed
176  return block.release();
177  }
178 
179  qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
180  qgssize index = row * static_cast< qgssize >( width ) + col;
181 
182  char *tmpBits = tmpBlock->bits( tmpIndex );
183  char *bits = block->bits( index );
184  if ( !tmpBits )
185  {
186  QgsDebugMsg( QStringLiteral( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
187  continue;
188  }
189  if ( !bits )
190  {
191  QgsDebugMsg( QStringLiteral( "Cannot set output block data." ) );
192  continue;
193  }
194  memcpy( bits, tmpBits, pixelSize );
195  }
196  }
197  }
198  else
199  {
200  if ( !readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ) )
201  {
202  QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
203  block->setIsNoData();
204  return block.release();
205  }
206  }
207 
208  // apply scale and offset
209  block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
210  // apply user no data values
211  block->applyNoDataValues( userNoDataValues( bandNo ) );
212  return block.release();
213 }
214 
217  , QgsRasterInterface( nullptr )
218 {
219 }
220 
222  : QgsDataProvider( uri, options )
223  , QgsRasterInterface( nullptr )
224 {
225 }
226 
227 QgsRasterDataProvider::ProviderCapabilities QgsRasterDataProvider::providerCapabilities() const
228 {
230 }
231 
232 //
233 //Random Static convenience function
234 //
236 // convenience function for building metadata() HTML table cells
237 
239 {
240  QString s;
241  return s;
242 }
243 
244 // Default implementation for values
245 QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox, int width, int height, int /*dpi*/ )
246 {
247  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
248  QMap<int, QVariant> results;
249 
250  if ( format != QgsRaster::IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
251  {
252  QgsDebugMsg( QStringLiteral( "Format not supported" ) );
253  return QgsRasterIdentifyResult( ERR( tr( "Format not supported" ) ) );
254  }
255 
256  if ( !extent().contains( point ) )
257  {
258  // Outside the raster
259  for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
260  {
261  results.insert( bandNo, QVariant() );
262  }
264  }
265 
266  QgsRectangle finalExtent = boundingBox;
267  if ( finalExtent.isEmpty() )
268  finalExtent = extent();
269 
270  if ( width == 0 )
271  {
272  width = capabilities() & Size ? xSize() : 1000;
273  }
274  if ( height == 0 )
275  {
276  height = capabilities() & Size ? ySize() : 1000;
277  }
278 
279  // Calculate the row / column where the point falls
280  double xres = ( finalExtent.width() ) / width;
281  double yres = ( finalExtent.height() ) / height;
282 
283  int col = static_cast< int >( std::floor( ( point.x() - finalExtent.xMinimum() ) / xres ) );
284  int row = static_cast< int >( std::floor( ( finalExtent.yMaximum() - point.y() ) / yres ) );
285 
286  double xMin = finalExtent.xMinimum() + col * xres;
287  double xMax = xMin + xres;
288  double yMax = finalExtent.yMaximum() - row * yres;
289  double yMin = yMax - yres;
290  QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );
291 
292  for ( int i = 1; i <= bandCount(); i++ )
293  {
294  std::unique_ptr< QgsRasterBlock > bandBlock( block( i, pixelExtent, 1, 1 ) );
295 
296  if ( bandBlock )
297  {
298  double value = bandBlock->value( 0 );
299 
300  results.insert( i, value );
301  }
302  else
303  {
304  results.insert( i, QVariant() );
305  }
306  }
308 }
309 
310 double QgsRasterDataProvider::sample( const QgsPointXY &point, int band,
311  bool *ok, const QgsRectangle &boundingBox, int width, int height, int dpi )
312 {
313  if ( ok )
314  *ok = false;
315 
316  const auto res = identify( point, QgsRaster::IdentifyFormatValue, boundingBox, width, height, dpi );
317  const QVariant value = res.results().value( band );
318 
319  if ( !value.isValid() )
320  return std::numeric_limits<double>::quiet_NaN();
321 
322  if ( ok )
323  *ok = true;
324 
325  return value.toDouble( ok );
326 }
327 
329 {
330  return QStringLiteral( "text/plain" );
331 }
332 
333 bool QgsRasterDataProvider::writeBlock( QgsRasterBlock *block, int band, int xOffset, int yOffset )
334 {
335  if ( !block )
336  return false;
337  if ( !isEditable() )
338  {
339  QgsDebugMsg( QStringLiteral( "writeBlock() called on read-only provider." ) );
340  return false;
341  }
342  return write( block->bits(), band, block->width(), block->height(), xOffset, yOffset );
343 }
344 
345 typedef QList<QPair<QString, QString> > *pyramidResamplingMethods_t();
346 QList<QPair<QString, QString> > QgsRasterDataProvider::pyramidResamplingMethods( const QString &providerKey )
347 {
348  pyramidResamplingMethods_t *pPyramidResamplingMethods = reinterpret_cast< pyramidResamplingMethods_t * >( cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "pyramidResamplingMethods" ) ) );
349  if ( pPyramidResamplingMethods )
350  {
351  QList<QPair<QString, QString> > *methods = pPyramidResamplingMethods();
352  if ( !methods )
353  {
354  QgsDebugMsg( QStringLiteral( "provider pyramidResamplingMethods returned no methods" ) );
355  }
356  else
357  {
358  return *methods;
359  }
360  }
361  else
362  {
363  QgsDebugMsg( QStringLiteral( "Could not resolve pyramidResamplingMethods provider library" ) );
364  }
365  return QList<QPair<QString, QString> >();
366 }
367 
369 {
370  QList<QgsRasterPyramid> myPyramidList = buildPyramidList();
371 
372  if ( myPyramidList.isEmpty() )
373  return false;
374 
375  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
376  for ( myRasterPyramidIterator = myPyramidList.begin();
377  myRasterPyramidIterator != myPyramidList.end();
378  ++myRasterPyramidIterator )
379  {
380  if ( myRasterPyramidIterator->exists )
381  {
382  return true;
383  }
384  }
385  return false;
386 }
387 
389 {
390  if ( bandNo >= mUserNoDataValue.size() )
391  {
392  for ( int i = mUserNoDataValue.size(); i < bandNo; i++ )
393  {
395  }
396  }
397  QgsDebugMsgLevel( QStringLiteral( "set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
398 
399  if ( mUserNoDataValue[bandNo - 1] != noData )
400  {
401  // Clear statistics
402  int i = 0;
403  while ( i < mStatistics.size() )
404  {
405  if ( mStatistics.value( i ).bandNumber == bandNo )
406  {
407  mStatistics.removeAt( i );
408  mHistograms.removeAt( i );
409  }
410  else
411  {
412  i++;
413  }
414  }
415  mUserNoDataValue[bandNo - 1] = noData;
416  }
417 }
418 
419 typedef QgsRasterDataProvider *createFunction_t( const QString &,
420  const QString &, int,
422  int, int, double *,
424  QStringList );
425 
427  const QString &uri,
428  const QString &format, int nBands,
429  Qgis::DataType type,
430  int width, int height, double *geoTransform,
432  const QStringList &createOptions )
433 {
434  createFunction_t *createFn = reinterpret_cast< createFunction_t * >( cast_to_fptr( QgsProviderRegistry::instance()->function( providerKey, "create" ) ) );
435  if ( !createFn )
436  {
437  QgsDebugMsg( "Cannot resolve 'create' function in " + providerKey + " provider" );
438  // TODO: it would be good to return invalid QgsRasterDataProvider
439  // with QgsError set, but QgsRasterDataProvider has pure virtual methods
440  return nullptr;
441  }
442  return createFn( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
443 }
444 
446 {
447  switch ( format )
448  {
450  return QStringLiteral( "Value" );
452  return QStringLiteral( "Text" );
454  return QStringLiteral( "Html" );
456  return QStringLiteral( "Feature" );
457  default:
458  return QStringLiteral( "Undefined" );
459  }
460 }
461 
463 {
464  switch ( format )
465  {
467  return tr( "Value" );
469  return tr( "Text" );
471  return tr( "Html" );
473  return tr( "Feature" );
474  default:
475  return QStringLiteral( "Undefined" );
476  }
477 }
478 
480 {
481  if ( formatName == QLatin1String( "Value" ) ) return QgsRaster::IdentifyFormatValue;
482  if ( formatName == QLatin1String( "Text" ) ) return QgsRaster::IdentifyFormatText;
483  if ( formatName == QLatin1String( "Html" ) ) return QgsRaster::IdentifyFormatHtml;
484  if ( formatName == QLatin1String( "Feature" ) ) return QgsRaster::IdentifyFormatFeature;
486 }
487 
489 {
490  switch ( format )
491  {
493  return IdentifyValue;
495  return IdentifyText;
497  return IdentifyHtml;
499  return IdentifyFeature;
500  default:
501  return NoCapabilities;
502  }
503 }
504 
506 {
507  return QList< double >();
508 }
509 
510 bool QgsRasterDataProvider::userNoDataValuesContains( int bandNo, double value ) const
511 {
512  QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
513  return QgsRasterRange::contains( value, rangeList );
514 }
515 
517 {
518  mDpi = other.mDpi;
523  mExtent = other.mExtent;
524 }
525 
526 // ENDS
bool hasPyramids()
Returns true if raster has at least one populated histogram.
virtual int bandCount() const =0
Gets number of bands.
virtual double sample(const QgsPointXY &point, int band, bool *ok=nullptr, const QgsRectangle &boundingBox=QgsRectangle(), int width=0, int height=0, int dpi=96)
Samples a raster value from the specified band found at the point position.
void setNoDataValue(double noDataValue)
Sets cell value that will be considered as "no data".
IdentifyFormat
Definition: qgsraster.h:57
A rectangle specified with double values.
Definition: qgsrectangle.h:41
void copyBaseSettings(const QgsRasterDataProvider &other)
Copy member variables from other raster data provider. Useful for implementation of clone() method in...
bool contains(double value) const
Returns true if this range contains the specified value.
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:135
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
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:48
A class to represent a 2D point.
Definition: qgspointxy.h:43
int height() const
Returns the height (number of rows) of the raster block.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:265
DataType
Raster data types.
Definition: qgis.h:79
virtual int ySize() const
Capability
If you add to this, please also add to capabilitiesString()
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
Abstract base class for spatial data provider implementations.
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
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)
virtual QString lastErrorFormat()
Returns the format of the error text for the last error in this provider.
Raster identify results container.
int dpi() const
Returns the dpi of the output device.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Raster data container.
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:426
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Returns the raster layers pyramid list.
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
QgsRectangle extent() const override=0
Returns the extent of the layer.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
virtual QList< double > nativeResolutions() const
Returns a list of native resolutions if available, i.e.
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:140
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Definition: qgsrectangle.h:312
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
Gets the data source specification.
QList< bool > mSrcHasNoDataValue
Source no data value exists.
QgsRasterDataProvider()
Provider capabilities.
#define cast_to_fptr(f)
Definition: qgis.h:158
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
Returns 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:596
double x
Definition: qgspointxy.h:47
virtual QString htmlMetadata()=0
Returns metadata in a format suitable for feeding directly into a subset of the GUI raster properties...
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:177
virtual bool readBlock(int bandNo, int xBlock, int yBlock, void *data)
Reads a block of raster data into data.
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:162
QList< QPair< QString, QString > > * pyramidResamplingMethods_t()
QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
Setting options for creating vector data providers.
char * bits(int row, int column)
Returns a pointer to block data.
QList< QgsRasterRange > QgsRasterRangeList
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:145
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.
int dataTypeSize(int bandNo)
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Returns a list of user no data value ranges.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
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
Returns the 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.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
Feedback object tailored for raster block reading.
static QString identifyFormatLabel(QgsRaster::IdentifyFormat format)
virtual int xSize() const
Gets raster size.
#define ERR(message)
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:130
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
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.