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.