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 );
107 if ( stats.contains( myRasterBandStats ) )
121 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
126 initStatistics( myRasterBandStats, bandNo, stats, extent, sampleSize );
131 if ( stats.contains( myRasterBandStats ) )
139 int myWidth = myRasterBandStats.
width;
140 int myHeight = myRasterBandStats.
height;
146 if ( myXBlockSize == 0 )
150 if ( myYBlockSize == 0 )
155 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
156 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
158 double myXRes = myExtent.
width() / myWidth;
159 double myYRes = myExtent.
height() / myHeight;
164 double mySumOfSquares = 0;
166 bool myFirstIterationFlag =
true;
167 bool isNoData =
false;
168 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
170 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
173 return myRasterBandStats;
175 QgsDebugMsgLevel( QStringLiteral(
"myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
176 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
177 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
179 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
180 double xmax = xmin + myBlockWidth * myXRes;
181 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
182 double ymax = ymin - myBlockHeight * myYRes;
186 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
189 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
191 double myValue = blk->valueAndNoData( i, isNoData );
195 myRasterBandStats.
sum += myValue;
198 if ( !std::isfinite( myValue ) )
continue;
200 if ( myFirstIterationFlag )
202 myFirstIterationFlag =
false;
219 double myDelta = myValue - myMean;
221 mySumOfSquares += myDelta * ( myValue - myMean );
234 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.
elementCount - 1 ) );
236 QgsDebugMsgLevel( QStringLiteral(
"************ STATS **************" ), 4 );
246 return myRasterBandStats;
252 double minimum,
double maximum,
255 bool includeOutOfRange )
264 if ( std::isnan( histogram.
minimum ) )
281 if ( std::isnan( histogram.
maximum ) )
303 histogram.
extent = finalExtent;
305 if ( sampleSize > 0 )
309 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
316 if ( xRes < srcXRes ) xRes = srcXRes;
317 if ( yRes < srcYRes ) yRes = srcYRes;
319 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
321 histogram.
width = static_cast <
int>( finalExtent.
width() / xRes );
322 histogram.
height = static_cast <
int>( finalExtent.
height() / yRes );
333 histogram.
width = 1000;
337 QgsDebugMsgLevel( QStringLiteral(
"theHistogram.width = %1 histogram.height = %2" ).arg( histogram.
width ).arg( histogram.
height ), 4 );
339 int myBinCount = binCount;
340 if ( myBinCount == 0 )
352 if ( myBinCount > 1000 ) myBinCount = 1000;
361 myBinCount = int( std::ceil( histogram.
maximum - histogram.
minimum + 1 ) );
372 double minimum,
double maximum,
375 bool includeOutOfRange )
377 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
383 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
399 double minimum,
double maximum,
404 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 );
420 int myBinCount = myHistogram.
binCount;
421 int myWidth = myHistogram.
width;
422 int myHeight = myHistogram.
height;
428 if ( myXBlockSize == 0 )
432 if ( myYBlockSize == 0 )
437 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
438 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
440 double myXRes = myExtent.
width() / myWidth;
441 double myYRes = myExtent.
height() / myHeight;
443 double myMinimum = myHistogram.
minimum;
444 double myMaximum = myHistogram.
maximum;
448 double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
449 myMinimum -= 0.1 * myerval;
450 myMaximum += 0.1 * myerval;
452 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
454 double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
457 bool isNoData =
false;
458 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
460 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
465 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
466 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
468 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
469 double xmax = xmin + myBlockWidth * myXRes;
470 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
471 double ymax = ymin - myBlockHeight * myYRes;
475 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
478 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
480 double myValue = blk->valueAndNoData( i, isNoData );
486 int myBinIndex = static_cast <
int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
488 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
492 if ( myBinIndex < 0 ) myBinIndex = 0;
493 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
501 myHistogram.
valid =
true;
506 for (
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
508 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
510 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
517 double lowerCount,
double upperCount,
518 double &lowerValue,
double &upperValue,
522 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
527 lowerValue = std::numeric_limits<double>::quiet_NaN();
528 upperValue = std::numeric_limits<double>::quiet_NaN();
542 int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
543 int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
544 bool myLowerFound =
false;
545 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
546 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
548 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
551 myCount += myBinValue;
552 if ( !myLowerFound && myCount > myMinCount )
554 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
556 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
558 if ( myCount >= myMaxCount )
560 upperValue = myHistogram.
minimum + myBin * myBinXStep;
561 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
571 if ( !std::isnan( lowerValue ) )
572 lowerValue = std::floor( lowerValue );
573 if ( !std::isnan( upperValue ) )
574 upperValue = std::ceil( upperValue );
580 QStringList abilitiesList;
590 abilitiesList += tr(
"Identify" );
595 abilitiesList += tr(
"Create Datasources" );
600 abilitiesList += tr(
"Remove Datasources" );
605 abilitiesList += tr(
"Build Pyramids" );
608 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QStringLiteral(
", " ) ), 4 );
610 return abilitiesList.join( QStringLiteral(
", " ) );
A rectangle specified with double values.
Thirty two bit signed integer (qint32)
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.
virtual QgsRectangle extent() const
Gets the extent of the interface.
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.
int bandNumber
The gdal band number (starts at 1)
double minimum
The minimum histogram value.
Thirty two bit unsigned integer (quint32)
double maximumValue
The maximum cell value in the raster band.
virtual int ySize() const
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 xBlockSize() const
Gets block size.
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)
bool isEmpty() const
Returns true if the rectangle is empty.
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.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
double width() const
Returns the width of the rectangle.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
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.
QString capabilitiesString() const
Returns the above in friendly format.
QgsRasterHistogram::HistogramVector histogramVector
Stores the histogram for a given layer.
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...
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...
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.
bool isCanceled() const
Tells whether the operation has been canceled already.
virtual int yBlockSize() const
double range
The range is the distance between min & max.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
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.
double yMaximum() const
Returns the y maximum value (top side of rectangle).
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
bool valid
Histogram is valid.
QgsRasterInterface * mInput
QgsRectangle extent
Extent used to calc histogram.
Feedback object tailored for raster block reading.
virtual int xSize() const
Gets raster size.
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.