30 #define ERR(message) QgsError(message, "Raster provider") 46 QgsDebugMsgLevel( QStringLiteral(
"bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
49 std::unique_ptr< QgsRasterBlock >
block = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), width, height );
55 if ( block->isEmpty() )
57 QgsDebugMsg( QStringLiteral(
"Couldn't create raster block" ) );
58 return block.release();
66 QgsDebugMsg( QStringLiteral(
"Extent outside provider extent" ) );
68 return block.release();
71 double xRes = boundingBox.
width() / width;
72 double yRes = boundingBox.
height() / height;
73 double tmpXRes, tmpYRes;
74 double providerXRes = 0;
75 double providerYRes = 0;
80 tmpXRes = std::max( providerXRes, xRes );
81 tmpYRes = std::max( providerYRes, yRes );
91 if ( tmpExtent != boundingBox ||
92 tmpXRes > xRes || tmpYRes > yRes )
96 if ( !
extent().contains( boundingBox ) )
99 block->setIsNoDataExcept( subRect );
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;
108 QgsDebugMsgLevel( QStringLiteral(
"fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
110 if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
111 fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
114 QgsDebugMsg( QStringLiteral(
"Row or column limits out of range" ) );
115 return block.release();
120 if ( tmpXRes > xRes )
127 if ( tmpYRes > yRes )
129 int row = std::floor( (
extent().yMaximum() - tmpExtent.
yMaximum() ) / providerYRes );
131 row = std::ceil( (
extent().yMaximum() - tmpExtent.
yMinimum() ) / providerYRes );
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;
139 QgsDebugMsgLevel( QStringLiteral(
"Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
142 std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), tmpWidth, tmpHeight );
148 if ( !
readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
150 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
151 block->setIsNoData();
152 return block.release();
157 double xMin = boundingBox.
xMinimum();
158 double yMax = boundingBox.
yMaximum();
159 double tmpXMin = tmpExtent.
xMinimum();
160 double tmpYMax = tmpExtent.
yMaximum();
162 for (
int row = fromRow; row <= toRow; row++ )
164 double y = yMax - ( row + 0.5 ) * yRes;
165 int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
167 for (
int col = fromCol; col <= toCol; col++ )
169 double x = xMin + ( col + 0.5 ) * xRes;
170 int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
172 if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
174 QgsDebugMsg( QStringLiteral(
"Source row or column limits out of range" ) );
175 block->setIsNoData();
176 return block.release();
179 qgssize tmpIndex =
static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
182 char *tmpBits = tmpBlock->bits( tmpIndex );
183 char *bits = block->bits( index );
186 QgsDebugMsg( QStringLiteral(
"Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
191 QgsDebugMsg( QStringLiteral(
"Cannot set output block data." ) );
194 memcpy( bits, tmpBits, pixelSize );
200 if ( !
readBlock( bandNo, boundingBox, width, height, block->bits(), feedback ) )
202 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
203 block->setIsNoData();
204 return block.release();
212 return block.release();
248 QMap<int, QVariant> results;
252 QgsDebugMsg( QStringLiteral(
"Format not supported" ) );
256 if ( !
extent().contains( point ) )
259 for (
int bandNo = 1; bandNo <=
bandCount(); bandNo++ )
261 results.insert( bandNo, QVariant() );
280 double xres = ( finalExtent.
width() ) / width;
281 double yres = ( finalExtent.
height() ) / height;
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 ) );
286 double xMin = finalExtent.
xMinimum() + col * xres;
287 double xMax = xMin + xres;
288 double yMax = finalExtent.
yMaximum() - row * yres;
289 double yMin = yMax - yres;
294 std::unique_ptr< QgsRasterBlock > bandBlock(
block( i, pixelExtent, 1, 1 ) );
298 double value = bandBlock->value( 0 );
300 results.insert( i, value );
304 results.insert( i, QVariant() );
311 bool *ok,
const QgsRectangle &boundingBox,
int width,
int height,
int dpi )
317 const QVariant value = res.results().value( band );
319 if ( !value.isValid() )
320 return std::numeric_limits<double>::quiet_NaN();
325 return value.toDouble( ok );
330 return QStringLiteral(
"text/plain" );
339 QgsDebugMsg( QStringLiteral(
"writeBlock() called on read-only provider." ) );
349 if ( pPyramidResamplingMethods )
351 QList<QPair<QString, QString> > *methods = pPyramidResamplingMethods();
354 QgsDebugMsg( QStringLiteral(
"provider pyramidResamplingMethods returned no methods" ) );
363 QgsDebugMsg( QStringLiteral(
"Could not resolve pyramidResamplingMethods provider library" ) );
365 return QList<QPair<QString, QString> >();
372 if ( myPyramidList.isEmpty() )
375 QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
376 for ( myRasterPyramidIterator = myPyramidList.begin();
377 myRasterPyramidIterator != myPyramidList.end();
378 ++myRasterPyramidIterator )
380 if ( myRasterPyramidIterator->exists )
397 QgsDebugMsgLevel( QStringLiteral(
"set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
420 const QString &,
int,
428 const QString &format,
int nBands,
430 int width,
int height,
double *geoTransform,
432 const QStringList &createOptions )
437 QgsDebugMsg(
"Cannot resolve 'create' function in " + providerKey +
" provider" );
442 return createFn( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
450 return QStringLiteral(
"Value" );
452 return QStringLiteral(
"Text" );
454 return QStringLiteral(
"Html" );
456 return QStringLiteral(
"Feature" );
458 return QStringLiteral(
"Undefined" );
467 return tr(
"Value" );
473 return tr(
"Feature" );
475 return QStringLiteral(
"Undefined" );
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.
int height() const
Returns the height (number of rows) of the raster block.
bool isEmpty() const
Returns true if the rectangle is empty.
void copyBaseSettings(const QgsRasterDataProvider &other)
Copy member variables from other raster data provider. Useful for implementation of clone() method in...
virtual void setUseSourceNoDataValue(int bandNo, bool use)
Sets the source nodata value usage.
virtual bool useSourceNoDataValue(int bandNo) const
Returns the source nodata value usage.
void setXMaximum(double x)
Set the maximum x value.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
bool contains(double value) const
Returns true if this range contains the specified value.
A class to represent a 2D point.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
virtual double bandOffset(int bandNo) const
Read band offset for raster value.
DataType
Raster data types.
Capability
If you add to this, please also add to capabilitiesString()
int width() const
Returns the width (number of columns) of the raster block.
static Capability identifyFormatToCapability(QgsRaster::IdentifyFormat format)
virtual QgsRasterRangeList userNoDataValues(int bandNo) const
Returns a list of user no data value ranges.
QgsDataSourceUri uri() const
Gets the data source specification.
Abstract base class for spatial data provider implementations.
static QRect subRect(const QgsRectangle &extent, int width, int height, const QgsRectangle &subExtent)
For extent and width, height find rectangle covered by subextent.
virtual int ySize() const
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.
virtual bool sourceHasNoDataValue(int bandNo) const
Returns true if source band has no data value.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Provider has no capabilities.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
#define QgsDebugMsgLevel(str, level)
virtual QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Returns the raster layers pyramid list.
static QgsRaster::IdentifyFormat identifyFormatFromName(const QString &formatName)
QgsRectangle extent() const override=0
Returns the extent of the layer.
virtual QgsCoordinateReferenceSystem crs() const =0
Returns the coordinate system for the data source.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
void setYMinimum(double y)
Set the minimum y value.
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
QList< bool > mSrcHasNoDataValue
Source no data value exists.
QgsRasterDataProvider()
Provider capabilities.
Base class for processing filters like renderers, reprojector, resampler etc.
virtual QgsRasterDataProvider::ProviderCapabilities providerCapabilities() const
Returns flags containing the supported capabilities of the data provider.
virtual double sourceNoDataValue(int bandNo) const
Value representing 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...
bool userNoDataValuesContains(int bandNo, double value) const
Returns true if user no data contains value.
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.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
virtual bool readBlock(int bandNo, int xBlock, int yBlock, void *data)
Read block of data.
virtual double bandScale(int bandNo) const
Read band scale for raster value.
static QList< QPair< QString, QString > > pyramidResamplingMethods(const QString &providerKey)
Returns a list of pyramid resampling method name and label pairs for given provider.
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
virtual int xSize() const
Gets raster size.
virtual bool isEditable() const
Checks whether the provider is in editing mode, i.e.
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)
virtual bool write(void *data, int band, int width, int height, int xOffset, int yOffset)
Writes into the provider datasource.
int dpi() const
Returns the dpi of the output device.
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
double width() const
Returns the width of the rectangle.
virtual void setUserNoDataValue(int bandNo, const QgsRasterRangeList &noData)
bool writeBlock(QgsRasterBlock *block, int band, int xOffset=0, int yOffset=0)
Writes pixel data from a raster block into the provider data source.
Feedback object tailored for raster block reading.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
static QString identifyFormatLabel(QgsRaster::IdentifyFormat format)
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.