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 );
 
  107     if ( stats.contains( myRasterBandStats ) )
 
  121   QgsDebugMsgLevel( QStringLiteral( 
"theBandNo = %1 stats = %2 sampleSize = %3" ).arg( bandNo ).arg( stats ).arg( sampleSize ), 4 );
 
  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 )
 
  305   if ( sampleSize > 0 )
 
  309     xRes = yRes = std::sqrt( ( 
static_cast<double>( 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 );
 
  339   qint64 myBinCount = binCount;
 
  340   if ( myBinCount == 0 )
 
  379                                        double minimum, 
double maximum,
 
  382                                        bool includeOutOfRange )
 
  384   QgsDebugMsgLevel( QStringLiteral( 
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
 
  390   initHistogram( myHistogram, bandNo, binCount, minimum, maximum, 
extent, sampleSize, includeOutOfRange );
 
  406     double minimum, 
double maximum,
 
  411   QgsDebugMsgLevel( QStringLiteral( 
"theBandNo = %1 binCount = %2 minimum = %3 maximum = %4 sampleSize = %5" ).arg( bandNo ).arg( binCount ).arg( minimum ).arg( maximum ).arg( sampleSize ), 4 );
 
  414   initHistogram( myHistogram, bandNo, binCount, minimum, maximum, 
extent, sampleSize, includeOutOfRange );
 
  427   int myBinCount = myHistogram.
binCount;
 
  428   int myWidth = myHistogram.
width;
 
  429   int myHeight = myHistogram.
height;
 
  435   if ( myXBlockSize == 0 ) 
 
  439   if ( myYBlockSize == 0 ) 
 
  444   int myNXBlocks = ( myWidth + myXBlockSize - 1 ) / myXBlockSize;
 
  445   int myNYBlocks = ( myHeight + myYBlockSize - 1 ) / myYBlockSize;
 
  447   double myXRes = myExtent.
width() / myWidth;
 
  448   double myYRes = myExtent.
height() / myHeight;
 
  450   double myMinimum = myHistogram.
minimum;
 
  451   double myMaximum = myHistogram.
maximum;
 
  455   double myerval = ( myMaximum - myMinimum ) / myHistogram.
binCount;
 
  456   myMinimum -= 0.1 * myerval;
 
  457   myMaximum += 0.1 * myerval;
 
  459   QgsDebugMsgLevel( QStringLiteral( 
"binCount = %1 myMinimum = %2 myMaximum = %3" ).arg( myHistogram.
binCount ).arg( myMinimum ).arg( myMaximum ), 4 );
 
  461   double myBinSize = ( myMaximum - myMinimum ) / myBinCount;
 
  464   bool isNoData = 
false;
 
  465   for ( 
int myYBlock = 0; myYBlock < myNYBlocks; myYBlock++ )
 
  467     for ( 
int myXBlock = 0; myXBlock < myNXBlocks; myXBlock++ )
 
  472       int myBlockWidth = std::min( myXBlockSize, myWidth - myXBlock * myXBlockSize );
 
  473       int myBlockHeight = std::min( myYBlockSize, myHeight - myYBlock * myYBlockSize );
 
  475       double xmin = myExtent.
xMinimum() + myXBlock * myXBlockSize * myXRes;
 
  476       double xmax = xmin + myBlockWidth * myXRes;
 
  477       double ymin = myExtent.
yMaximum() - myYBlock * myYBlockSize * myYRes;
 
  478       double ymax = ymin - myBlockHeight * myYRes;
 
  482       std::unique_ptr< QgsRasterBlock > blk( 
block( bandNo, myPartExtent, myBlockWidth, myBlockHeight, feedback ) );
 
  485       for ( 
qgssize i = 0; i < ( static_cast< qgssize >( myBlockHeight ) ) * myBlockWidth; i++ )
 
  487         double myValue = blk->valueAndNoData( i, isNoData );
 
  493         int myBinIndex = 
static_cast <int>( std::floor( ( myValue - myMinimum ) /  myBinSize ) );
 
  495         if ( ( myBinIndex < 0 || myBinIndex > ( myBinCount - 1 ) ) && !includeOutOfRange )
 
  499         if ( myBinIndex < 0 ) myBinIndex = 0;
 
  500         if ( myBinIndex > ( myBinCount - 1 ) ) myBinIndex = myBinCount - 1;
 
  508   myHistogram.
valid = 
true;
 
  513   for ( 
int i = 0; i < std::min( myHistogram.
histogramVector.size(), 500 ); i++ )
 
  515     hist += QString::number( myHistogram.
histogramVector.value( i ) ) + 
' ';
 
  517   QgsDebugMsgLevel( QStringLiteral( 
"Histogram (max first 500 bins): " ) + hist, 4 );
 
  524                                         double lowerCount, 
double upperCount,
 
  525                                         double &lowerValue, 
double &upperValue,
 
  529   QgsDebugMsgLevel( QStringLiteral( 
"theBandNo = %1 lowerCount = %2 upperCount = %3 sampleSize = %4" ).arg( bandNo ).arg( lowerCount ).arg( upperCount ).arg( sampleSize ), 4 );
 
  534   lowerValue = std::numeric_limits<double>::quiet_NaN();
 
  535   upperValue = std::numeric_limits<double>::quiet_NaN();
 
  549   int myMinCount = 
static_cast< int >( std::round( lowerCount * myHistogram.
nonNullCount ) );
 
  550   int myMaxCount = 
static_cast< int >( std::round( upperCount * myHistogram.
nonNullCount ) );
 
  551   bool myLowerFound = 
false;
 
  552   QgsDebugMsgLevel( QStringLiteral( 
"binCount = %1 minimum = %2 maximum = %3 myBinXStep = %4" ).arg( myHistogram.
binCount ).arg( myHistogram.
minimum ).arg( myHistogram.
maximum ).arg( myBinXStep ), 4 );
 
  553   QgsDebugMsgLevel( QStringLiteral( 
"myMinCount = %1 myMaxCount = %2" ).arg( myMinCount ).arg( myMaxCount ), 4 );
 
  555   for ( 
int myBin = 0; myBin < myHistogram.
histogramVector.size(); myBin++ )
 
  558     myCount += myBinValue;
 
  559     if ( !myLowerFound && myCount > myMinCount )
 
  561       lowerValue = myHistogram.
minimum + myBin * myBinXStep;
 
  563       QgsDebugMsgLevel( QStringLiteral( 
"found lowerValue %1 at bin %2" ).arg( lowerValue ).arg( myBin ), 4 );
 
  565     if ( myCount >= myMaxCount )
 
  567       upperValue = myHistogram.
minimum + myBin * myBinXStep;
 
  568       QgsDebugMsgLevel( QStringLiteral( 
"found upperValue %1 at bin %2" ).arg( upperValue ).arg( myBin ), 4 );
 
  578     if ( !std::isnan( lowerValue ) )
 
  579       lowerValue = std::floor( lowerValue );
 
  580     if ( !std::isnan( upperValue ) )
 
  581       upperValue = std::ceil( upperValue );
 
  587   QStringList abilitiesList;
 
  597     abilitiesList += tr( 
"Identify" );
 
  602     abilitiesList += tr( 
"Create Datasources" );
 
  607     abilitiesList += tr( 
"Remove Datasources" );
 
  612     abilitiesList += tr( 
"Build Pyramids" );
 
  615   QgsDebugMsgLevel( 
"Capability: " + abilitiesList.join( QLatin1String( 
", " ) ), 4 );
 
  617   return abilitiesList.join( QLatin1String( 
", " ) );
 
  625   return tr( 
"Band" ) + QStringLiteral( 
" %1" ) .arg( bandNumber, 1 + 
static_cast< int >( std::log10( 
static_cast< double >( 
bandCount() ) ) ), 10, QChar( 
'0' ) );
 
  640   if ( colorInterp != QLatin1String( 
"Undefined" ) )
 
  642     name.append( QStringLiteral( 
" (%1)" ).arg( colorInterp ) );
 
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 SIP_HOLDGIL
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.
int statsGathered
Collected 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.
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.
The QgsRasterHistogram is a container for histogram of a single raster band.
double minimum
The minimum histogram value.
int bandNumber
The gdal band number (starts at 1)
double maximum
The maximum histogram value.
bool includeOutOfRange
Whether histogram includes out of range values (in first and last bin)
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.
Base class for processing filters like renderers, reprojector, resampler etc.
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 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 yBlockSize() const
QList< QgsRasterBandStats > mStatistics
List of cached statistics, all bands mixed.
QString capabilitiesString() const
Returns the raster interface capabilities in friendly format.
@ BuildPyramids
Supports building of pyramids (overviews)
@ Identify
At least one identify format supported.
@ Create
Create new datasets.
@ Size
Original data source size (and thus resolution) is known, it is not always available,...
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)
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.
void initStatistics(QgsRasterBandStats &statistics, int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &boundingBox=QgsRectangle(), int binCount=0)
Fill in statistics defaults if not specified.
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)
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
QString displayBandName(int bandNumber) const
Generates a friendly, descriptive name for the specified bandNumber.
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).
QgsRasterInterface * mInput
virtual int capabilities() const
Returns a bitmask containing the supported capabilities.
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 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.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isEmpty() const
Returns true if the rectangle is empty.
QgsRectangle intersect(const QgsRectangle &rect) const
Returns the intersection with the given rectangle.
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)