33 #define ERR(message) QgsError(message, "Raster provider")
 
   49   QgsDebugMsgLevel( QStringLiteral( 
"bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
 
   52   std::unique_ptr< QgsRasterBlock > 
block = std::make_unique< QgsRasterBlock >( 
dataType( bandNo ), width, height );
 
   60     QgsDebugMsg( QStringLiteral( 
"Couldn't create raster block" ) );
 
   61     block->
setError( { tr( 
"Couldn't create raster block." ), QStringLiteral( 
"Raster" ) } );
 
   63     return block.release();
 
   71     QgsDebugMsg( QStringLiteral( 
"Extent outside provider extent" ) );
 
   72     block->
setError( { tr( 
"Extent outside provider extent." ), QStringLiteral( 
"Raster" ) } );
 
   75     return block.release();
 
   78   double xRes = boundingBox.
width() / width;
 
   79   double yRes = boundingBox.
height() / height;
 
   80   double tmpXRes, tmpYRes;
 
   81   double providerXRes = 0;
 
   82   double providerYRes = 0;
 
   87     tmpXRes = std::max( providerXRes, xRes );
 
   88     tmpYRes = std::max( providerYRes, yRes );
 
   98   if ( tmpExtent != boundingBox ||
 
   99        tmpXRes > xRes || tmpYRes > yRes )
 
  103     if ( !
extent().contains( boundingBox ) )
 
  110     int fromRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMaximum() ) / yRes );
 
  111     int toRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMinimum() ) / yRes ) - 1;
 
  112     int fromCol = std::round( ( tmpExtent.
xMinimum() - boundingBox.
xMinimum() ) / xRes );
 
  113     int toCol = std::round( ( tmpExtent.
xMaximum() - boundingBox.
xMinimum() ) / xRes ) - 1;
 
  115     QgsDebugMsgLevel( QStringLiteral( 
"fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
 
  117     if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
 
  118          fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
 
  121       QgsDebugMsg( QStringLiteral( 
"Row or column limits out of range" ) );
 
  122       block->
setError( { tr( 
"Row or column limits out of range" ), QStringLiteral( 
"Raster" ) } );
 
  124       return block.release();
 
  129     if ( tmpXRes > xRes )
 
  131       int col = std::floor( ( tmpExtent.
xMinimum() - 
extent().xMinimum() ) / providerXRes );
 
  133       col = std::ceil( ( tmpExtent.
xMaximum() - 
extent().xMinimum() ) / providerXRes );
 
  136     if ( tmpYRes > yRes )
 
  138       int row = std::floor( ( 
extent().yMaximum() - tmpExtent.
yMaximum() ) / providerYRes );
 
  140       row = std::ceil( ( 
extent().yMaximum() - tmpExtent.
yMinimum() ) / providerYRes );
 
  143     int tmpWidth = std::round( tmpExtent.
width() / tmpXRes );
 
  144     int tmpHeight = std::round( tmpExtent.
height() / tmpYRes );
 
  145     tmpXRes = tmpExtent.
width() / tmpWidth;
 
  146     tmpYRes = tmpExtent.
height() / tmpHeight;
 
  148     QgsDebugMsgLevel( QStringLiteral( 
"Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
 
  151     std::unique_ptr< QgsRasterBlock > tmpBlock = std::make_unique< QgsRasterBlock >( 
dataType( bandNo ), tmpWidth, tmpHeight );
 
  157     if ( !
readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
 
  159       QgsDebugMsg( QStringLiteral( 
"Error occurred while reading block" ) );
 
  160       block->
setError( { tr( 
"Error occurred while reading block." ), QStringLiteral( 
"Raster" ) } );
 
  163       return block.release();
 
  168     double xMin = boundingBox.
xMinimum();
 
  169     double yMax = boundingBox.
yMaximum();
 
  170     double tmpXMin = tmpExtent.
xMinimum();
 
  171     double tmpYMax = tmpExtent.
yMaximum();
 
  173     for ( 
int row = fromRow; row <= toRow; row++ )
 
  175       double y = yMax - ( row + 0.5 ) * yRes;
 
  176       int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
 
  178       for ( 
int col = fromCol; col <= toCol; col++ )
 
  180         double x = xMin + ( col + 0.5 ) * xRes;
 
  181         int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
 
  183         if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
 
  185           QgsDebugMsg( QStringLiteral( 
"Source row or column limits out of range" ) );
 
  187           block->
setError( { tr( 
"Source row or column limits out of range." ), QStringLiteral( 
"Raster" ) } );
 
  189           return block.release();
 
  195         char *tmpBits = tmpBlock->
bits( tmpIndex );
 
  199           QgsDebugMsg( QStringLiteral( 
"Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
 
  204           QgsDebugMsg( QStringLiteral( 
"Cannot set output block data." ) );
 
  207         memcpy( bits, tmpBits, pixelSize );
 
  215       QgsDebugMsg( QStringLiteral( 
"Error occurred while reading block" ) );
 
  217       block->
setError( { tr( 
"Error occurred while reading block." ), QStringLiteral( 
"Raster" ) } );
 
  219       return block.release();
 
  227   return block.release();
 
  239     QgsDataProvider::ReadFlags flags )
 
  268   QMap<int, QVariant> results;
 
  272     QgsDebugMsg( QStringLiteral( 
"Format not supported" ) );
 
  276   if ( !
extent().contains( point ) )
 
  279     for ( 
int bandNo = 1; bandNo <= 
bandCount(); bandNo++ )
 
  281       results.insert( bandNo, QVariant() );
 
  300   double xres = ( finalExtent.
width() ) / width;
 
  301   double yres = ( finalExtent.
height() ) / height;
 
  303   int col = 
static_cast< int >( std::floor( ( point.
x() - finalExtent.
xMinimum() ) / xres ) );
 
  304   int row = 
static_cast< int >( std::floor( ( finalExtent.
yMaximum() - point.
y() ) / yres ) );
 
  306   double xMin = finalExtent.
xMinimum() + col * xres;
 
  307   double xMax = xMin + xres;
 
  308   double yMax = finalExtent.
yMaximum() - row * yres;
 
  309   double yMin = yMax - yres;
 
  314     std::unique_ptr< QgsRasterBlock > bandBlock( 
block( i, pixelExtent, 1, 1 ) );
 
  318       double value = bandBlock->value( 0 );
 
  320       results.insert( i, value );
 
  324       results.insert( i, QVariant() );
 
  331                                       bool *ok, 
const QgsRectangle &boundingBox, 
int width, 
int height, 
int dpi )
 
  337   const QVariant value = res.results().value( band );
 
  339   if ( !value.isValid() )
 
  340     return std::numeric_limits<double>::quiet_NaN();
 
  345   return value.toDouble( ok );
 
  350   return QStringLiteral( 
"text/plain" );
 
  359     QgsDebugMsg( QStringLiteral( 
"writeBlock() called on read-only provider." ) );
 
  369   if ( methods.isEmpty() )
 
  371     QgsDebugMsg( QStringLiteral( 
"provider pyramidResamplingMethods returned no methods" ) );
 
  379   return std::any_of( pyramidList.constBegin(), pyramidList.constEnd(), []( 
QgsRasterPyramid pyramid ) { return pyramid.getExists(); } );
 
  391   QgsDebugMsgLevel( QStringLiteral( 
"set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
 
  415   return mTemporalCapabilities.get();
 
  420   return mTemporalCapabilities.get();
 
  425     const QString &format, 
int nBands,
 
  427     int width, 
int height, 
double *geoTransform,
 
  429     const QStringList &createOptions )
 
  435                                  height, geoTransform, 
crs, createOptions );
 
  438     QgsDebugMsg( 
"Cannot resolve 'createRasterDataProviderFunction' function in " + providerKey + 
" provider" );
 
  452       return QStringLiteral( 
"Value" );
 
  454       return QStringLiteral( 
"Text" );
 
  456       return QStringLiteral( 
"Html" );
 
  458       return QStringLiteral( 
"Feature" );
 
  460       return QStringLiteral( 
"Undefined" );
 
  469       return tr( 
"Value" );
 
  475       return tr( 
"Feature" );
 
  477       return QStringLiteral( 
"Undefined" );
 
  509   return QList< double >();
 
  544   if ( mTemporalCapabilities && other.mTemporalCapabilities )
 
  546     *mTemporalCapabilities = *other.mTemporalCapabilities;
 
  552   if ( 
str == QLatin1String( 
"bilinear" ) )
 
  556   else if ( 
str == QLatin1String( 
"cubic" ) )
 
  560   else if ( 
str == QLatin1String( 
"cubicSpline" ) )
 
  564   else if ( 
str == QLatin1String( 
"lanczos" ) )
 
  568   else if ( 
str == QLatin1String( 
"average" ) )
 
  572   else if ( 
str == QLatin1String( 
"mode" ) )
 
  576   else if ( 
str == QLatin1String( 
"gauss" ) )
 
  585   if ( filterElem.isNull() )
 
  590   QDomElement resamplingElement = filterElem.firstChildElement( QStringLiteral( 
"resampling" ) );
 
  591   if ( !resamplingElement.isNull() )
 
  593     setMaxOversampling( resamplingElement.attribute( QStringLiteral( 
"maxOversampling" ), QStringLiteral( 
"2.0" ) ).toDouble() );
 
  594     setZoomedInResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral( 
"zoomedInResamplingMethod" ) ) ) );
 
  595     setZoomedOutResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral( 
"zoomedOutResamplingMethod" ) ) ) );
 
  605       return QStringLiteral( 
"nearestNeighbour" );
 
  607       return QStringLiteral( 
"bilinear" );
 
  609       return QStringLiteral( 
"cubic" );
 
  611       return QStringLiteral( 
"cubicSpline" );
 
  613       return QStringLiteral( 
"lanczos" );
 
  615       return QStringLiteral( 
"average" );
 
  617       return QStringLiteral( 
"mode" );
 
  619       return QStringLiteral( 
"gauss" );
 
  622   return QStringLiteral( 
"nearestNeighbour" );
 
  627   QDomElement providerElement = doc.createElement( QStringLiteral( 
"provider" ) );
 
  628   parentElem.appendChild( providerElement );
 
  630   QDomElement resamplingElement = doc.createElement( QStringLiteral( 
"resampling" ) );
 
  631   providerElement.appendChild( resamplingElement );
 
  633   resamplingElement.setAttribute( QStringLiteral( 
"enabled" ),
 
  636   resamplingElement.setAttribute( QStringLiteral( 
"zoomedInResamplingMethod" ),
 
  639   resamplingElement.setAttribute( QStringLiteral( 
"zoomedOutResamplingMethod" ),
 
  642   resamplingElement.setAttribute( QStringLiteral( 
"maxOversampling" ),
 
DataType
Raster data types.
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.
Point geometry type, with support for z-dimension and m-values.
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.
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 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 QList< QgsRasterPyramid > buildPyramidList(const QList< int > &overviewList=QList< int >())
Returns the raster layers pyramid list.
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 existing pyramid.
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.
@ Average
Average 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.
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.
int dataTypeSize(int bandNo) const
Returns the size (in bytes) for the data type for the specified band.
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.
This struct is used to store pyramid info for the raster layer.
bool contains(double value) const
Returns true if this range contains the specified value.
@ IdentifyFormatUndefined
@ UndefinedColorInterpretation
A rectangle specified with double values.
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).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
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...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugMsgLevel(str, level)
QList< QgsRasterRange > QgsRasterRangeList
const QgsCoordinateReferenceSystem & crs
Setting options for creating vector data providers.