30 #define ERR(message) QgsError(message, "Raster provider") 46 QgsDebugMsgLevel( QStringLiteral(
"bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
57 QgsDebugMsg( QStringLiteral(
"Couldn't create raster block" ) );
66 QgsDebugMsg( QStringLiteral(
"Extent outside provider extent" ) );
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 ) )
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" ) );
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 );
148 readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->
bits(), feedback );
152 double xMin = boundingBox.
xMinimum();
153 double yMax = boundingBox.
yMaximum();
154 double tmpXMin = tmpExtent.
xMinimum();
155 double tmpYMax = tmpExtent.
yMaximum();
157 for (
int row = fromRow; row <= toRow; row++ )
159 double y = yMax - ( row + 0.5 ) * yRes;
160 int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
162 for (
int col = fromCol; col <= toCol; col++ )
164 double x = xMin + ( col + 0.5 ) * xRes;
165 int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
167 if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
169 QgsDebugMsg( QStringLiteral(
"Source row or column limits out of range" ) );
175 qgssize tmpIndex =
static_cast< qgssize >( tmpRow ) * static_cast< qgssize >( tmpWidth ) + tmpCol;
178 char *tmpBits = tmpBlock->
bits( tmpIndex );
179 char *bits = block->
bits( index );
182 QgsDebugMsg( QStringLiteral(
"Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
187 QgsDebugMsg( QStringLiteral(
"Cannot set output block data." ) );
190 memcpy( bits, tmpBits, pixelSize );
198 readBlock( bandNo, boundingBox, width, height, block->
bits(), feedback );
241 QMap<int, QVariant> results;
245 QgsDebugMsg( QStringLiteral(
"Format not supported" ) );
249 if ( !
extent().contains( point ) )
252 for (
int bandNo = 1; bandNo <=
bandCount(); bandNo++ )
254 results.insert( bandNo, QVariant() );
273 double xres = ( finalExtent.
width() ) / width;
274 double yres = ( finalExtent.
height() ) / height;
276 int col =
static_cast< int >( std::floor( ( point.
x() - finalExtent.
xMinimum() ) / xres ) );
277 int row =
static_cast< int >( std::floor( ( finalExtent.
yMaximum() - point.
y() ) / yres ) );
279 double xMin = finalExtent.
xMinimum() + col * xres;
280 double xMax = xMin + xres;
281 double yMax = finalExtent.
yMaximum() - row * yres;
282 double yMin = yMax - yres;
287 std::unique_ptr< QgsRasterBlock > bandBlock(
block( i, pixelExtent, 1, 1 ) );
291 double value = bandBlock->value( 0 );
293 results.insert( i, value );
297 results.insert( i, QVariant() );
304 bool *ok,
const QgsRectangle &boundingBox,
int width,
int height,
int dpi )
310 const QVariant value = res.results().value( band );
312 if ( !value.isValid() )
313 return std::numeric_limits<double>::quiet_NaN();
318 return value.toDouble( ok );
323 return QStringLiteral(
"text/plain" );
332 QgsDebugMsg( QStringLiteral(
"writeBlock() called on read-only provider." ) );
342 if ( pPyramidResamplingMethods )
344 QList<QPair<QString, QString> > *methods = pPyramidResamplingMethods();
347 QgsDebugMsg( QStringLiteral(
"provider pyramidResamplingMethods returned no methods" ) );
356 QgsDebugMsg( QStringLiteral(
"Could not resolve pyramidResamplingMethods provider library" ) );
358 return QList<QPair<QString, QString> >();
365 if ( myPyramidList.isEmpty() )
368 QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
369 for ( myRasterPyramidIterator = myPyramidList.begin();
370 myRasterPyramidIterator != myPyramidList.end();
371 ++myRasterPyramidIterator )
373 if ( myRasterPyramidIterator->exists )
390 QgsDebugMsgLevel( QStringLiteral(
"set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
413 const QString &,
int,
421 const QString &format,
int nBands,
423 int width,
int height,
double *geoTransform,
425 const QStringList &createOptions )
430 QgsDebugMsg(
"Cannot resolve 'create' function in " + providerKey +
" provider" );
435 return createFn( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
443 return QStringLiteral(
"Value" );
445 return QStringLiteral(
"Text" );
447 return QStringLiteral(
"Html" );
449 return QStringLiteral(
"Feature" );
451 return QStringLiteral(
"Undefined" );
460 return tr(
"Value" );
466 return tr(
"Feature" );
468 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".
virtual void readBlock(int bandNo, int xBlock, int yBlock, void *data)
Read block of 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.
void applyNoDataValues(const QgsRasterRangeList &rangeList)
bool setIsNoDataExcept(QRect exceptRect)
Set the whole block to no data except specified rectangle.
A class to represent a 2D point.
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)
QgsRasterDataProvider * createFunction_t(const QString &, const QString &, int, Qgis::DataType, int, int, double *, const QgsCoordinateReferenceSystem &, QStringList)
bool setIsNoData(int row, int column)
Set no data on pixel.
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.
double width() const
Returns the width of the rectangle.
void setYMinimum(double y)
Set the minimum y value.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
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.
bool isEmpty() const
Returns true if block is empty, i.e.
QgsRasterDataProvider()
Provider capabilities.
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).
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).
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 applyScaleOffset(double scale, double offset)
Apply band scale and offset to raster block values.
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.