31 #define ERR(message) QgsError(message, "Raster provider") 47 QgsDebugMsgLevel( QStringLiteral(
"bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
50 std::unique_ptr< QgsRasterBlock >
block = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), width, height );
56 if ( block->isEmpty() )
58 QgsDebugMsg( QStringLiteral(
"Couldn't create raster block" ) );
59 return block.release();
67 QgsDebugMsg( QStringLiteral(
"Extent outside provider extent" ) );
69 return block.release();
72 double xRes = boundingBox.
width() / width;
73 double yRes = boundingBox.
height() / height;
74 double tmpXRes, tmpYRes;
75 double providerXRes = 0;
76 double providerYRes = 0;
81 tmpXRes = std::max( providerXRes, xRes );
82 tmpYRes = std::max( providerYRes, yRes );
92 if ( tmpExtent != boundingBox ||
93 tmpXRes > xRes || tmpYRes > yRes )
97 if ( !
extent().contains( boundingBox ) )
100 block->setIsNoDataExcept( subRect );
104 int fromRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMaximum() ) / yRes );
105 int toRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMinimum() ) / yRes ) - 1;
106 int fromCol = std::round( ( tmpExtent.
xMinimum() - boundingBox.
xMinimum() ) / xRes );
107 int toCol = std::round( ( tmpExtent.
xMaximum() - boundingBox.
xMinimum() ) / xRes ) - 1;
109 QgsDebugMsgLevel( QStringLiteral(
"fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
111 if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
112 fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
115 QgsDebugMsg( QStringLiteral(
"Row or column limits out of range" ) );
116 return block.release();
121 if ( tmpXRes > xRes )
128 if ( tmpYRes > yRes )
130 int row = std::floor( (
extent().yMaximum() - tmpExtent.
yMaximum() ) / providerYRes );
132 row = std::ceil( (
extent().yMaximum() - tmpExtent.
yMinimum() ) / providerYRes );
135 int tmpWidth = std::round( tmpExtent.
width() / tmpXRes );
136 int tmpHeight = std::round( tmpExtent.
height() / tmpYRes );
137 tmpXRes = tmpExtent.
width() / tmpWidth;
138 tmpYRes = tmpExtent.
height() / tmpHeight;
140 QgsDebugMsgLevel( QStringLiteral(
"Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
143 std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), tmpWidth, tmpHeight );
149 if ( !
readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
151 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
152 block->setIsNoData();
153 return block.release();
158 double xMin = boundingBox.
xMinimum();
159 double yMax = boundingBox.
yMaximum();
160 double tmpXMin = tmpExtent.
xMinimum();
161 double tmpYMax = tmpExtent.
yMaximum();
163 for (
int row = fromRow; row <= toRow; row++ )
165 double y = yMax - ( row + 0.5 ) * yRes;
166 int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
168 for (
int col = fromCol; col <= toCol; col++ )
170 double x = xMin + ( col + 0.5 ) * xRes;
171 int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
173 if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
175 QgsDebugMsg( QStringLiteral(
"Source row or column limits out of range" ) );
176 block->setIsNoData();
177 return block.release();
180 qgssize tmpIndex =
static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
183 char *tmpBits = tmpBlock->bits( tmpIndex );
184 char *bits = block->bits( index );
187 QgsDebugMsg( QStringLiteral(
"Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
192 QgsDebugMsg( QStringLiteral(
"Cannot set output block data." ) );
195 memcpy( bits, tmpBits, pixelSize );
201 if ( !
readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ) )
203 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
204 block->setIsNoData();
205 return block.release();
213 return block.release();
249 QMap<int, QVariant> results;
253 QgsDebugMsg( QStringLiteral(
"Format not supported" ) );
257 if ( !
extent().contains( point ) )
260 for (
int bandNo = 1; bandNo <=
bandCount(); bandNo++ )
262 results.insert( bandNo, QVariant() );
281 double xres = ( finalExtent.
width() ) / width;
282 double yres = ( finalExtent.
height() ) / height;
284 int col =
static_cast< int >( std::floor( ( point.
x() - finalExtent.
xMinimum() ) / xres ) );
285 int row =
static_cast< int >( std::floor( ( finalExtent.
yMaximum() - point.
y() ) / yres ) );
287 double xMin = finalExtent.
xMinimum() + col * xres;
288 double xMax = xMin + xres;
289 double yMax = finalExtent.
yMaximum() - row * yres;
290 double yMin = yMax - yres;
295 std::unique_ptr< QgsRasterBlock > bandBlock(
block( i, pixelExtent, 1, 1 ) );
299 double value = bandBlock->value( 0 );
301 results.insert( i, value );
305 results.insert( i, QVariant() );
312 bool *ok,
const QgsRectangle &boundingBox,
int width,
int height,
int dpi )
318 const QVariant value = res.results().value( band );
320 if ( !value.isValid() )
321 return std::numeric_limits<double>::quiet_NaN();
326 return value.toDouble( ok );
331 return QStringLiteral(
"text/plain" );
340 QgsDebugMsg( QStringLiteral(
"writeBlock() called on read-only provider." ) );
350 if ( methods.isEmpty() )
352 QgsDebugMsg( QStringLiteral(
"provider pyramidResamplingMethods returned no methods" ) );
361 if ( myPyramidList.isEmpty() )
364 QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
365 for ( myRasterPyramidIterator = myPyramidList.begin();
366 myRasterPyramidIterator != myPyramidList.end();
367 ++myRasterPyramidIterator )
369 if ( myRasterPyramidIterator->exists )
386 QgsDebugMsgLevel( QStringLiteral(
"set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
411 const QString &format,
int nBands,
413 int width,
int height,
double *geoTransform,
415 const QStringList &createOptions )
421 height, geoTransform, crs, createOptions );
423 QgsDebugMsg(
"Cannot resolve 'createRasterDataProviderFunction' function in " + providerKey +
" provider" );
435 return QStringLiteral(
"Value" );
437 return QStringLiteral(
"Text" );
439 return QStringLiteral(
"Html" );
441 return QStringLiteral(
"Feature" );
443 return QStringLiteral(
"Undefined" );
452 return tr(
"Value" );
458 return tr(
"Feature" );
460 return QStringLiteral(
"Undefined" );
492 return QList< double >();
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".
A rectangle specified with double values.
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.
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.
A class to represent a 2D point.
virtual bool ignoreExtents() const
Returns true if the extents reported by the data provider are not reliable and it's possible that the...
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)
DataType
Raster data types.
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)
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.
Provider has no capabilities.
#define QgsDebugMsgLevel(str, level)
bool isEmpty() const
Returns true if the rectangle is empty.
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.
void setYMinimum(double y)
Set the minimum y value.
QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns list of raster pyramid resampling methods.
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.
virtual 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.
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...
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).
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).
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.
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).
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).
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.
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.
double height() const
Returns the height of the rectangle.
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.