23 #include <QStringList> 42 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 sampleSize = %2" ).arg( bandNo ).arg( sampleSize ), 4 );
56 statistics.
extent = finalExtent;
62 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
69 if ( xRes < srcXRes ) xRes = srcXRes;
70 if ( yRes < srcYRes ) yRes = srcYRes;
72 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
74 statistics.
width = static_cast <
int>( std::ceil( finalExtent.
width() / xRes ) );
75 statistics.
height = static_cast <
int>( std::ceil( finalExtent.
height() / yRes ) );
86 statistics.
width = 1000;
90 QgsDebugMsgLevel( QStringLiteral(
"theStatistics.width = %1 statistics.height = %2" ).arg( statistics.
width ).arg( statistics.
height ), 4 );
98 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
102 initStatistics( myRasterBandStats, bandNo, stats, extent, sampleSize );
106 if ( stats.
contains( myRasterBandStats ) )
120 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
125 initStatistics( myRasterBandStats, bandNo, stats, extent, sampleSize );
129 if ( stats.
contains( myRasterBandStats ) )
137 int myWidth = myRasterBandStats.
width;
138 int myHeight = myRasterBandStats.
height;
144 if ( myXBlockSize == 0 )
148 if ( myYBlockSize == 0 )
153 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
154 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
156 double myXRes = myExtent.
width() / myWidth;
157 double myYRes = myExtent.
height() / myHeight;
162 double mySumOfSquares = 0;
164 bool myFirstIterationFlag =
true;
165 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
167 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
170 return myRasterBandStats;
172 QgsDebugMsgLevel( QStringLiteral(
"myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
173 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
174 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
176 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
177 double xmax = xmin + myBlockWidth * myXRes;
178 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
179 double ymax = ymin - myBlockHeight * myYRes;
183 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
186 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
188 if ( blk->isNoData( i ) )
continue;
190 double myValue = blk->value( i );
191 myRasterBandStats.
sum += myValue;
194 if ( !std::isfinite( myValue ) )
continue;
196 if ( myFirstIterationFlag )
198 myFirstIterationFlag =
false;
215 double myDelta = myValue - myMean;
217 mySumOfSquares += myDelta * ( myValue - myMean );
230 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.
elementCount - 1 ) );
232 QgsDebugMsgLevel( QStringLiteral(
"************ STATS **************" ), 4 );
242 return myRasterBandStats;
248 double minimum,
double maximum,
251 bool includeOutOfRange )
260 if ( std::isnan( histogram.
minimum ) )
277 if ( std::isnan( histogram.
maximum ) )
299 histogram.
extent = finalExtent;
301 if ( sampleSize > 0 )
305 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
312 if ( xRes < srcXRes ) xRes = srcXRes;
313 if ( yRes < srcYRes ) yRes = srcYRes;
315 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
317 histogram.
width = static_cast <
int>( finalExtent.
width() / xRes );
318 histogram.
height = static_cast <
int>( finalExtent.
height() / yRes );
329 histogram.
width = 1000;
333 QgsDebugMsgLevel( QStringLiteral(
"theHistogram.width = %1 histogram.height = %2" ).arg( histogram.
width ).arg( histogram.
height ), 4 );
335 int myBinCount = binCount;
336 if ( myBinCount == 0 )
348 if ( myBinCount > 1000 ) myBinCount = 1000;
357 myBinCount = int( std::ceil( histogram.
maximum - histogram.
minimum + 1 ) );
368 double minimum,
double maximum,
371 bool includeOutOfRange )
373 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
379 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
383 if ( histogram == myHistogram )
394 double minimum,
double maximum,
399 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
402 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
407 if ( histogram == myHistogram )
414 int myBinCount = myHistogram.
binCount;
415 int myWidth = myHistogram.
width;
416 int myHeight = myHistogram.
height;
422 if ( myXBlockSize == 0 )
426 if ( myYBlockSize == 0 )
431 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
432 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
434 double myXRes = myExtent.
width() / myWidth;
435 double myYRes = myExtent.
height() / myHeight;
437 double myMinimum = myHistogram.
minimum;
438 double myMaximum = myHistogram.
maximum;
442 double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
443 myMinimum -= 0.1 * myerval;
444 myMaximum += 0.1 * myerval;
446 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
448 double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
451 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
453 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
458 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
459 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
461 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
462 double xmax = xmin + myBlockWidth * myXRes;
463 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
464 double ymax = ymin - myBlockHeight * myYRes;
468 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
471 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
473 if ( blk->isNoData( i ) )
477 double myValue = blk->value( i );
479 int myBinIndex = static_cast <
int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
481 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
485 if ( myBinIndex < 0 ) myBinIndex = 0;
486 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
494 myHistogram.
valid =
true;
499 for (
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
501 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
503 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
510 double lowerCount,
double upperCount,
511 double &lowerValue,
double &upperValue,
515 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
520 lowerValue = std::numeric_limits<double>::quiet_NaN();
521 upperValue = std::numeric_limits<double>::quiet_NaN();
535 int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
536 int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
537 bool myLowerFound =
false;
538 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
539 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
541 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
544 myCount += myBinValue;
545 if ( !myLowerFound && myCount > myMinCount )
547 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
549 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
551 if ( myCount >= myMaxCount )
553 upperValue = myHistogram.
minimum + myBin * myBinXStep;
554 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
564 if ( !std::isnan( lowerValue ) )
565 lowerValue = std::floor( lowerValue );
566 if ( !std::isnan( upperValue ) )
567 upperValue = std::ceil( upperValue );
573 QStringList abilitiesList;
583 abilitiesList += tr(
"Identify" );
588 abilitiesList += tr(
"Create Datasources" );
593 abilitiesList += tr(
"Remove Datasources" );
598 abilitiesList += tr(
"Build Pyramids" );
601 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QStringLiteral(
", " ) ), 4 );
603 return abilitiesList.join( QStringLiteral(
", " ) );
bool isCanceled() const
Tells whether the operation has been canceled already.
A rectangle specified with double values.
Thirty two bit signed integer (qint32)
bool isEmpty() const
Returns true if the rectangle is empty.
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)
double sum
The sum of all cells in the band. NO_DATA values are excluded.
int bandNumber
The gdal band number (starts at 1)
int width
Number of columns used to calc histogram.
int height
Number of rows used to calc statistics.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
int bandNumber
The gdal band number (starts at 1)
virtual int xBlockSize() const
Gets block size.
double minimum
The minimum histogram value.
Thirty two bit unsigned integer (quint32)
virtual int yBlockSize() const
double maximumValue
The maximum cell value in the raster band.
QString capabilitiesString() const
Returns the above in friendly format.
int height
Number of rows used to calc histogram.
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.
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.
Sixteen bit signed integer (qint16)
virtual int ySize() const
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc. not collected 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...
QgsRectangle extent
Extent used to calc statistics.
double stdDev
The standard deviation of the cell values.
The RasterBandStats struct is a container for statistics about a single raster band.
double mean
The mean cell value for the band. NO_DATA values are excluded.
void initStatistics(QgsRasterBandStats &statistics, int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &boundingBox=QgsRectangle(), int binCount=0)
Fill in statistics defaults if not specified.
QgsRasterInterface(QgsRasterInterface *input=nullptr)
#define QgsDebugMsgLevel(str, level)
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.
QList< QgsRasterHistogram > mHistograms
List of cached histograms, all bands mixed.
qgssize elementCount
The number of not no data cells in the band.
virtual bool hasStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0)
Returns true if histogram is available (cached, already calculated).
int statsGathered
Collected statistics.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
Sixteen bit unsigned integer (quint16)
Base class for processing filters like renderers, reprojector, resampler etc.
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...
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double maximum
The maximum histogram value.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
virtual int xSize() const
Gets raster size.
virtual QgsRectangle extent() const
Gets the extent of the interface.
double range
The range is the distance between min & max.
double minimumValue
The minimum cell value in the raster band.
The QgsRasterHistogram is a container for histogram of a single raster band.
int binCount
Number of bins (intervals,buckets) in histogram.
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.
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
bool valid
Histogram is valid.
double width() const
Returns the width of the rectangle.
QgsRasterInterface * mInput
QgsRectangle extent
Extent used to calc histogram.
Feedback object tailored for raster block reading.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Eight bit unsigned integer (quint8)
bool includeOutOfRange
Whether histogram includes out of range values (in first and last bin)
double height() const
Returns the height of the rectangle.
double sumOfSquares
The sum of the squares. Used to calculate standard deviation.
int width
Number of columns used to calc statistics.
int nonNullCount
The number of non NULL cells used to calculate histogram.