From 16e2b583b32cbeec621f3117436b7c2366eb3d8a Mon Sep 17 00:00:00 2001 From: Denis Rouzaud Date: Wed, 8 Jan 2025 16:09:08 +0100 Subject: [PATCH] fix nodata value in virtual raster layers --- .../qgsvirtualrasterprovider.cpp | 4 +- .../testqgsvirtualrasterprovider.cpp | 35 ++++++++++++++++++ tests/testdata/raster/no_data.tif | Bin 0 -> 729 bytes 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 tests/testdata/raster/no_data.tif diff --git a/src/providers/virtualraster/qgsvirtualrasterprovider.cpp b/src/providers/virtualraster/qgsvirtualrasterprovider.cpp index c052e4654387..61989668b6ed 100644 --- a/src/providers/virtualraster/qgsvirtualrasterprovider.cpp +++ b/src/providers/virtualraster/qgsvirtualrasterprovider.cpp @@ -122,7 +122,6 @@ QgsVirtualRasterProvider::QgsVirtualRasterProvider( const QgsVirtualRasterProvid , mFormulaString( other.mFormulaString ) , mLastError( other.mLastError ) , mRasterLayers {} // see note in other constructor above - { for ( const auto &it : other.mRasterLayers ) { @@ -149,6 +148,7 @@ QgsRasterBlock *QgsVirtualRasterProvider::block( int bandNo, const QgsRectangle { Q_UNUSED( bandNo ); std::unique_ptr tblock = std::make_unique( Qgis::DataType::Float64, width, height ); + double *outputData = ( double * ) ( tblock->bits() ); QMap inputBlocks; @@ -182,7 +182,7 @@ QgsRasterBlock *QgsVirtualRasterProvider::block( int bandNo, const QgsRectangle inputBlocks.insert( it->ref, block.release() ); } - QgsRasterMatrix resultMatrix( width, 1, nullptr, -FLT_MAX ); + QgsRasterMatrix resultMatrix( width, 1, nullptr, std::numeric_limits::quiet_NaN() ); for ( int i = 0; i < height; ++i ) { diff --git a/tests/src/providers/testqgsvirtualrasterprovider.cpp b/tests/src/providers/testqgsvirtualrasterprovider.cpp index 450609c91000..592db283d8c5 100644 --- a/tests/src/providers/testqgsvirtualrasterprovider.cpp +++ b/tests/src/providers/testqgsvirtualrasterprovider.cpp @@ -70,11 +70,13 @@ class TestQgsVirtualRasterProvider : public QgsTest void testConstructor(); void testNewCalcNodeMethods(); void testSecondGenerationVirtualRaster(); + void testNoData(); private: QString mTestDataDir; QgsRasterLayer *mDemRasterLayer = nullptr; QgsRasterLayer *mLandsatRasterLayer = nullptr; + QgsRasterLayer *mNoDataRasterLayer = nullptr; }; //runs before all tests @@ -93,6 +95,10 @@ void TestQgsVirtualRasterProvider::initTestCase() QString landsatFileName = mTestDataDir + "landsat.tif"; QFileInfo landsatRasterFileInfo( landsatFileName ); mLandsatRasterLayer = new QgsRasterLayer( landsatRasterFileInfo.filePath(), landsatRasterFileInfo.completeBaseName() ); + + QString nodataFileName = mTestDataDir + "raster/no_data.tif"; + QFileInfo nodataRasterFileInfo( nodataFileName ); + mNoDataRasterLayer = new QgsRasterLayer( nodataRasterFileInfo.filePath(), nodataRasterFileInfo.completeBaseName() ); } void TestQgsVirtualRasterProvider::validLayer() @@ -291,5 +297,34 @@ void TestQgsVirtualRasterProvider::testSecondGenerationVirtualRaster() QCOMPARE( sampledValueCalc_1, sampledValue + 200. ); QCOMPARE( layerSecond->dataProvider()->crs(), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) ); } + +void TestQgsVirtualRasterProvider::testNoData() +{ + double tlx = 415780.969; + double tly = 759360.133; + double cellSize = 0.1; + + // nodata + // 0 NaN + // NaN 1 + // 2 NaN + QString str = QStringLiteral( "?crs=EPSG:2105&extent=415780.96899999998277053,759359.8330999999307096,415781.16899999999441206,759360.13309999997727573&width=2&height=3&formula=\"nodata@1\" ^2 / \"nodata@1\"&nodata:provider=gdal" ); + + QString uri = QString( "%1&%2" ).arg( str, QStringLiteral( "nodata:uri=" ) % mTestDataDir % QStringLiteral( "raster/no_data.tif" ) ); + + std::unique_ptr layerNoData = std::make_unique( uri, QStringLiteral( "no-data" ), QStringLiteral( "virtualraster" ) ); + QVERIFY( layerNoData->dataProvider()->isValid() ); + QVERIFY( layerNoData->isValid() ); + + QgsPointXY p11( tlx + .5 * cellSize, tly - .5 * cellSize ); + QgsPointXY p12( tlx + 1.5 * cellSize, tly - .5 * cellSize ); + QgsPointXY p31( tlx + .5 * cellSize, tly - 2.5 * cellSize ); + + Q_ASSERT( std::isnan( layerNoData->dataProvider()->sample( p11, 1 ) ) ); // 0^2/0 + Q_ASSERT( std::isnan( layerNoData->dataProvider()->sample( p12, 1 ) ) ); // NaN^2/NaN + QCOMPARE( layerNoData->dataProvider()->sample( p31, 1 ), 2 ); // 2^2/2 +} + + QGSTEST_MAIN( TestQgsVirtualRasterProvider ) #include "testqgsvirtualrasterprovider.moc" diff --git a/tests/testdata/raster/no_data.tif b/tests/testdata/raster/no_data.tif new file mode 100644 index 0000000000000000000000000000000000000000..31326849d62750f975c8720481010c9a5c7a8bb6 GIT binary patch literal 729 zcmebD)MDUZU|;p+_AnX}wzx_2PR9q66C@p>5