33#include "moc_qgsrasterinterface.cpp"
35using namespace Qt::StringLiterals;
51 int sampleSize )
const
53 QgsDebugMsgLevel( u
"theBandNo = %1 sampleSize = %2"_s.arg( bandNo ).arg( sampleSize ), 4 );
67 statistics.
extent = finalExtent;
73 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
80 if ( xRes < srcXRes ) xRes = srcXRes;
81 if ( yRes < srcYRes ) yRes = srcYRes;
85 statistics.
width =
static_cast <int>( std::ceil( finalExtent.
width() / xRes ) );
86 statistics.
height =
static_cast <int>( std::ceil( finalExtent.
height() / yRes ) );
97 statistics.
width = 1000;
109 QgsDebugMsgLevel( u
"theBandNo = %1 stats = %2 sampleSize = %3"_s.arg( bandNo ).arg(
static_cast<int>( stats ) ).arg( sampleSize ), 4 );
118 if ( stats.contains( myRasterBandStats ) )
132 QgsDebugMsgLevel( u
"theBandNo = %1 stats = %2 sampleSize = %3"_s.arg( bandNo ).arg(
static_cast<int>( stats ) ).arg( sampleSize ), 4 );
142 if ( stats.contains( myRasterBandStats ) )
150 const int myWidth = myRasterBandStats.
width;
151 const int myHeight = myRasterBandStats.
height;
157 if ( myXBlockSize == 0 )
161 if ( myYBlockSize == 0 )
166 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
167 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
169 const double myXRes = myExtent.
width() / myWidth;
170 const double myYRes = myExtent.
height() / myHeight;
175 double mySumOfSquares = 0;
177 bool myFirstIterationFlag =
true;
178 bool isNoData =
false;
179 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
181 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
184 return myRasterBandStats;
186 QgsDebugMsgLevel( u
"myYBlock = %1 myXBlock = %2"_s.arg( myYBlock ).arg( myXBlock ), 4 );
187 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
188 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
190 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
191 const double xmax = xmin + myBlockWidth * myXRes;
192 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
193 const double ymax = ymin - myBlockHeight * myYRes;
195 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
197 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
200 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
202 const double myValue = blk->valueAndNoData( i, isNoData );
206 myRasterBandStats.
sum += myValue;
209 if ( !std::isfinite( myValue ) )
continue;
211 if ( myFirstIterationFlag )
213 myFirstIterationFlag =
false;
230 const double myDelta = myValue - myMean;
232 mySumOfSquares += myDelta * ( myValue - myMean );
245 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / (
static_cast< double >( myRasterBandStats.
elementCount ) - 1 ) );
257 return myRasterBandStats;
268 double minimum,
double maximum,
271 bool includeOutOfRange )
276 histogram.includeOutOfRange = includeOutOfRange;
321 if ( sampleSize > 0 )
325 xRes = yRes = std::sqrt( (
static_cast<double>( finalExtent.
width( ) ) * finalExtent.
height() ) / sampleSize );
332 if ( xRes < srcXRes ) xRes = srcXRes;
333 if ( yRes < srcYRes ) yRes = srcYRes;
337 histogram.width =
static_cast <int>( finalExtent.
width() / xRes );
355 qint64 myBinCount = binCount;
356 if ( myBinCount == 0 )
383 myBinCount =
static_cast<qint64
>(
histogram.width ) *
static_cast<qint64
>(
histogram.height );
388 histogram.binCount =
static_cast<int>( std::min( 10000000LL, myBinCount ) );
399 double minimum,
double maximum,
402 bool includeOutOfRange )
404 QgsDebugMsgLevel( u
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5"_s.arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
410 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
426 double minimum,
double maximum,
431 QgsDebugMsgLevel( u
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5"_s.arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
434 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
447 const int myBinCount = myHistogram.
binCount;
448 const int myWidth = myHistogram.
width;
449 const int myHeight = myHistogram.
height;
455 if ( myXBlockSize == 0 )
459 if ( myYBlockSize == 0 )
464 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
465 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
467 const double myXRes = myExtent.
width() / myWidth;
468 const double myYRes = myExtent.
height() / myHeight;
470 double myMinimum = myHistogram.
minimum;
471 double myMaximum = myHistogram.
maximum;
475 const double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
476 myMinimum -= 0.1 * myerval;
477 myMaximum += 0.1 * myerval;
479 QgsDebugMsgLevel( u
"binCount = %1 myMinimum = %2 myMaximum = %3"_s.arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
481 const double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
484 bool isNoData =
false;
485 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
487 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
492 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
493 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
495 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
496 const double xmax = xmin + myBlockWidth * myXRes;
497 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
498 const double ymax = ymin - myBlockHeight * myYRes;
500 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
502 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
505 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
507 const double myValue = blk->valueAndNoData( i, isNoData );
513 int myBinIndex =
static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
515 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
519 if ( myBinIndex < 0 ) myBinIndex = 0;
520 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
528 myHistogram.
valid =
true;
533 for ( std::size_t i = 0; i < std::min< std::size_t >( myHistogram.
histogramVector.size(), 500 ); i++ )
535 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
544 double lowerCount,
double upperCount,
545 double &lowerValue,
double &upperValue,
549 QgsDebugMsgLevel( u
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4"_s.arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
554 lowerValue = std::numeric_limits<double>::quiet_NaN();
555 upperValue = std::numeric_limits<double>::quiet_NaN();
569 const int myMinCount =
static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
570 const int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
571 bool myLowerFound =
false;
573 QgsDebugMsgLevel( u
"myMinCount = %1 myMaxCount = %2"_s.arg( myMinCount ).arg( myMaxCount ), 4 );
575 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
578 myCount += myBinValue;
579 if ( !myLowerFound && myCount > myMinCount )
581 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
583 QgsDebugMsgLevel( u
"found lowerValue %1 at bin %2"_s.arg( lowerValue ).arg( myBin ), 4 );
585 if ( myCount >= myMaxCount )
587 upperValue = myHistogram.
minimum + myBin * myBinXStep;
588 QgsDebugMsgLevel( u
"found upperValue %1 at bin %2"_s.arg( upperValue ).arg( myBin ), 4 );
598 if ( !std::isnan( lowerValue ) )
599 lowerValue = std::floor( lowerValue );
600 if ( !std::isnan( upperValue ) )
601 upperValue = std::ceil( upperValue );
607 QStringList abilitiesList;
617 abilitiesList += tr(
"Identify" );
622 abilitiesList += tr(
"Build Pyramids" );
627 return abilitiesList.join(
", "_L1 );
633 return mInput->generateBandName( bandNumber );
636 return tr(
"Band" ) + u
" %1"_s .arg( bandNumber, 1 + (
bandCount() > 0 ?
static_cast< int >( std::log10(
static_cast< double >(
bandCount() ) ) ) : 0 ), 10, QChar(
'0' ) );
642 return mInput->colorInterpretationName( bandNo );
651 if ( colorInterp != tr(
"Undefined" ) )
653 name.append( u
" (%1)"_s.arg( colorInterp ) );
665 return mRenderContext;
QFlags< RasterInterfaceCapability > RasterInterfaceCapabilities
Raster interface capabilities.
@ BuildPyramids
Supports building of pyramids (overviews) (Deprecated since QGIS 3.38 – use RasterProviderCapability:...
@ NoCapabilities
No capabilities.
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
@ Identify
At least one identify format supported.
QFlags< RasterBandStatistic > RasterBandStatistics
Statistics to be calculated for raster bands.
@ All
All available statistics.
DataType
Raster data types.
@ Int16
Sixteen bit signed integer (qint16).
@ UInt16
Sixteen bit unsigned integer (quint16).
@ Byte
Eight bit unsigned integer (quint8).
@ Int32
Thirty two bit signed integer (qint32).
@ UInt32
Thirty two bit unsigned integer (quint32).
bool isCanceled() const
Tells whether the operation has been canceled already.
The RasterBandStats struct is a container for statistics about a single raster band.
qgssize elementCount
The number of not no data cells in the band.
int bandNumber
The gdal band number (starts at 1).
double sumOfSquares
The sum of the squares. Used to calculate standard deviation.
int height
Number of rows used to calc statistics.
double mean
The mean cell value for the band. NO_DATA values are excluded.
QgsRectangle extent
Extent used to calc statistics.
double stdDev
The standard deviation of the cell values.
double minimumValue
The minimum cell value in the raster band.
int width
Number of columns used to calc statistics.
double sum
The sum of all cells in the band. NO_DATA values are excluded.
Qgis::RasterBandStatistics statsGathered
Collected statistics.
double maximumValue
The maximum cell value in the raster band.
double range
The range is the distance between min & max.
Feedback object tailored for raster block reading.
QgsRenderContext renderContext() const
Returns the render context of the associated block reading.
void setRenderContext(const QgsRenderContext &renderContext)
Sets the render context of the associated block reading.
A container for a histogram of a single raster band.
double minimum
The minimum histogram value.
double maximum
The maximum histogram value.
QgsRectangle extent
Extent used to calc histogram.
int nonNullCount
The number of non NULL cells used to calculate histogram.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
int height
Number of rows used to calc histogram.
int width
Number of columns used to calc histogram.
bool valid
Histogram is valid.
int binCount
Number of bins (intervals,buckets) in histogram.
virtual void cumulativeCut(int bandNo, double lowerCount, double upperCount, double &lowerValue, double &upperValue, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Find values for cumulative pixel count cut.
virtual Qgis::RasterInterfaceCapabilities capabilities() const
Returns the capabilities supported by the interface.
virtual int yBlockSize() const
virtual QgsRasterBlock * block(int bandNo, const QgsRectangle &extent, int width, int height, QgsRasterBlockFeedback *feedback=nullptr)=0
Read block of data using given extent and size.
Q_DECL_DEPRECATED void initStatistics(QgsRasterBandStats &statistics, int bandNo, int stats, const QgsRectangle &boundingBox=QgsRectangle(), int binCount=0) const
Fill in statistics defaults if not specified.
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
Q_DECL_DEPRECATED QString capabilitiesString() const
Returns the raster interface capabilities in friendly format.
void initHistogram(QgsRasterHistogram &histogram, int bandNo, int binCount, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &boundingBox=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false)
Fill in histogram defaults if not specified.
virtual int xSize() const
Gets raster size.
virtual QString generateBandName(int bandNumber) const
helper function to create zero padded band names
QgsRasterInterface(QgsRasterInterface *input=nullptr)
Q_DECL_DEPRECATED QgsRasterBandStats bandStatistics(int bandNo, int stats, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual Qgis::DataType sourceDataType(int bandNo) const
Returns source data type for the band specified by number, source data type may be shorter than dataT...
virtual int xBlockSize() const
Gets block size.
virtual int bandCount() const =0
Gets number of bands.
virtual bool hasHistogram(int bandNo, int binCount, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false)
Returns true if histogram is available (cached, already calculated).
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
Q_DECL_DEPRECATED bool hasStatistics(int bandNo, int stats, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Returns true if histogram is available (cached, already calculated).
QgsRasterInterface * mInput
virtual int ySize() const
virtual QgsRectangle extent() const
Gets the extent of the interface.
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
virtual QString colorInterpretationName(int bandNumber) const
Returns the name of the color interpretation for the specified bandNumber.
virtual QgsRasterInterface * input() const
Current input.
virtual QgsRasterHistogram histogram(int bandNo, int binCount=0, double minimum=std::numeric_limits< double >::quiet_NaN(), double maximum=std::numeric_limits< double >::quiet_NaN(), const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, bool includeOutOfRange=false, QgsRasterBlockFeedback *feedback=nullptr)
Returns a band histogram.
A rectangle specified with double values.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
Contains information about the context of a rendering operation.
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...
#define QgsDebugMsgLevel(str, level)