37 changes: 28 additions & 9 deletions src/core/raster/qgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ unsigned int QgsRasterLayer::bandCount() const

const QString QgsRasterLayer::bandName( int theBandNo )
{
#if 0
if ( theBandNo <= mRasterStatsList.size() && theBandNo > 0 )
{
//vector starts at base 0, band counts at base1!
Expand All @@ -296,23 +297,30 @@ const QString QgsRasterLayer::bandName( int theBandNo )
{
return QString( "" );
}
#endif
return dataProvider()->generateBandName( theBandNo );
}

int QgsRasterLayer::bandNumber( QString const & theBandName ) const
{
for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
if ( !mDataProvider ) return 0;
for ( int myIterator = 1; myIterator <= dataProvider()->bandCount(); ++myIterator )
{
//find out the name of this band
#if 0
QgsRasterBandStats myRasterBandStats = mRasterStatsList[myIterator];
QgsDebugMsg( "myRasterBandStats.bandName: " + myRasterBandStats.bandName + " :: theBandName: "
+ theBandName );

if ( myRasterBandStats.bandName == theBandName )
#endif
QString myBandName = dataProvider()->generateBandName( myIterator );
if ( myBandName == theBandName )
{
QgsDebugMsg( "********** band " + QString::number( myRasterBandStats.bandNumber ) +
QgsDebugMsg( "********** band " + QString::number( myIterator ) +
" was found in bandNumber " + theBandName );

return myRasterBandStats.bandNumber;
return myIterator;
}
}
QgsDebugMsg( "********** no band was found in bandNumber " + theBandName );
Expand Down Expand Up @@ -612,11 +620,13 @@ bool QgsRasterLayer::copySymbologySettings( const QgsMapLayer& theOther )

/**
* @param theBandNo the band number
* @return pointer to the color table
* @return ointer to the color table
*/
QList<QgsColorRampShader::ColorRampItem>* QgsRasterLayer::colorTable( int theBandNo )
QList<QgsColorRampShader::ColorRampItem> QgsRasterLayer::colorTable( int theBandNo )
{
return &( mRasterStatsList[theBandNo-1].colorTable );
//return &( mRasterStatsList[theBandNo-1].colorTable );
if ( !mDataProvider ) return QList<QgsColorRampShader::ColorRampItem>();
return dataProvider()->colorTable( theBandNo );
}

/**
Expand Down Expand Up @@ -1707,6 +1717,7 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
mBandCount = mDataProvider->bandCount( );
for ( int i = 1; i <= mBandCount; i++ )
{
#if 0
QgsRasterBandStats myRasterBandStats;
myRasterBandStats.bandName = mDataProvider->generateBandName( i );
myRasterBandStats.bandNumber = i;
Expand All @@ -1718,6 +1729,7 @@ void QgsRasterLayer::setDataProvider( QString const & provider )
myRasterBandStats.colorTable = ct;

mRasterStatsList.push_back( myRasterBandStats );
#endif

//Build a new contrast enhancement for the band and store in list
//QgsContrastEnhancement myContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )mDataProvider->dataType( i ) );
Expand Down Expand Up @@ -1814,7 +1826,7 @@ void QgsRasterLayer::closeDataProvider()
mPipe.remove( mDataProvider );
mDataProvider = 0;

mRasterStatsList.clear();
//mRasterStatsList.clear();
mContrastEnhancementList.clear();

mHasPyramids = false;
Expand Down Expand Up @@ -2066,12 +2078,15 @@ void QgsRasterLayer::setNoDataValue( double theNoDataValue )
mNoDataValue = theNoDataValue;
mValidNoDataValue = true;
//Basically set the raster stats as invalid
// TODO! No data value must be set on provider and stats cleared
#if 0
QList<QgsRasterBandStats>::iterator myIterator = mRasterStatsList.begin();
while ( myIterator != mRasterStatsList.end() )
{
( *myIterator ).statsGathered = false;
++myIterator;
}
#endif
}
}

Expand Down Expand Up @@ -2651,19 +2666,22 @@ QString QgsRasterLayer::validateBandName( QString const & theBandName )
return TRSTRING_NOT_SET;
}

if ( !mDataProvider ) return TRSTRING_NOT_SET;

//check that a valid band name was passed
QgsDebugMsg( "Looking through raster band stats for matching band name" );
for ( int myIterator = 0; myIterator < mRasterStatsList.size(); ++myIterator )
for ( int myIterator = 1; myIterator < mDataProvider->bandCount(); ++myIterator )
{
//find out the name of this band
if ( mRasterStatsList[myIterator].bandName == theBandName )
if ( mDataProvider->generateBandName( myIterator ) == theBandName );
{
QgsDebugMsg( "Matching band name found" );
return theBandName;
}
}
QgsDebugMsg( "No matching band name found in raster band stats" );

#if 0
QgsDebugMsg( "Testing for non zero-buffered names" );
//TODO Remove test in v2.0 or earlier
QStringList myBandNameComponents = theBandName.split( " " );
Expand Down Expand Up @@ -2702,6 +2720,7 @@ QString QgsRasterLayer::validateBandName( QString const & theBandName )
}
}
}
#endif

//if no matches were found default to not set
QgsDebugMsg( "All checks failed, returning '" + QSTRING_NOT_SET + "'" );
Expand Down
6 changes: 3 additions & 3 deletions src/core/raster/qgsrasterlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
bool copySymbologySettings( const QgsMapLayer& theOther );

/** \brief Get a pointer to the color table */
QList<QgsColorRampShader::ColorRampItem>* colorTable( int theBandNoInt );
QList<QgsColorRampShader::ColorRampItem> colorTable( int theBandNoInt );

/** Returns the data provider */
QgsRasterDataProvider* dataProvider();
Expand Down Expand Up @@ -530,7 +530,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
/** \brief Returns the number of raster units per each raster pixel. In a world file, this is normally the first row (without the sign) */
double rasterUnitsPerPixel();

const RasterStatsList rasterStatsList() const { return mRasterStatsList; }
//const RasterStatsList rasterStatsList() const { return mRasterStatsList; }

/** \brief Read color table from GDAL raster band */
// Keep this for QgsRasterLayerProperties
Expand Down Expand Up @@ -844,7 +844,7 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
RasterPyramidList mPyramidList;

/** \brief A collection of stats - one for each band in the layer */
RasterStatsList mRasterStatsList;
//RasterStatsList mRasterStatsList;

LayerType mRasterType;

Expand Down
6 changes: 3 additions & 3 deletions src/gui/raster/qgspalettedrendererwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ void QgsPalettedRendererWidget::setFromRenderer( const QgsRasterRenderer* r )
else
{
//read default palette settings from layer
QList<QgsColorRampShader::ColorRampItem>* itemList =
QList<QgsColorRampShader::ColorRampItem> itemList =
mRasterLayer->colorTable( mBandComboBox->itemData( mBandComboBox->currentIndex() ).toInt() );
QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList->constBegin();
QList<QgsColorRampShader::ColorRampItem>::const_iterator itemIt = itemList.constBegin();
int index = 0;
for ( ; itemIt != itemList->constEnd(); ++itemIt )
for ( ; itemIt != itemList.constEnd(); ++itemIt )
{
QTreeWidgetItem* item = new QTreeWidgetItem( mTreeWidget );
item->setText( 0, QString::number( index ) );
Expand Down
18 changes: 10 additions & 8 deletions src/gui/raster/qgsrasterhistogramwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,9 +406,9 @@ void QgsRasterHistogramWidget::refreshHistogram()
if ( ! mySelectedBands.contains( myIteratorInt ) )
continue;
}
QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
int sampleSize = 250000; // number of sample cells
//QgsRasterBandStats myRasterBandStats = mRasterLayer->dataProvider()->bandStatistics( myIteratorInt );
// mRasterLayer->populateHistogram( myIteratorInt, BINCOUNT, myIgnoreOutOfRangeFlag, myThoroughBandScanFlag );
QgsRasterHistogram myHistogram = mRasterLayer->dataProvider()->histogram( myIteratorInt, BINCOUNT, std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), QgsRectangle(), sampleSize );

QwtPlotCurve * mypCurve = new QwtPlotCurve( tr( "Band %1" ).arg( myIteratorInt ) );
Expand All @@ -424,8 +424,10 @@ void QgsRasterHistogramWidget::refreshHistogram()
// calculate first bin x value and bin step size if not Byte data
if ( mRasterLayer->dataProvider()->srcDataType( myIteratorInt ) != QgsRasterDataProvider::Byte )
{
myBinXStep = myRasterBandStats.range / BINCOUNT;
myBinX = myRasterBandStats.minimumValue + myBinXStep / 2.0;
//myBinXStep = myRasterBandStats.range / BINCOUNT;
//myBinX = myRasterBandStats.minimumValue + myBinXStep / 2.0;
myBinXStep = ( myHistogram.maximum - myHistogram.minimum ) / BINCOUNT;
myBinX = myHistogram.minimum + myBinXStep / 2.0;
}
else
{
Expand All @@ -451,13 +453,13 @@ void QgsRasterHistogramWidget::refreshHistogram()
mypCurve->setData( myX2Data, myY2Data );
#endif
mypCurve->attach( mpPlot );
if ( myFirstIteration || mHistoMin > myRasterBandStats.minimumValue )
if ( myFirstIteration || mHistoMin > myHistogram.minimum )
{
mHistoMin = myRasterBandStats.minimumValue;
mHistoMin = myHistogram.minimum;
}
if ( myFirstIteration || mHistoMax < myRasterBandStats.maximumValue )
if ( myFirstIteration || mHistoMax < myHistogram.maximum )
{
mHistoMax = myRasterBandStats.maximumValue;
mHistoMax = myHistogram.maximum;
}
QgsDebugMsg( QString( "computed histo min = %1 max = %2" ).arg( mHistoMin ).arg( mHistoMax ) );
myFirstIteration = false;
Expand Down
28 changes: 14 additions & 14 deletions src/gui/raster/qgsrasterminmaxwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
#include "qgsrasterminmaxwidget.h"

QgsRasterMinMaxWidget::QgsRasterMinMaxWidget( QgsRasterLayer* theLayer, QWidget *parent ):
QWidget( parent )
,mLayer ( theLayer )
QWidget( parent )
, mLayer( theLayer )
{
QgsDebugMsg("Entered.");
QgsDebugMsg( "Entered." );
setupUi( this );
}

Expand All @@ -32,12 +32,12 @@ QgsRasterMinMaxWidget::~QgsRasterMinMaxWidget()

void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()
{
QgsDebugMsg("Entered.");
QgsDebugMsg( "Entered." );

foreach ( int myBand, mBands )
foreach( int myBand, mBands )
{
QgsDebugMsg( QString("myBand = %1").arg(myBand));
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
QgsDebugMsg( QString( "myBand = %1" ).arg( myBand ) );
if ( myBand < 1 || myBand > mLayer->dataProvider()->bandCount() )
{
continue;
}
Expand All @@ -46,10 +46,10 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()

QgsRectangle myExtent; // empty == full
if ( mCurrentExtentRadioButton->isChecked() )
{
{
myExtent = mExtent; // current
}
QgsDebugMsg( QString("myExtent.isEmpty() = %1").arg(myExtent.isEmpty()) );
QgsDebugMsg( QString( "myExtent.isEmpty() = %1" ).arg( myExtent.isEmpty() ) );

int mySampleSize = 0; // 0 == exact
if ( mEstimateRadioButton->isChecked() )
Expand All @@ -59,24 +59,24 @@ void QgsRasterMinMaxWidget::on_mLoadPushButton_clicked()

if ( mCumulativeCutRadioButton->isChecked() )
{
mLayer->dataProvider()->cumulativeCut ( myBand, 0.02, 0.98, myMin, myMax, myExtent, mySampleSize );
}
mLayer->dataProvider()->cumulativeCut( myBand, 0.02, 0.98, myMin, myMax, myExtent, mySampleSize );
}
else if ( mMinMaxRadioButton->isChecked() )
{
// TODO: consider provider minimum/maximumValue() (has to be defined well in povider)
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, myExtent, mySampleSize );
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Min | QgsRasterBandStats::Max, myExtent, mySampleSize );
myMin = myRasterBandStats.minimumValue;
myMax = myRasterBandStats.maximumValue;
}
else if ( mStdDevRadioButton->isChecked() )
{
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, myExtent, mySampleSize );
QgsRasterBandStats myRasterBandStats = mLayer->dataProvider()->bandStatistics( myBand, QgsRasterBandStats::Mean, myExtent, mySampleSize );
double myStdDev = mStdDevSpinBox->value();
myMin = myRasterBandStats.mean - ( myStdDev * myRasterBandStats.stdDev );
myMax = myRasterBandStats.mean + ( myStdDev * myRasterBandStats.stdDev );

}

emit load ( myBand, myMin, myMax );
emit load( myBand, myMin, myMax );
}
}
67 changes: 47 additions & 20 deletions src/providers/gdal/qgsgdalprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,8 @@ bool QgsGdalProvider::hasHistogram( int theBandNo,
return true;
}

QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
QgsRasterHistogram myHistogram;
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );

// If not cached, check if supported by GDAL
if ( myHistogram.extent != extent() )
Expand Down Expand Up @@ -1329,7 +1330,8 @@ QgsRasterHistogram QgsGdalProvider::histogram( int theBandNo,
{
QgsDebugMsg( QString( "theBandNo = %1 theBinCount = %2 theMinimum = %3 theMaximum = %4 theSampleSize = %5" ).arg( theBandNo ).arg( theBinCount ).arg( theMinimum ).arg( theMaximum ).arg( theSampleSize ) );

QgsRasterHistogram myHistogram = histogramDefaults( theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );
QgsRasterHistogram myHistogram;
initHistogram( myHistogram, theBandNo, theBinCount, theMinimum, theMaximum, theExtent, theSampleSize, theIncludeOutOfRange );

// Find cached
foreach( QgsRasterHistogram histogram, mHistograms )
Expand Down Expand Up @@ -2002,21 +2004,28 @@ QGISEXTERN bool isValidRasterFileName( QString const & theFileNameQString, QStri
}

bool QgsGdalProvider::hasStatistics( int theBandNo,
int theStats,
const QgsRectangle & theExtent,
int theSampleSize )
{
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );

// First check if cached in mStatistics
if ( QgsRasterDataProvider::hasStatistics( theBandNo, theExtent, theSampleSize ) )
if ( QgsRasterDataProvider::hasStatistics( theBandNo, theStats, theExtent, theSampleSize ) )
{
return true;
}

QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
QgsRasterBandStats myRasterBandStats;
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );

// If not cached, check if supported by GDAL
if ( myRasterBandStats.extent != extent() )
int supportedStats = QgsRasterBandStats::Min | QgsRasterBandStats::Max
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
| QgsRasterBandStats::StdDev;

if ( myRasterBandStats.extent != extent() ||
( theStats & ( ~supportedStats ) ) )
{
QgsDebugMsg( "Not supported by GDAL." );
return false;
Expand All @@ -2041,13 +2050,19 @@ bool QgsGdalProvider::hasStatistics( int theBandNo,

// Params in GDALGetRasterStatistics must not be NULL otherwise GDAL returns
// without error even if stats are not cached
double pdfMin;
double pdfMax;
double pdfMean;
double pdfStdDev;
double dfMin, dfMax, dfMean, dfStdDev;
double *pdfMin = &dfMin;
double *pdfMax = &dfMax;
double *pdfMean = &dfMean;
double *pdfStdDev = &dfStdDev;

if ( !( theStats & QgsRasterBandStats::Min ) ) pdfMin = NULL;
if ( !( theStats & QgsRasterBandStats::Max ) ) pdfMax = NULL;
if ( !( theStats & QgsRasterBandStats::Mean ) ) pdfMean = NULL;
if ( !( theStats & QgsRasterBandStats::StdDev ) ) pdfStdDev = NULL;

// try to fetch the cached stats (bForce=FALSE)
CPLErr myerval = GDALGetRasterStatistics( myGdalBand, bApproxOK, FALSE, &pdfMin, &pdfMax, &pdfMean, &pdfStdDev );
CPLErr myerval = GDALGetRasterStatistics( myGdalBand, bApproxOK, FALSE, pdfMin, pdfMax, pdfMean, pdfStdDev );

if ( CE_None == myerval ) // CE_Warning if cached not found
{
Expand All @@ -2058,29 +2073,40 @@ bool QgsGdalProvider::hasStatistics( int theBandNo,
return false;
}

QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRectangle & theExtent, int theSampleSize )
QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, int theStats, const QgsRectangle & theExtent, int theSampleSize )
{
QgsDebugMsg( QString( "theBandNo = %1 theSampleSize = %2" ).arg( theBandNo ).arg( theSampleSize ) );

// TODO: null values set on raster layer!!!

// Currently there is no API in GDAL to collect statistics of specified extent
// or with defined sample size. We check first if we have cached stats, if not,
// and it is not possible to use GDAL we call generic provider method,
// otherwise we use GDAL (faster, cache)

QgsRasterBandStats myRasterBandStats = statisticsDefaults( theBandNo, theExtent, theSampleSize );
QgsRasterBandStats myRasterBandStats;
initStatistics( myRasterBandStats, theBandNo, theStats, theExtent, theSampleSize );

foreach( QgsRasterBandStats stats, mStatistics )
{
if ( stats == myRasterBandStats )
if ( stats.contains( myRasterBandStats ) )
{
QgsDebugMsg( "Using cached statistics." );
return stats;
}
}

if ( myRasterBandStats.extent != extent() )
int supportedStats = QgsRasterBandStats::Min | QgsRasterBandStats::Max
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
| QgsRasterBandStats::StdDev;

QgsDebugMsg( QString( "theStats = %1 supportedStats = %2" ).arg( theStats, 0, 2 ).arg( supportedStats, 0, 2 ) );

if ( myRasterBandStats.extent != extent() ||
( theStats & ( ~supportedStats ) ) )
{
QgsDebugMsg( "Using generic statistics." );
return QgsRasterDataProvider::bandStatistics( theBandNo, theExtent, theSampleSize );
return QgsRasterDataProvider::bandStatistics( theBandNo, theStats, theExtent, theSampleSize );
}

QgsDebugMsg( "Using GDAL statistics." );
Expand Down Expand Up @@ -2131,10 +2157,14 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRect
//calculate the mean
myRasterBandStats.mean = pdfMean;
myRasterBandStats.sum = 0; //not available via gdal
myRasterBandStats.elementCount = mWidth * mHeight;
//myRasterBandStats.elementCount = mWidth * mHeight;
// Sum of non NULL
myRasterBandStats.elementCount = 0; //not available via gdal
myRasterBandStats.sumOfSquares = 0; //not available via gdal
myRasterBandStats.stdDev = pdfStdDev;
myRasterBandStats.statsGathered = true;
myRasterBandStats.statsGathered = QgsRasterBandStats::Min | QgsRasterBandStats::Max
| QgsRasterBandStats::Range | QgsRasterBandStats::Mean
| QgsRasterBandStats::StdDev;

#ifdef QGISDEBUG
QgsDebugMsg( "************ STATS **************" );
Expand All @@ -2145,9 +2175,6 @@ QgsRasterBandStats QgsGdalProvider::bandStatistics( int theBandNo, const QgsRect
QgsDebugMsg( QString( "MEAN %1" ).arg( myRasterBandStats.mean ) );
QgsDebugMsg( QString( "STDDEV %1" ).arg( myRasterBandStats.stdDev ) );
#endif

myRasterBandStats.statsGathered = true;

}

mStatistics.append( myRasterBandStats );
Expand Down
2 changes: 2 additions & 0 deletions src/providers/gdal/qgsgdalprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,10 +239,12 @@ class QgsGdalProvider : public QgsRasterDataProvider
static QStringList subLayers( GDALDatasetH dataset );

bool hasStatistics( int theBandNo,
int theStats = QgsRasterBandStats::All,
const QgsRectangle & theExtent = QgsRectangle(),
int theSampleSize = 0 );

QgsRasterBandStats bandStatistics( int theBandNo,
int theStats = QgsRasterBandStats::All,
const QgsRectangle & theExtent = QgsRectangle(),
int theSampleSize = 0 );

Expand Down
18 changes: 12 additions & 6 deletions tests/src/core/testqgsrasterlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,26 +183,32 @@ void TestQgsRasterLayer::landsatBasic875Qml()
}
void TestQgsRasterLayer::checkDimensions()
{
mReport += "<h2>Check Dimensions</h2>\n";
QVERIFY( mpRasterLayer->width() == 10 );
QVERIFY( mpRasterLayer->height() == 10 );
// regression check for ticket #832
// note bandStatistics call is base 1
QVERIFY( mpRasterLayer->dataProvider()->bandStatistics( 1 ).elementCount == 100 );
mReport += "<h2>Check Dimensions</h2>\n";
// TODO: elementCount is not collected by GDAL, use other stats.
//QVERIFY( mpRasterLayer->dataProvider()->bandStatistics( 1 ).elementCount == 100 );
mReport += "<p>Passed</p>";
}
void TestQgsRasterLayer::checkStats()
{
QgsRasterBandStats myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1 );
mReport += "<h2>Check Stats</h2>\n";
QgsRasterBandStats myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev );
QVERIFY( mpRasterLayer->width() == 10 );
QVERIFY( mpRasterLayer->height() == 10 );
QVERIFY( myStatistics.elementCount == 100 );
//QVERIFY( myStatistics.elementCount == 100 );
QVERIFY( myStatistics.minimumValue == 0 );
QVERIFY( myStatistics.maximumValue == 9 );
QVERIFY( myStatistics.mean == 4.5 );
QVERIFY( fabs( myStatistics.stdDev - 2.87228132326901431 )
double stdDev = 2.87228132326901431;
// TODO: verify why GDAL stdDev is so different from generic (2.88675)
mReport += QString( "stdDev = %1 expected = %2<br>\n" ).arg( myStatistics.stdDev ).arg( stdDev );
QVERIFY( fabs( myStatistics.stdDev - stdDev )
< 0.0000000000000001 );
mReport += "<h2>Check Stats</h2>\n";
mReport += "<p>Passed</p>";
}

Expand Down