Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix raster stats calculation for very small extents compared with
pixel size, when a sample size is set

Refs #19445
  • Loading branch information
nyalldawson committed Jul 20, 2018
1 parent d79dd73 commit 34b2191
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/core/raster/qgsrasterinterface.cpp
Expand Up @@ -71,8 +71,8 @@ void QgsRasterInterface::initStatistics( QgsRasterBandStats &statistics,
}
QgsDebugMsgLevel( QStringLiteral( "xRes = %1 yRes = %2" ).arg( xRes ).arg( yRes ), 4 );

statistics.width = static_cast <int>( finalExtent.width() / xRes );
statistics.height = static_cast <int>( finalExtent.height() / yRes );
statistics.width = static_cast <int>( std::ceil( finalExtent.width() / xRes ) );
statistics.height = static_cast <int>( std::ceil( finalExtent.height() / yRes ) );
}
else
{
Expand Down
49 changes: 44 additions & 5 deletions tests/src/core/testqgsrasterlayer.cpp
Expand Up @@ -386,17 +386,56 @@ void TestQgsRasterLayer::checkStats()
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.minimumValue == 0 );
QVERIFY( myStatistics.maximumValue == 9 );
QCOMPARE( mpRasterLayer->width(), 10 );
QCOMPARE( mpRasterLayer->height(), 10 );
//QCOMPARE( myStatistics.elementCount, 100 );
QCOMPARE( myStatistics.minimumValue, 0 );
QCOMPARE( myStatistics.maximumValue, 9 );
QGSCOMPARENEAR( myStatistics.mean, 4.5, 4 * std::numeric_limits<double>::epsilon() );
double stdDev = 2.87228132326901431;
// TODO: verify why GDAL stdDev is so different from generic (2.88675)
mReport += QStringLiteral( "stdDev = %1 expected = %2<br>\n" ).arg( myStatistics.stdDev ).arg( stdDev );
QGSCOMPARENEAR( myStatistics.stdDev, stdDev, 0.00000000000001 );
mReport += QLatin1String( "<p>Passed</p>" );

// limited extent
myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, QgsRectangle( 1535400, 5083280, 1535450, 5083320 ) );

QCOMPARE( myStatistics.minimumValue, 2 );
QCOMPARE( myStatistics.maximumValue, 7 );
QGSCOMPARENEAR( myStatistics.mean, 4.5, 4 * std::numeric_limits<double>::epsilon() );
QGSCOMPARENEAR( myStatistics.stdDev, 1.507557, 0.00001 );

// with sample size
myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, QgsRectangle( 1535400, 5083280, 1535450, 5083320 ), 10 );
QCOMPARE( myStatistics.minimumValue, 2 );
QCOMPARE( myStatistics.maximumValue, 7 );
QCOMPARE( myStatistics.elementCount, 12 );
QGSCOMPARENEAR( myStatistics.mean, 4.5, 4 * std::numeric_limits<double>::epsilon() );
QGSCOMPARENEAR( myStatistics.stdDev, 2.153222, 0.00001 );

// extremely limited extent - ~1 px size
myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, QgsRectangle( 1535400, 5083280, 1535412, 5083288 ) );
QCOMPARE( myStatistics.minimumValue, 2 );
QCOMPARE( myStatistics.maximumValue, 3 );
QGSCOMPARENEAR( myStatistics.mean, 2.600000, 4 * std::numeric_limits<double>::epsilon() );
QGSCOMPARENEAR( myStatistics.stdDev, 0.492366, 0.00001 );

// extremely limited extent - ~1 px size - with sample size
myStatistics = mpRasterLayer->dataProvider()->bandStatistics( 1,
QgsRasterBandStats::Min | QgsRasterBandStats::Max |
QgsRasterBandStats::Mean | QgsRasterBandStats::StdDev, QgsRectangle( 1535400, 5083280, 1535412, 5083288 ), 6 );
QCOMPARE( myStatistics.minimumValue, 2 );
QCOMPARE( myStatistics.maximumValue, 3 );
QCOMPARE( myStatistics.elementCount, 2 );
QGSCOMPARENEAR( myStatistics.mean, 2.500000, 4 * std::numeric_limits<double>::epsilon() );
QGSCOMPARENEAR( myStatistics.stdDev, 0.707107, 0.00001 );
}

// test scale_factor and offset - uses netcdf file which may not be supported
Expand Down

0 comments on commit 34b2191

Please sign in to comment.