QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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 "qgsprovidermetadata.h"
22 #include "qgsrasterprojector.h"
23 #include "qgslogger.h"
24 #include "qgsmessagelog.h"
25 #include "qgsapplication.h"
26 
27 #include <QTime>
28 #include <QMap>
29 #include <QByteArray>
30 #include <QVariant>
31 
32 #define ERR(message) QgsError(message, "Raster provider")
33 
35 {
36  if ( mUseSrcNoDataValue.size() < bandNo )
37  {
38  for ( int i = mUseSrcNoDataValue.size(); i < bandNo; i++ )
39  {
40  mUseSrcNoDataValue.append( false );
41  }
42  }
43  mUseSrcNoDataValue[bandNo - 1] = use;
44 }
45 
46 QgsRasterBlock *QgsRasterDataProvider::block( int bandNo, QgsRectangle const &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback )
47 {
48  QgsDebugMsgLevel( QStringLiteral( "bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
49  QgsDebugMsgLevel( QStringLiteral( "boundingBox = %1" ).arg( boundingBox.toString() ), 4 );
50 
51  std::unique_ptr< QgsRasterBlock > block = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), width, height );
52  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
53  {
55  }
56 
57  if ( block->isEmpty() )
58  {
59  QgsDebugMsg( QStringLiteral( "Couldn't create raster block" ) );
60  block->setError( { tr( "Couldn't create raster block." ), QStringLiteral( "Raster" ) } );
61  block->setValid( false );
62  return block.release();
63  }
64 
65  // Read necessary extent only
66  QgsRectangle tmpExtent = boundingBox;
67 
68  if ( tmpExtent.isEmpty() )
69  {
70  QgsDebugMsg( QStringLiteral( "Extent outside provider extent" ) );
71  block->setError( { tr( "Extent outside provider extent." ), QStringLiteral( "Raster" ) } );
72  block->setValid( false );
73  block->setIsNoData();
74  return block.release();
75  }
76 
77  double xRes = boundingBox.width() / width;
78  double yRes = boundingBox.height() / height;
79  double tmpXRes, tmpYRes;
80  double providerXRes = 0;
81  double providerYRes = 0;
82  if ( capabilities() & Size )
83  {
84  providerXRes = extent().width() / xSize();
85  providerYRes = extent().height() / ySize();
86  tmpXRes = std::max( providerXRes, xRes );
87  tmpYRes = std::max( providerYRes, yRes );
88  if ( qgsDoubleNear( tmpXRes, xRes ) ) tmpXRes = xRes;
89  if ( qgsDoubleNear( tmpYRes, yRes ) ) tmpYRes = yRes;
90  }
91  else
92  {
93  tmpXRes = xRes;
94  tmpYRes = yRes;
95  }
96 
97  if ( tmpExtent != boundingBox ||
98  tmpXRes > xRes || tmpYRes > yRes )
99  {
100  // Read smaller extent or lower resolution
101 
102  if ( !extent().contains( boundingBox ) )
103  {
104  QRect subRect = QgsRasterBlock::subRect( boundingBox, width, height, extent() );
105  block->setIsNoDataExcept( subRect );
106  }
107 
108  // Calculate row/col limits (before tmpExtent is aligned)
109  int fromRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMaximum() ) / yRes );
110  int toRow = std::round( ( boundingBox.yMaximum() - tmpExtent.yMinimum() ) / yRes ) - 1;
111  int fromCol = std::round( ( tmpExtent.xMinimum() - boundingBox.xMinimum() ) / xRes );
112  int toCol = std::round( ( tmpExtent.xMaximum() - boundingBox.xMinimum() ) / xRes ) - 1;
113 
114  QgsDebugMsgLevel( QStringLiteral( "fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
115 
116  if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
117  fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
118  {
119  // Should not happen
120  QgsDebugMsg( QStringLiteral( "Row or column limits out of range" ) );
121  block->setError( { tr( "Row or column limits out of range" ), QStringLiteral( "Raster" ) } );
122  block->setValid( false );
123  return block.release();
124  }
125 
126  // If lower source resolution is used, the extent must be aligned to original
127  // resolution to avoid possible shift due to resampling
128  if ( tmpXRes > xRes )
129  {
130  int col = std::floor( ( tmpExtent.xMinimum() - extent().xMinimum() ) / providerXRes );
131  tmpExtent.setXMinimum( extent().xMinimum() + col * providerXRes );
132  col = std::ceil( ( tmpExtent.xMaximum() - extent().xMinimum() ) / providerXRes );
133  tmpExtent.setXMaximum( extent().xMinimum() + col * providerXRes );
134  }
135  if ( tmpYRes > yRes )
136  {
137  int row = std::floor( ( extent().yMaximum() - tmpExtent.yMaximum() ) / providerYRes );
138  tmpExtent.setYMaximum( extent().yMaximum() - row * providerYRes );
139  row = std::ceil( ( extent().yMaximum() - tmpExtent.yMinimum() ) / providerYRes );
140  tmpExtent.setYMinimum( extent().yMaximum() - row * providerYRes );
141  }
142  int tmpWidth = std::round( tmpExtent.width() / tmpXRes );
143  int tmpHeight = std::round( tmpExtent.height() / tmpYRes );
144  tmpXRes = tmpExtent.width() / tmpWidth;
145  tmpYRes = tmpExtent.height() / tmpHeight;
146 
147  QgsDebugMsgLevel( QStringLiteral( "Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
148  QgsDebugMsgLevel( QStringLiteral( "tmpExtent = %1" ).arg( tmpExtent.toString() ), 4 );
149 
150  std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >( dataType( bandNo ), tmpWidth, tmpHeight );
151  if ( sourceHasNoDataValue( bandNo ) && useSourceNoDataValue( bandNo ) )
152  {
153  tmpBlock->setNoDataValue( sourceNoDataValue( bandNo ) );
154  }
155 
156  if ( !readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
157  {
158  QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
159  block->setError( { tr( "Error occurred while reading block." ), QStringLiteral( "Raster" ) } );
160  block->setValid( false );
161  block->setIsNoData();
162  return block.release();
163  }
164 
165  int pixelSize = dataTypeSize( bandNo );
166 
167  double xMin = boundingBox.xMinimum();
168  double yMax = boundingBox.yMaximum();
169  double tmpXMin = tmpExtent.xMinimum();
170  double tmpYMax = tmpExtent.yMaximum();
171 
172  for ( int row = fromRow; row <= toRow; row++ )
173  {
174  double y = yMax - ( row + 0.5 ) * yRes;
175  int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
176 
177  for ( int col = fromCol; col <= toCol; col++ )
178  {
179  double x = xMin + ( col + 0.5 ) * xRes;
180  int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
181 
182  if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
183  {
184  QgsDebugMsg( QStringLiteral( "Source row or column limits out of range" ) );
185  block->setIsNoData(); // so that the problem becomes obvious and fixed
186  block->setError( { tr( "Source row or column limits out of range." ), QStringLiteral( "Raster" ) } );
187  block->setValid( false );
188  return block.release();
189  }
190 
191  qgssize tmpIndex = static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
192  qgssize index = row * static_cast< qgssize >( width ) + col;
193 
194  char *tmpBits = tmpBlock->bits( tmpIndex );
195  char *bits = block->bits( index );
196  if ( !tmpBits )
197  {
198  QgsDebugMsg( QStringLiteral( "Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
199  continue;
200  }
201  if ( !bits )
202  {
203  QgsDebugMsg( QStringLiteral( "Cannot set output block data." ) );
204  continue;
205  }
206  memcpy( bits, tmpBits, pixelSize );
207  }
208  }
209  }
210  else
211  {
212  if ( !readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ) )
213  {
214  QgsDebugMsg( QStringLiteral( "Error occurred while reading block" ) );
215  block->setIsNoData();
216  block->setError( { tr( "Error occurred while reading block." ), QStringLiteral( "Raster" ) } );
217  block->setValid( false );
218  return block.release();
219  }
220  }
221 
222  // apply scale and offset
223  block->applyScaleOffset( bandScale( bandNo ), bandOffset( bandNo ) );
224  // apply user no data values
226  return block.release();
227 }
228 
230  : QgsDataProvider( QString(), QgsDataProvider::ProviderOptions(), QgsDataProvider::ReadFlags() )
231  , QgsRasterInterface( nullptr )
232  , mTemporalCapabilities( qgis::make_unique< QgsRasterDataProviderTemporalCapabilities >() )
233 {
234 
235 }
236 
238  QgsDataProvider::ReadFlags flags )
239  : QgsDataProvider( uri, options, flags )
240  , QgsRasterInterface( nullptr )
241  , mTemporalCapabilities( qgis::make_unique< QgsRasterDataProviderTemporalCapabilities >() )
242 {
243 }
244 
245 QgsRasterDataProvider::ProviderCapabilities QgsRasterDataProvider::providerCapabilities() const
246 {
248 }
249 
251 {
252  Q_UNUSED( bandNo )
254 }
255 
256 //
257 //Random Static convenience function
258 //
260 
261 // TODO
262 // (WMS) IdentifyFormatFeature is not consistent with QgsRaster::IdentifyFormatValue.
263 // IdentifyFormatHtml: better error reporting
264 QgsRasterIdentifyResult QgsRasterDataProvider::identify( const QgsPointXY &point, QgsRaster::IdentifyFormat format, const QgsRectangle &boundingBox, int width, int height, int /*dpi*/ )
265 {
266  QgsDebugMsgLevel( QStringLiteral( "Entered" ), 4 );
267  QMap<int, QVariant> results;
268 
269  if ( format != QgsRaster::IdentifyFormatValue || !( capabilities() & IdentifyValue ) )
270  {
271  QgsDebugMsg( QStringLiteral( "Format not supported" ) );
272  return QgsRasterIdentifyResult( ERR( tr( "Format not supported" ) ) );
273  }
274 
275  if ( !extent().contains( point ) )
276  {
277  // Outside the raster
278  for ( int bandNo = 1; bandNo <= bandCount(); bandNo++ )
279  {
280  results.insert( bandNo, QVariant() );
281  }
283  }
284 
285  QgsRectangle finalExtent = boundingBox;
286  if ( finalExtent.isEmpty() )
287  finalExtent = extent();
288 
289  if ( width == 0 )
290  {
291  width = capabilities() & Size ? xSize() : 1000;
292  }
293  if ( height == 0 )
294  {
295  height = capabilities() & Size ? ySize() : 1000;
296  }
297 
298  // Calculate the row / column where the point falls
299  double xres = ( finalExtent.width() ) / width;
300  double yres = ( finalExtent.height() ) / height;
301 
302  int col = static_cast< int >( std::floor( ( point.x() - finalExtent.xMinimum() ) / xres ) );
303  int row = static_cast< int >( std::floor( ( finalExtent.yMaximum() - point.y() ) / yres ) );
304 
305  double xMin = finalExtent.xMinimum() + col * xres;
306  double xMax = xMin + xres;
307  double yMax = finalExtent.yMaximum() - row * yres;
308  double yMin = yMax - yres;
309  QgsRectangle pixelExtent( xMin, yMin, xMax, yMax );
310 
311  for ( int i = 1; i <= bandCount(); i++ )
312  {
313  std::unique_ptr< QgsRasterBlock > bandBlock( block( i, pixelExtent, 1, 1 ) );
314 
315  if ( bandBlock )
316  {
317  double value = bandBlock->value( 0 );
318 
319  results.insert( i, value );
320  }
321  else
322  {
323  results.insert( i, QVariant() );
324  }
325  }
327 }
328 
329 double QgsRasterDataProvider::sample( const QgsPointXY &point, int band,
330  bool *ok, const QgsRectangle &boundingBox, int width, int height, int dpi )
331 {
332  if ( ok )
333  *ok = false;
334 
335  const auto res = identify( point, QgsRaster::IdentifyFormatValue, boundingBox, width, height, dpi );
336  const QVariant value = res.results().value( band );
337 
338  if ( !value.isValid() )
339  return std::numeric_limits<double>::quiet_NaN();
340 
341  if ( ok )
342  *ok = true;
343 
344  return value.toDouble( ok );
345 }
346 
348 {
349  return QStringLiteral( "text/plain" );
350 }
351 
352 bool QgsRasterDataProvider::writeBlock( QgsRasterBlock *block, int band, int xOffset, int yOffset )
353 {
354  if ( !block )
355  return false;
356  if ( !isEditable() )
357  {
358  QgsDebugMsg( QStringLiteral( "writeBlock() called on read-only provider." ) );
359  return false;
360  }
361  return write( block->bits(), band, block->width(), block->height(), xOffset, yOffset );
362 }
363 
364 // typedef QList<QPair<QString, QString> > *pyramidResamplingMethods_t();
365 QList<QPair<QString, QString> > QgsRasterDataProvider::pyramidResamplingMethods( const QString &providerKey )
366 {
367  QList<QPair<QString, QString> > methods = QgsProviderRegistry::instance()->pyramidResamplingMethods( providerKey );
368  if ( methods.isEmpty() )
369  {
370  QgsDebugMsg( QStringLiteral( "provider pyramidResamplingMethods returned no methods" ) );
371  }
372  return methods;
373 }
374 
376 {
377  QList<QgsRasterPyramid> myPyramidList = buildPyramidList();
378 
379  if ( myPyramidList.isEmpty() )
380  return false;
381 
382  QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
383  for ( myRasterPyramidIterator = myPyramidList.begin();
384  myRasterPyramidIterator != myPyramidList.end();
385  ++myRasterPyramidIterator )
386  {
387  if ( myRasterPyramidIterator->exists )
388  {
389  return true;
390  }
391  }
392  return false;
393 }
394 
396 {
397  if ( bandNo >= mUserNoDataValue.size() )
398  {
399  for ( int i = mUserNoDataValue.size(); i < bandNo; i++ )
400  {
402  }
403  }
404  QgsDebugMsgLevel( QStringLiteral( "set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
405 
406  if ( mUserNoDataValue[bandNo - 1] != noData )
407  {
408  // Clear statistics
409  int i = 0;
410  while ( i < mStatistics.size() )
411  {
412  if ( mStatistics.value( i ).bandNumber == bandNo )
413  {
414  mStatistics.removeAt( i );
415  mHistograms.removeAt( i );
416  }
417  else
418  {
419  i++;
420  }
421  }
422  mUserNoDataValue[bandNo - 1] = noData;
423  }
424 }
425 
427 {
428  return mTemporalCapabilities.get();
429 }
430 
432 {
433  return mTemporalCapabilities.get();
434 }
435 
437  const QString &uri,
438  const QString &format, int nBands,
439  Qgis::DataType type,
440  int width, int height, double *geoTransform,
442  const QStringList &createOptions )
443 {
445  providerKey,
446  uri, format,
447  nBands, type, width,
448  height, geoTransform, crs, createOptions );
449  if ( !ret )
450  {
451  QgsDebugMsg( "Cannot resolve 'createRasterDataProviderFunction' function in " + providerKey + " provider" );
452  }
453 
454  // TODO: it would be good to return invalid QgsRasterDataProvider
455  // with QgsError set, but QgsRasterDataProvider has pure virtual methods
456 
457  return ret;
458 }
459 
461 {
462  switch ( format )
463  {
465  return QStringLiteral( "Value" );
467  return QStringLiteral( "Text" );
469  return QStringLiteral( "Html" );
471  return QStringLiteral( "Feature" );
472  default:
473  return QStringLiteral( "Undefined" );
474  }
475 }
476 
478 {
479  switch ( format )
480  {
482  return tr( "Value" );
484  return tr( "Text" );
486  return tr( "Html" );
488  return tr( "Feature" );
489  default:
490  return QStringLiteral( "Undefined" );
491  }
492 }
493 
495 {
496  if ( formatName == QLatin1String( "Value" ) ) return QgsRaster::IdentifyFormatValue;
497  if ( formatName == QLatin1String( "Text" ) ) return QgsRaster::IdentifyFormatText;
498  if ( formatName == QLatin1String( "Html" ) ) return QgsRaster::IdentifyFormatHtml;
499  if ( formatName == QLatin1String( "Feature" ) ) return QgsRaster::IdentifyFormatFeature;
501 }
502 
504 {
505  switch ( format )
506  {
508  return IdentifyValue;
510  return IdentifyText;
512  return IdentifyHtml;
514  return IdentifyFeature;
515  default:
516  return NoCapabilities;
517  }
518 }
519 
521 {
522  return QList< double >();
523 }
524 
526 {
527  return false;
528 }
529 
531 {
532  Q_UNUSED( point )
533  Q_UNUSED( type )
534  return QgsPoint();
535 }
536 
537 bool QgsRasterDataProvider::userNoDataValuesContains( int bandNo, double value ) const
538 {
539  QgsRasterRangeList rangeList = mUserNoDataValue.value( bandNo - 1 );
540  return QgsRasterRange::contains( value, rangeList );
541 }
542 
544 {
545  mDpi = other.mDpi;
550  mExtent = other.mExtent;
555 
556  // copy temporal properties
557  if ( mTemporalCapabilities && other.mTemporalCapabilities )
558  {
559  *mTemporalCapabilities = *other.mTemporalCapabilities;
560  }
561 }
562 
563 static QgsRasterDataProvider::ResamplingMethod resamplingMethodFromString( const QString &str )
564 {
565  if ( str == QLatin1String( "bilinear" ) )
566  {
568  }
569  else if ( str == QLatin1String( "cubic" ) )
570  {
572  }
573  else if ( str == QLatin1String( "cubicSpline" ) )
574  {
576  }
577  else if ( str == QLatin1String( "lanczos" ) )
578  {
580  }
581  else if ( str == QLatin1String( "average" ) )
582  {
584  }
585  else if ( str == QLatin1String( "mode" ) )
586  {
588  }
589  else if ( str == QLatin1String( "gauss" ) )
590  {
592  }
594 }
595 
596 void QgsRasterDataProvider::readXml( const QDomElement &filterElem )
597 {
598  if ( filterElem.isNull() )
599  {
600  return;
601  }
602 
603  QDomElement resamplingElement = filterElem.firstChildElement( QStringLiteral( "resampling" ) );
604  if ( !resamplingElement.isNull() )
605  {
606  setMaxOversampling( resamplingElement.attribute( QStringLiteral( "maxOversampling" ), QStringLiteral( "2.0" ) ).toDouble() );
607  setZoomedInResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral( "zoomedInResamplingMethod" ) ) ) );
608  setZoomedOutResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral( "zoomedOutResamplingMethod" ) ) ) );
609  enableProviderResampling( resamplingElement.attribute( QStringLiteral( "enabled" ) ) == QLatin1String( "true" ) );
610  }
611 }
612 
613 static QString resamplingMethodToString( QgsRasterDataProvider::ResamplingMethod method )
614 {
615  switch ( method )
616  {
618  return QStringLiteral( "nearestNeighbour" );
620  return QStringLiteral( "bilinear" );
622  return QStringLiteral( "cubic" );
624  return QStringLiteral( "cubicSpline" );
626  return QStringLiteral( "lanczos" );
628  return QStringLiteral( "average" );
630  return QStringLiteral( "mode" );
632  return QStringLiteral( "gauss" );
633  }
634  // should not happen
635  return QStringLiteral( "nearestNeighbour" );
636 }
637 
638 void QgsRasterDataProvider::writeXml( QDomDocument &doc, QDomElement &parentElem ) const
639 {
640  QDomElement providerElement = doc.createElement( QStringLiteral( "provider" ) );
641  parentElem.appendChild( providerElement );
642 
643  QDomElement resamplingElement = doc.createElement( QStringLiteral( "resampling" ) );
644  providerElement.appendChild( resamplingElement );
645 
646  resamplingElement.setAttribute( QStringLiteral( "enabled" ),
647  mProviderResamplingEnabled ? QStringLiteral( "true" ) : QStringLiteral( "false" ) );
648 
649  resamplingElement.setAttribute( QStringLiteral( "zoomedInResamplingMethod" ),
650  resamplingMethodToString( mZoomedInResamplingMethod ) );
651 
652  resamplingElement.setAttribute( QStringLiteral( "zoomedOutResamplingMethod" ),
653  resamplingMethodToString( mZoomedOutResamplingMethod ) );
654 
655  resamplingElement.setAttribute( QStringLiteral( "maxOversampling" ),
656  QString::number( mMaxOversampling ) );
657 }
658 
660 {
661  return colorName( colorInterpretation( bandNo ) );
662 }
DataType
Raster data types.
Definition: qgis.h:102
This class represents a coordinate reference system (CRS).
Abstract base class for spatial data provider implementations.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
QgsDataSourceUri uri() const
Gets the data source specification.
A class to represent a 2D point.
Definition: qgspointxy.h:44
double y
Definition: qgspointxy.h:48
Q_GADGET double x
Definition: qgspointxy.h:47
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:38
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QgsRasterDataProvider * createRasterDataProvider(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 new instance of raster data provider.
QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns list of raster pyramid resampling methods.
Feedback object tailored for raster block reading.
Raster data container.
bool isEmpty() const
Returns true if block is empty, i.e.
void setNoDataValue(double noDataValue) SIP_HOLDGIL
Sets cell value that will be considered as "no data".
void setValid(bool valid) SIP_HOLDGIL
Mark block as valid or invalid.
int width() const SIP_HOLDGIL
Returns the width (number of columns) of the raster block.
char * bits(int row, int column)
Returns a pointer to block data.
bool setIsNoDataExcept(QRect exceptRect)
Set the whole block to no data except specified rectangle.
void applyNoDataValues(const QgsRasterRangeList &rangeList)
void applyScaleOffset(double scale, double offset)
Apply band scale and offset to raster block values.
static QRect subRect(const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent)
For extent and width, height find rectangle covered by subextent.
void setError(const QgsError &error)
Sets the last error.
int height() const SIP_HOLDGIL
Returns the height (number of rows) of the raster block.
bool setIsNoData(int row, int column) SIP_HOLDGIL
Set no data on pixel.
Implementation of data provider temporal properties for QgsRasterDataProviders.
Base class for raster data providers.
double mMaxOversampling
Maximum boundary for oversampling (to avoid too much data traffic). Default: 2.0.
QList< bool > mUseSrcNoDataValue
Use source nodata value.
TransformType
Types of transformation in transformCoordinates() function.
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Returns the raster layers pyramid list.
virtual double bandOffset(int bandNo) const
Read band offset for raster value.
virtual QString lastErrorFormat()
Returns the format of the error text for the last error in this provider.
bool mProviderResamplingEnabled
Whether provider resampling is enabled.
virtual bool useSourceNoDataValue(int bandNo) const
Returns the source nodata value usage.
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage.
virtual double sourceNoDataValue(int bandNo) const
Value representing no data value.
QString colorName(int colorInterpretation) const
void readXml(const QDomElement &filterElem) override
Sets base class members from xml. Usually called from create() methods of subclasses.
QList< QgsRasterRangeList > mUserNoDataValue
List of lists of user defined additional no data values for each band, indexed from 0.
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.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
virtual bool isEditable() const
Checks whether the provider is in editing mode, i.e.
void copyBaseSettings(const QgsRasterDataProvider &other)
Copy member variables from other raster data provider. Useful for implementation of clone() method in...
bool userNoDataValuesContains(int bandNo, double value) const
Returns true if user no data contains value.
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 bool enableProviderResampling(bool enable)
Enable or disable provider-level resampling.
QgsRectangle extent() const override=0
Returns the extent of the layer.
virtual bool ignoreExtents() const
Returns true if the extents reported by the data provider are not reliable and it's possible that the...
virtual bool setMaxOversampling(double factor)
Sets maximum oversampling factor for zoomed-out operations.
Qgis::DataType dataType(int bandNo) const override=0
Returns data type for the band specified by number.
ResamplingMethod mZoomedOutResamplingMethod
Resampling method for zoomed out pixel extraction.
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
bool hasPyramids()
Returns true if raster has at least one populated histogram.
virtual double bandScale(int bandNo) const
Read band scale for raster value.
static QString identifyFormatName(QgsRaster::IdentifyFormat format)
@ NoProviderCapabilities
Provider has no capabilities.
int dpi() const
Returns the dpi of the output device.
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.
static QString identifyFormatLabel(QgsRaster::IdentifyFormat format)
QgsRasterBlock * block(int bandNo, const QgsRectangle &boundingBox, int width, int height, QgsRasterBlockFeedback *feedback=nullptr) override
Read block of data using given extent and size.
virtual int colorInterpretation(int bandNo) const
Returns data type for the band specified by number.
QList< double > mSrcNoDataValue
Source no data value is available and is set to be used or internal no data is available.
virtual bool readBlock(int bandNo, int xBlock, int yBlock, void *data)
Reads a block of raster data into data.
ResamplingMethod mZoomedInResamplingMethod
Resampling method for zoomed in pixel extraction.
QgsRasterDataProvider()
Provider capabilities.
QList< bool > mSrcHasNoDataValue
Source no data value exists.
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.
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Returns a list of user no data value ranges.
virtual bool setZoomedInResamplingMethod(ResamplingMethod method)
Set resampling method to apply for zoomed-in operations.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
void writeXml(QDomDocument &doc, QDomElement &parentElem) const override
Write base class members to xml.
virtual QList< double > nativeResolutions() const
Returns a list of native resolutions if available, i.e.
virtual QgsPoint transformCoordinates(const QgsPoint &point, TransformType type)
Transforms coordinates between source image coordinate space [0..width]x[0..height] and layer coordin...
QgsRasterDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
QString colorInterpretationName(int bandNo) const override
Returns the name of the color interpretation for the specified bandNumber.
ResamplingMethod
Resampling method for provider-level resampling.
@ Lanczos
Lanczos windowed sinc interpolation (6x6 kernel)
@ Nearest
Nearest-neighbour resampling.
@ Mode
Mode (selects the value which appears most often of all the sampled points)
@ Bilinear
Bilinear (2x2 kernel) resampling.
@ CubicSpline
Cubic B-Spline Approximation (4x4 kernel)
@ Cubic
Cubic Convolution Approximation (4x4 kernel) resampling.
virtual bool write(void *data, int band, int width, int height, int xOffset, int yOffset)
Writes into the provider datasource.
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
virtual bool setZoomedOutResamplingMethod(ResamplingMethod method)
Set resampling method to apply for zoomed-out operations.
Raster identify results container.
Base class for processing filters like renderers, reprojector, resampler etc.
int dataTypeSize(int bandNo)
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
Capability
If you add to this, please also add to capabilitiesString()
@ IdentifyValue
Numerical values.
@ IdentifyFeature
WMS GML -> feature.
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
virtual int xSize() const
Gets raster size.
virtual int bandCount() const =0
Gets number of bands.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
virtual int ySize() const
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
bool contains(double value) const
Returns true if this range contains the specified value.
IdentifyFormat
Definition: qgsraster.h:58
@ IdentifyFormatFeature
Definition: qgsraster.h:63
@ IdentifyFormatValue
Definition: qgsraster.h:60
@ IdentifyFormatText
Definition: qgsraster.h:61
@ IdentifyFormatUndefined
Definition: qgsraster.h:59
@ IdentifyFormatHtml
Definition: qgsraster.h:62
@ UndefinedColorInterpretation
Definition: qgsraster.h:37
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:140
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:135
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:130
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:145
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
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:769
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:316
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
#define ERR(message)
QList< QgsRasterRange > QgsRasterRangeList
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.