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 bool isNoData =
false;
166 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
168 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
171 return myRasterBandStats;
173 QgsDebugMsgLevel( QStringLiteral(
"myYBlock = %1 myXBlock = %2" ).arg( myYBlock ).arg( myXBlock ), 4 );
174 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
175 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
177 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
178 double xmax = xmin + myBlockWidth * myXRes;
179 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
180 double ymax = ymin - myBlockHeight * myYRes;
184 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
187 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
189 double myValue = blk->valueAndNoData( i, isNoData );
193 myRasterBandStats.
sum += myValue;
196 if ( !std::isfinite( myValue ) )
continue;
198 if ( myFirstIterationFlag )
200 myFirstIterationFlag =
false;
217 double myDelta = myValue - myMean;
219 mySumOfSquares += myDelta * ( myValue - myMean );
232 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.
elementCount - 1 ) );
234 QgsDebugMsgLevel( QStringLiteral(
"************ STATS **************" ), 4 );
244 return myRasterBandStats;
250 double minimum,
double maximum,
253 bool includeOutOfRange )
262 if ( std::isnan( histogram.
minimum ) )
279 if ( std::isnan( histogram.
maximum ) )
301 histogram.
extent = finalExtent;
303 if ( sampleSize > 0 )
307 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
314 if ( xRes < srcXRes ) xRes = srcXRes;
315 if ( yRes < srcYRes ) yRes = srcYRes;
317 QgsDebugMsgLevel( QStringLiteral(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
319 histogram.
width = static_cast <
int>( finalExtent.
width() / xRes );
320 histogram.
height = static_cast <
int>( finalExtent.
height() / yRes );
331 histogram.
width = 1000;
335 QgsDebugMsgLevel( QStringLiteral(
"theHistogram.width = %1 histogram.height = %2" ).arg( histogram.
width ).arg( histogram.
height ), 4 );
337 int myBinCount = binCount;
338 if ( myBinCount == 0 )
350 if ( myBinCount > 1000 ) myBinCount = 1000;
359 myBinCount = int( std::ceil( histogram.
maximum - histogram.
minimum + 1 ) );
370 double minimum,
double maximum,
373 bool includeOutOfRange )
375 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
381 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
385 if ( histogram == myHistogram )
396 double minimum,
double maximum,
401 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
404 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
409 if ( histogram == myHistogram )
416 int myBinCount = myHistogram.
binCount;
417 int myWidth = myHistogram.
width;
418 int myHeight = myHistogram.
height;
424 if ( myXBlockSize == 0 )
428 if ( myYBlockSize == 0 )
433 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
434 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
436 double myXRes = myExtent.
width() / myWidth;
437 double myYRes = myExtent.
height() / myHeight;
439 double myMinimum = myHistogram.
minimum;
440 double myMaximum = myHistogram.
maximum;
444 double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
445 myMinimum -= 0.1 * myerval;
446 myMaximum += 0.1 * myerval;
448 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
450 double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
453 bool isNoData =
false;
454 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
456 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
461 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
462 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
464 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
465 double xmax = xmin + myBlockWidth * myXRes;
466 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
467 double ymax = ymin - myBlockHeight * myYRes;
471 std::unique_ptr< QgsRasterBlock > blk(
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
474 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
476 double myValue = blk->valueAndNoData( i, isNoData );
482 int myBinIndex = static_cast <
int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
484 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
488 if ( myBinIndex < 0 ) myBinIndex = 0;
489 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
497 myHistogram.
valid =
true;
502 for (
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
504 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
506 QgsDebugMsgLevel( QStringLiteral(
"Histogram (max first 500 bins): " ) + hist, 4 );
513 double lowerCount,
double upperCount,
514 double &lowerValue,
double &upperValue,
518 QgsDebugMsgLevel( QStringLiteral(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
523 lowerValue = std::numeric_limits<double>::quiet_NaN();
524 upperValue = std::numeric_limits<double>::quiet_NaN();
538 int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
539 int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
540 bool myLowerFound =
false;
541 QgsDebugMsgLevel( QStringLiteral(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
542 QgsDebugMsgLevel( QStringLiteral(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
544 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
547 myCount += myBinValue;
548 if ( !myLowerFound && myCount > myMinCount )
550 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
552 QgsDebugMsgLevel( QStringLiteral(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
554 if ( myCount >= myMaxCount )
556 upperValue = myHistogram.
minimum + myBin * myBinXStep;
557 QgsDebugMsgLevel( QStringLiteral(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
567 if ( !std::isnan( lowerValue ) )
568 lowerValue = std::floor( lowerValue );
569 if ( !std::isnan( upperValue ) )
570 upperValue = std::ceil( upperValue );
576 QStringList abilitiesList;
586 abilitiesList += tr(
"Identify" );
591 abilitiesList += tr(
"Create Datasources" );
596 abilitiesList += tr(
"Remove Datasources" );
601 abilitiesList += tr(
"Build Pyramids" );
604 QgsDebugMsgLevel(
"Capability: " + abilitiesList.join( QStringLiteral(
", " ) ), 4 );
606 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)
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc. not collected statistics.
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.