32#include "moc_qgsrasterinterface.cpp"
48 int sampleSize )
const
50 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ), 4 );
64 statistics.
extent = finalExtent;
70 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
77 if ( xRes < srcXRes ) xRes = srcXRes;
78 if ( yRes < srcYRes ) yRes = srcYRes;
80 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
82 statistics.
width =
static_cast <int>( std::ceil( finalExtent.
width() / xRes ) );
83 statistics.
height =
static_cast <int>( std::ceil( finalExtent.
height() / yRes ) );
94 statistics.
width = 1000;
98 QgsDebugMsgLevel( QStringLiteral(
"theStatistics.width = %1 statistics.height = %2" ).arg( statistics.
width ).arg( statistics.
height ), 4 );
106 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg(
static_cast<int>( stats ) ).arg( sampleSize ), 4 );
115 if ( stats.contains( myRasterBandStats ) )
129 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg(
static_cast<int>( stats ) ).arg( sampleSize ), 4 );
139 if ( stats.contains( myRasterBandStats ) )
147 const int myWidth = myRasterBandStats.
width;
148 const int myHeight = myRasterBandStats.
height;
154 if ( myXBlockSize == 0 )
158 if ( myYBlockSize == 0 )
163 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
164 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
166 const double myXRes = myExtent.
width() / myWidth;
167 const double myYRes = myExtent.
height() / myHeight;
172 double mySumOfSquares = 0;
174 bool myFirstIterationFlag =
true;
175 bool isNoData =
false;
176 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
178 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
181 return myRasterBandStats;
183 QgsDebugMsgLevel( QStringLiteral(
"myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
184 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
185 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
187 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
188 const double xmax = xmin + myBlockWidth * myXRes;
189 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
190 const double ymax = ymin - myBlockHeight * myYRes;
192 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
194 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
197 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
199 const double myValue = blk->valueAndNoData( i, isNoData );
203 myRasterBandStats.
sum += myValue;
206 if ( !std::isfinite( myValue ) )
continue;
208 if ( myFirstIterationFlag )
210 myFirstIterationFlag =
false;
227 const double myDelta = myValue - myMean;
229 mySumOfSquares += myDelta * ( myValue - myMean );
242 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / (
static_cast< double >( myRasterBandStats.
elementCount ) - 1 ) );
244 QgsDebugMsgLevel( QStringLiteral(
"************ STATS **************" ), 4 );
254 return myRasterBandStats;
265 double minimum,
double maximum,
268 bool includeOutOfRange )
273 histogram.includeOutOfRange = includeOutOfRange;
318 if ( sampleSize > 0 )
322 xRes = yRes = std::sqrt( (
static_cast<double>( finalExtent.
width( ) ) * finalExtent.
height() ) / sampleSize );
329 if ( xRes < srcXRes ) xRes = srcXRes;
330 if ( yRes < srcYRes ) yRes = srcYRes;
332 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
334 histogram.width =
static_cast <int>( finalExtent.
width() / xRes );
352 qint64 myBinCount = binCount;
353 if ( myBinCount == 0 )
380 myBinCount =
static_cast<qint64
>(
histogram.width ) *
static_cast<qint64
>(
histogram.height );
385 histogram.binCount =
static_cast<int>( std::min( 10000000LL, myBinCount ) );
396 double minimum,
double maximum,
399 bool includeOutOfRange )
401 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
407 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
423 double minimum,
double maximum,
428 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
431 initHistogram( myHistogram, bandNo, binCount, minimum, maximum,
extent, sampleSize, includeOutOfRange );
444 const int myBinCount = myHistogram.
binCount;
445 const int myWidth = myHistogram.
width;
446 const int myHeight = myHistogram.
height;
452 if ( myXBlockSize == 0 )
456 if ( myYBlockSize == 0 )
461 const int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
462 const int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
464 const double myXRes = myExtent.
width() / myWidth;
465 const double myYRes = myExtent.
height() / myHeight;
467 double myMinimum = myHistogram.
minimum;
468 double myMaximum = myHistogram.
maximum;
472 const double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
473 myMinimum -= 0.1 * myerval;
474 myMaximum += 0.1 * myerval;
476 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
478 const double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
481 bool isNoData =
false;
482 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
484 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
489 const int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
490 const int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
492 const double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
493 const double xmax = xmin + myBlockWidth * myXRes;
494 const double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
495 const double ymax = ymin - myBlockHeight * myYRes;
497 const QgsRectangle myPartExtent( xmin, ymin, xmax, ymax );
499 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
502 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
504 const double myValue = blk->valueAndNoData( i, isNoData );
510 int myBinIndex =
static_cast <int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
512 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
516 if ( myBinIndex < 0 ) myBinIndex = 0;
517 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
525 myHistogram.
valid =
true;
530 for ( std::size_t i = 0; i < std::min< std::size_t >( myHistogram.
histogramVector.size(), 500 ); i++ )
532 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
534 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
541 double lowerCount,
double upperCount,
542 double &lowerValue,
double &upperValue,
546 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
551 lowerValue = std::numeric_limits<double>::quiet_NaN();
552 upperValue = std::numeric_limits<double>::quiet_NaN();
566 const int myMinCount =
static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
567 const int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
568 bool myLowerFound =
false;
569 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
570 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
572 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
575 myCount += myBinValue;
576 if ( !myLowerFound && myCount > myMinCount )
578 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
580 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
582 if ( myCount >= myMaxCount )
584 upperValue = myHistogram.
minimum + myBin * myBinXStep;
585 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
595 if ( !std::isnan( lowerValue ) )
596 lowerValue = std::floor( lowerValue );
597 if ( !std::isnan( upperValue ) )
598 upperValue = std::ceil( upperValue );
604 QStringList abilitiesList;
614 abilitiesList += tr(
"Identify" );
619 abilitiesList += tr(
"Build Pyramids" );
622 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QLatin1String(
", " ) ), 4 );
624 return abilitiesList.join( QLatin1String(
", " ) );
630 return mInput->generateBandName( bandNumber );
633 return tr(
"Band" ) + QStringLiteral(
" %1" ) .arg( bandNumber, 1 + (
bandCount() > 0 ?
static_cast< int >( std::log10(
static_cast< double >(
bandCount() ) ) ) : 0 ), 10, QChar(
'0' ) );
639 return mInput->colorInterpretationName( bandNo );
648 if ( colorInterp != tr(
"Undefined" ) )
650 name.append( QStringLiteral(
" (%1)" ).arg( colorInterp ) );
662 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)