From 20f9ac4c02baed6de3e9d0e9d335bcbf9f8b70fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Traizet?= <cedric.traizet@c-s.fr> Date: Mon, 27 Jul 2020 10:14:51 +0200 Subject: [PATCH] BUG: implement bilinear resampling in DEMHandler because rasterio extra args doesn't work with vrt --- Modules/IO/IOGDAL/include/otbDEMHandler.h | 10 +++ Modules/IO/IOGDAL/src/otbDEMHandler.cxx | 101 ++++++++++++++++++++-- 2 files changed, 103 insertions(+), 8 deletions(-) diff --git a/Modules/IO/IOGDAL/include/otbDEMHandler.h b/Modules/IO/IOGDAL/include/otbDEMHandler.h index 65fade966e..c566b1a5f8 100644 --- a/Modules/IO/IOGDAL/include/otbDEMHandler.h +++ b/Modules/IO/IOGDAL/include/otbDEMHandler.h @@ -87,12 +87,19 @@ protected: private: +private: + DEMHandler(const Self&) = delete; + void operator=(const Self&) = delete; + + /** List of RAII capsules on all opened DEM datasets for memory management */ std::vector<otb::GDALDatasetWrapper::Pointer> m_DatasetList; + /** Pointer to the DEM dataset */ GDALDataset * m_Dataset; GDALDataset* m_shiftedDS; + /** Pointer to the geoid dataset */ GDALDataset* m_GeoidDS; bool m_ApplyVerticalDatum; @@ -101,10 +108,13 @@ private: static Pointer m_Singleton; + /** Default height above elliposid, used when no DEM or geoid height is available. */ double m_DefaultHeightAboveEllipsoid; + /** List of the DEM directories currently opened */ std::vector<std::string> m_DEMDirectories; + /** Filename of the current geoid */ std::string m_GeoidFilename; }; diff --git a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx index 13e04691a6..058fb30218 100644 --- a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx +++ b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx @@ -86,7 +86,6 @@ void DEMHandler::OpenDEMFile(const std::string & path) void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory) { auto demFiles = GetFilesInDirectory(DEMDirectory); - for (const auto & file : demFiles) { auto ds = otb::GDALDriverManagerWrapper::GetInstance().Open(file); @@ -134,12 +133,12 @@ void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory) } void DEMHandler::OpenDEMDirectory(const char* DEMDirectory) -{ - OpenDEMDirectory(DEMDirectory); +{ + OpenDEMDirectory(std::string(DEMDirectory)); } boost::optional<double> DEMHandler::GetDEMValue(double lon, double lat, GDALDataset* ds) -{std::cout << "hey " << m_Dataset << " " << m_GeoidDS << " " << m_shiftedDS << " " << std::endl; +{ double value= 0.; GDALRasterIOExtraArg extraArgs = m_RasterIOArgs; @@ -151,26 +150,80 @@ boost::optional<double> DEMHandler::GetDEMValue(double lon, double lat, GDALData auto x = (lon - geoTransform[0]) / geoTransform[1] - 0.5; auto y = (lat - geoTransform[3]) / geoTransform[5] - 0.5; - std::cout <<"x="<< x << " y=" << y << std::endl; - + if (x < 0 || y < 0 || x > ds->GetRasterXSize() || y > ds->GetRasterYSize()) { - std::cout << "invalid coordinates" << std::endl; + //std::cout << "invalid coordinates" << std::endl; return boost::none; } +#if 0 +extraArgs.eResampleAlg = GDALRIOResampleAlg::GRIORA_Bilinear; extraArgs.bFloatingPointWindowValidity = TRUE; extraArgs.dfXOff = x; extraArgs.dfYOff = y; extraArgs.dfXSize = 1; extraArgs.dfYSize = 1; + //ds->GetRasterBand(1)->GetNoDataValue() << std::endl; +/* auto err = ds->GetRasterBand(1)->RasterIO( GF_Read, static_cast<int>(x), static_cast<int>(y), 1, 1, &value, 1, 1, GDT_Float64, 0, 0, &extraArgs); + */ + auto err = ds->RasterIO( GF_Read, static_cast<int>(x), static_cast<int>(y), 1, 1, + &value, 1, 1, GDT_Float64, 1, nullptr, + 0, 0,0, &extraArgs); - std::cout << "value :" << value << std::endl; + if (err || value == ds->GetRasterBand(1)->GetNoDataValue()) + { + return boost::none; + } + + //std::cout << "value :" << value << std::endl; return value; + +#else + auto x_int = static_cast<int>(x); + auto y_int = static_cast<int>(y); + + auto deltaX = x - x_int; + auto deltaY = y - y_int; +/* + std::cout <<"x="<< x << " y=" << y << std::endl; + std::cout <<"x_int="<< x_int << " y_int=" << y_int << std::endl; + std::cout <<"deltaX="<< deltaX << " deltaY=" << deltaY << std::endl; + */ + if (x < 0 || y < 0 || x+1 > ds->GetRasterXSize() || y+1 > ds->GetRasterYSize()) + { + //std::cout << "invalid coordinates" << std::endl; + return boost::none; + } + + // Bilinear interpolation. + double elevData[4]; + + auto err = ds->GetRasterBand(1)->RasterIO( GF_Read, x_int, y_int, 2, 2, + elevData, 2, 2, GDT_Float64, + 0, 0, &extraArgs); + + // Test for no data. Don't return a value if one pixel + // of the interpolation is no data. + for (int i =0; i<4; i++) + { + if (elevData[i] == ds->GetRasterBand(1)->GetNoDataValue()) + { + return boost::none; + } + } + + auto xBil1 = elevData[0] * (1-deltaX) + elevData[1] * deltaX; + auto xBil2 = elevData[2] * (1-deltaX) + elevData[3] * deltaX; + + auto yBil = xBil1 * (1.0 - deltaY) + xBil2 * deltaY; + return yBil; + +#endif } bool DEMHandler::OpenGeoidFile(const char* geoidFile) @@ -213,6 +266,7 @@ void DEMHandler::CreateShiftedDataset() double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) { +#if 0 auto ds = m_Dataset && m_GeoidDS ? m_shiftedDS : m_Dataset ? m_Dataset : m_GeoidDS ? m_GeoidDS @@ -228,6 +282,37 @@ double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) } return m_DefaultHeightAboveEllipsoid; +#else + double result = 0.; + boost::optional<double> DEMresult; + boost::optional<double> geoidResult; + + + + if (m_Dataset) + { + DEMresult = GetDEMValue(lon, lat, m_Dataset); + if (DEMresult) + { + result += *DEMresult; + } + } + + + if (m_GeoidDS) + { + geoidResult = GetDEMValue(lon, lat, m_GeoidDS); + if (geoidResult) + { + result += *geoidResult; + } + } + + if (DEMresult || geoidResult) + return result; + else + return m_DefaultHeightAboveEllipsoid; +#endif } double DEMHandler::GetHeightAboveEllipsoid(const PointType& geoPoint) -- GitLab