23 #include <QStringList> 42 QgsDebugMsgLevel( QString(
"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( QString(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
74 statistics.
width = static_cast <
int>( finalExtent.
width() / xRes );
75 statistics.
height = static_cast <
int>( finalExtent.
height() / yRes );
86 statistics.
width = 1000;
90 QgsDebugMsgLevel( QString(
"theStatistics.width = %1 statistics.height = %2" ).arg( statistics.
width ).arg( statistics.
height ), 4 );
98 QgsDebugMsgLevel( QString(
"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( QString(
"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( QString(
"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 QgsRasterBlock *blk =
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback );
186 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
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 );
231 myRasterBandStats.
stdDev = std::sqrt( mySumOfSquares / ( myRasterBandStats.
elementCount - 1 ) );
243 return myRasterBandStats;
249 double minimum,
double maximum,
252 bool includeOutOfRange )
261 if ( std::isnan( histogram.
minimum ) )
278 if ( std::isnan( histogram.
maximum ) )
300 histogram.
extent = finalExtent;
302 if ( sampleSize > 0 )
306 xRes = yRes = std::sqrt( ( finalExtent.
width() * finalExtent.
height() ) / sampleSize );
313 if ( xRes < srcXRes ) xRes = srcXRes;
314 if ( yRes < srcYRes ) yRes = srcYRes;
316 QgsDebugMsgLevel( QString(
"xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );
318 histogram.
width = static_cast <
int>( finalExtent.
width() / xRes );
319 histogram.
height = static_cast <
int>( finalExtent.
height() / yRes );
330 histogram.
width = 1000;
336 int myBinCount = binCount;
337 if ( myBinCount == 0 )
349 if ( myBinCount > 1000 ) myBinCount = 1000;
358 myBinCount = int( std::ceil( histogram.
maximum - histogram.
minimum + 1 ) );
369 double minimum,
double maximum,
372 bool includeOutOfRange )
374 QgsDebugMsgLevel( QString(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
380 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
384 if ( histogram == myHistogram )
395 double minimum,
double maximum,
400 QgsDebugMsgLevel( QString(
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
403 initHistogram( myHistogram, bandNo, binCount, minimum, maximum, extent, sampleSize, includeOutOfRange );
408 if ( histogram == myHistogram )
415 int myBinCount = myHistogram.
binCount;
416 int myWidth = myHistogram.
width;
417 int myHeight = myHistogram.
height;
423 if ( myXBlockSize == 0 )
427 if ( myYBlockSize == 0 )
432 int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
433 int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
435 double myXRes = myExtent.
width() / myWidth;
436 double myYRes = myExtent.
height() / myHeight;
438 double myMinimum = myHistogram.
minimum;
439 double myMaximum = myHistogram.
maximum;
443 double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
444 myMinimum -= 0.1 * myerval;
445 myMaximum += 0.1 * myerval;
447 QgsDebugMsgLevel( QString(
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
449 double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
452 for (
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
454 for (
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
459 int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
460 int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
462 double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
463 double xmax = xmin + myBlockWidth * myXRes;
464 double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
465 double ymax = ymin - myBlockHeight * myYRes;
469 QgsRasterBlock *blk =
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback );
472 for (
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
478 double myValue = blk->
value( i );
480 int myBinIndex = static_cast <
int>( std::floor( ( myValue - myMinimum ) / myBinSize ) );
482 if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
486 if ( myBinIndex < 0 ) myBinIndex = 0;
487 if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
496 myHistogram.
valid =
true;
501 for (
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
503 hist += QString::number( myHistogram.
histogramVector.value( i ) ) +
' ';
512 double lowerCount,
double upperCount,
513 double &lowerValue,
double &upperValue,
517 QgsDebugMsgLevel( QString(
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
522 lowerValue = std::numeric_limits<double>::quiet_NaN();
523 upperValue = std::numeric_limits<double>::quiet_NaN();
537 int myMinCount = static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
538 int myMaxCount =
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
539 bool myLowerFound =
false;
540 QgsDebugMsgLevel( QString(
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
541 QgsDebugMsgLevel( QString(
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
543 for (
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
546 myCount += myBinValue;
547 if ( !myLowerFound && myCount > myMinCount )
549 lowerValue = myHistogram.
minimum + myBin * myBinXStep;
551 QgsDebugMsgLevel( QString(
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
553 if ( myCount >= myMaxCount )
555 upperValue = myHistogram.
minimum + myBin * myBinXStep;
556 QgsDebugMsgLevel( QString(
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
566 if ( lowerValue != std::numeric_limits<double>::quiet_NaN() )
567 lowerValue = std::floor( lowerValue );
568 if ( upperValue != std::numeric_limits<double>::quiet_NaN() )
569 upperValue = std::ceil( upperValue );
575 QStringList abilitiesList;
585 abilitiesList += tr(
"Identify" );
590 abilitiesList += tr(
"Create Datasources" );
595 abilitiesList += tr(
"Remove Datasources" );
600 abilitiesList += tr(
"Build Pyramids" );
605 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
Get 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
QgsRectangle intersect(const QgsRectangle *rect) const
Return the intersection with the given rectangle.
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)
Get 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 isNoData(int row, int column)
Check if value at position is no data.
bool contains(const QgsRasterBandStats &s) const
Compares region, size etc. not collected statistics.
virtual int xBlockSize() const
Get 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.
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
Store 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)
Get 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 value(int row, int column) const
Read a single value if type of block is numeric.
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
Get 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.