Skip to content

Commit

Permalink
Merge pull request #60089 from qgis/backport-60084-to-release-3_40
Browse files Browse the repository at this point in the history
[Backport release-3_40] fix nodata value in virtual raster layers
  • Loading branch information
rouault authored Jan 11, 2025
2 parents 7d48298 + 16e2b58 commit 225fbc6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/providers/virtualraster/qgsvirtualrasterprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 )
{
Expand All @@ -149,6 +148,7 @@ QgsRasterBlock *QgsVirtualRasterProvider::block( int bandNo, const QgsRectangle
{
Q_UNUSED( bandNo );
std::unique_ptr<QgsRasterBlock> tblock = std::make_unique<QgsRasterBlock>( Qgis::DataType::Float64, width, height );

double *outputData = ( double * ) ( tblock->bits() );

QMap<QString, QgsRasterBlock *> inputBlocks;
Expand Down Expand Up @@ -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<double>::quiet_NaN() );

for ( int i = 0; i < height; ++i )
{
Expand Down
35 changes: 35 additions & 0 deletions tests/src/providers/testqgsvirtualrasterprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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<QgsRasterLayer> layerNoData = std::make_unique<QgsRasterLayer>( 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"
Binary file added tests/testdata/raster/no_data.tif
Binary file not shown.

0 comments on commit 225fbc6

Please sign in to comment.