32 #define ERR(message) QgsError(message, "Raster provider")
48 QgsDebugMsgLevel( QStringLiteral(
"bandNo = %1 width = %2 height = %3" ).arg( bandNo ).arg( width ).arg( height ), 4 );
51 std::unique_ptr< QgsRasterBlock >
block = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), width, height );
59 QgsDebugMsg( QStringLiteral(
"Couldn't create raster block" ) );
60 block->
setError( { tr(
"Couldn't create raster block." ), QStringLiteral(
"Raster" ) } );
62 return block.release();
70 QgsDebugMsg( QStringLiteral(
"Extent outside provider extent" ) );
71 block->
setError( { tr(
"Extent outside provider extent." ), QStringLiteral(
"Raster" ) } );
74 return block.release();
77 double xRes = boundingBox.
width() / width;
78 double yRes = boundingBox.
height() / height;
79 double tmpXRes, tmpYRes;
80 double providerXRes = 0;
81 double providerYRes = 0;
86 tmpXRes = std::max( providerXRes, xRes );
87 tmpYRes = std::max( providerYRes, yRes );
97 if ( tmpExtent != boundingBox ||
98 tmpXRes > xRes || tmpYRes > yRes )
102 if ( !
extent().contains( boundingBox ) )
109 int fromRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMaximum() ) / yRes );
110 int toRow = std::round( ( boundingBox.
yMaximum() - tmpExtent.
yMinimum() ) / yRes ) - 1;
111 int fromCol = std::round( ( tmpExtent.
xMinimum() - boundingBox.
xMinimum() ) / xRes );
112 int toCol = std::round( ( tmpExtent.
xMaximum() - boundingBox.
xMinimum() ) / xRes ) - 1;
114 QgsDebugMsgLevel( QStringLiteral(
"fromRow = %1 toRow = %2 fromCol = %3 toCol = %4" ).arg( fromRow ).arg( toRow ).arg( fromCol ).arg( toCol ), 4 );
116 if ( fromRow < 0 || fromRow >= height || toRow < 0 || toRow >= height ||
117 fromCol < 0 || fromCol >= width || toCol < 0 || toCol >= width )
120 QgsDebugMsg( QStringLiteral(
"Row or column limits out of range" ) );
121 block->
setError( { tr(
"Row or column limits out of range" ), QStringLiteral(
"Raster" ) } );
123 return block.release();
128 if ( tmpXRes > xRes )
130 int col = std::floor( ( tmpExtent.
xMinimum() -
extent().xMinimum() ) / providerXRes );
132 col = std::ceil( ( tmpExtent.
xMaximum() -
extent().xMinimum() ) / providerXRes );
135 if ( tmpYRes > yRes )
137 int row = std::floor( (
extent().yMaximum() - tmpExtent.
yMaximum() ) / providerYRes );
139 row = std::ceil( (
extent().yMaximum() - tmpExtent.
yMinimum() ) / providerYRes );
142 int tmpWidth = std::round( tmpExtent.
width() / tmpXRes );
143 int tmpHeight = std::round( tmpExtent.
height() / tmpYRes );
144 tmpXRes = tmpExtent.
width() / tmpWidth;
145 tmpYRes = tmpExtent.
height() / tmpHeight;
147 QgsDebugMsgLevel( QStringLiteral(
"Reading smaller block tmpWidth = %1 height = %2" ).arg( tmpWidth ).arg( tmpHeight ), 4 );
150 std::unique_ptr< QgsRasterBlock > tmpBlock = qgis::make_unique< QgsRasterBlock >(
dataType( bandNo ), tmpWidth, tmpHeight );
156 if ( !
readBlock( bandNo, tmpExtent, tmpWidth, tmpHeight, tmpBlock->bits(), feedback ) )
158 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
159 block->
setError( { tr(
"Error occurred while reading block." ), QStringLiteral(
"Raster" ) } );
162 return block.release();
167 double xMin = boundingBox.
xMinimum();
168 double yMax = boundingBox.
yMaximum();
169 double tmpXMin = tmpExtent.
xMinimum();
170 double tmpYMax = tmpExtent.
yMaximum();
172 for (
int row = fromRow; row <= toRow; row++ )
174 double y = yMax - ( row + 0.5 ) * yRes;
175 int tmpRow = std::floor( ( tmpYMax - y ) / tmpYRes );
177 for (
int col = fromCol; col <= toCol; col++ )
179 double x = xMin + ( col + 0.5 ) * xRes;
180 int tmpCol = std::floor( ( x - tmpXMin ) / tmpXRes );
182 if ( tmpRow < 0 || tmpRow >= tmpHeight || tmpCol < 0 || tmpCol >= tmpWidth )
184 QgsDebugMsg( QStringLiteral(
"Source row or column limits out of range" ) );
186 block->
setError( { tr(
"Source row or column limits out of range." ), QStringLiteral(
"Raster" ) } );
188 return block.release();
194 char *tmpBits = tmpBlock->
bits( tmpIndex );
198 QgsDebugMsg( QStringLiteral(
"Cannot get input block data tmpRow = %1 tmpCol = %2 tmpIndex = %3." ).arg( tmpRow ).arg( tmpCol ).arg( tmpIndex ) );
203 QgsDebugMsg( QStringLiteral(
"Cannot set output block data." ) );
206 memcpy( bits, tmpBits, pixelSize );
214 QgsDebugMsg( QStringLiteral(
"Error occurred while reading block" ) );
216 block->
setError( { tr(
"Error occurred while reading block." ), QStringLiteral(
"Raster" ) } );
218 return block.release();
226 return block.release();
238 QgsDataProvider::ReadFlags flags )
267 QMap<int, QVariant> results;
271 QgsDebugMsg( QStringLiteral(
"Format not supported" ) );
275 if ( !
extent().contains( point ) )
278 for (
int bandNo = 1; bandNo <=
bandCount(); bandNo++ )
280 results.insert( bandNo, QVariant() );
299 double xres = ( finalExtent.
width() ) / width;
300 double yres = ( finalExtent.
height() ) / height;
302 int col =
static_cast< int >( std::floor( ( point.
x() - finalExtent.
xMinimum() ) / xres ) );
303 int row =
static_cast< int >( std::floor( ( finalExtent.
yMaximum() - point.
y() ) / yres ) );
305 double xMin = finalExtent.
xMinimum() + col * xres;
306 double xMax = xMin + xres;
307 double yMax = finalExtent.
yMaximum() - row * yres;
308 double yMin = yMax - yres;
313 std::unique_ptr< QgsRasterBlock > bandBlock(
block( i, pixelExtent, 1, 1 ) );
317 double value = bandBlock->value( 0 );
319 results.insert( i, value );
323 results.insert( i, QVariant() );
330 bool *ok,
const QgsRectangle &boundingBox,
int width,
int height,
int dpi )
336 const QVariant value = res.results().value( band );
338 if ( !value.isValid() )
339 return std::numeric_limits<double>::quiet_NaN();
344 return value.toDouble( ok );
349 return QStringLiteral(
"text/plain" );
358 QgsDebugMsg( QStringLiteral(
"writeBlock() called on read-only provider." ) );
368 if ( methods.isEmpty() )
370 QgsDebugMsg( QStringLiteral(
"provider pyramidResamplingMethods returned no methods" ) );
379 if ( myPyramidList.isEmpty() )
382 QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
383 for ( myRasterPyramidIterator = myPyramidList.begin();
384 myRasterPyramidIterator != myPyramidList.end();
385 ++myRasterPyramidIterator )
387 if ( myRasterPyramidIterator->exists )
404 QgsDebugMsgLevel( QStringLiteral(
"set %1 band %1 no data ranges" ).arg( noData.size() ), 4 );
428 return mTemporalCapabilities.get();
433 return mTemporalCapabilities.get();
438 const QString &format,
int nBands,
440 int width,
int height,
double *geoTransform,
442 const QStringList &createOptions )
448 height, geoTransform,
crs, createOptions );
451 QgsDebugMsg(
"Cannot resolve 'createRasterDataProviderFunction' function in " + providerKey +
" provider" );
465 return QStringLiteral(
"Value" );
467 return QStringLiteral(
"Text" );
469 return QStringLiteral(
"Html" );
471 return QStringLiteral(
"Feature" );
473 return QStringLiteral(
"Undefined" );
482 return tr(
"Value" );
488 return tr(
"Feature" );
490 return QStringLiteral(
"Undefined" );
522 return QList< double >();
557 if ( mTemporalCapabilities && other.mTemporalCapabilities )
559 *mTemporalCapabilities = *other.mTemporalCapabilities;
565 if ( str == QLatin1String(
"bilinear" ) )
569 else if ( str == QLatin1String(
"cubic" ) )
573 else if ( str == QLatin1String(
"cubicSpline" ) )
577 else if ( str == QLatin1String(
"lanczos" ) )
581 else if ( str == QLatin1String(
"average" ) )
585 else if ( str == QLatin1String(
"mode" ) )
589 else if ( str == QLatin1String(
"gauss" ) )
598 if ( filterElem.isNull() )
603 QDomElement resamplingElement = filterElem.firstChildElement( QStringLiteral(
"resampling" ) );
604 if ( !resamplingElement.isNull() )
606 setMaxOversampling( resamplingElement.attribute( QStringLiteral(
"maxOversampling" ), QStringLiteral(
"2.0" ) ).toDouble() );
607 setZoomedInResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral(
"zoomedInResamplingMethod" ) ) ) );
608 setZoomedOutResamplingMethod( resamplingMethodFromString( resamplingElement.attribute( QStringLiteral(
"zoomedOutResamplingMethod" ) ) ) );
618 return QStringLiteral(
"nearestNeighbour" );
620 return QStringLiteral(
"bilinear" );
622 return QStringLiteral(
"cubic" );
624 return QStringLiteral(
"cubicSpline" );
626 return QStringLiteral(
"lanczos" );
628 return QStringLiteral(
"average" );
630 return QStringLiteral(
"mode" );
632 return QStringLiteral(
"gauss" );
635 return QStringLiteral(
"nearestNeighbour" );
640 QDomElement providerElement = doc.createElement( QStringLiteral(
"provider" ) );
641 parentElem.appendChild( providerElement );
643 QDomElement resamplingElement = doc.createElement( QStringLiteral(
"resampling" ) );
644 providerElement.appendChild( resamplingElement );
646 resamplingElement.setAttribute( QStringLiteral(
"enabled" ),
649 resamplingElement.setAttribute( QStringLiteral(
"zoomedInResamplingMethod" ),
652 resamplingElement.setAttribute( QStringLiteral(
"zoomedOutResamplingMethod" ),
655 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 QList< QgsRasterPyramid > buildPyramidList(QList< int > overviewList=QList< int >())
Returns the raster layers pyramid list.
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 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 populated histogram.
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.
int dataTypeSize(int bandNo)
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.
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.
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.