[Git][debian-gis-team/otb][master] 7 commits: New upstream version 8.1.1+dfsg
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Fri Jan 13 20:29:16 GMT 2023
Bas Couwenberg pushed to branch master at Debian GIS Project / otb
Commits:
f53878cd by Bas Couwenberg at 2023-01-13T16:23:46+01:00
New upstream version 8.1.1+dfsg
- - - - -
a72c05f0 by Bas Couwenberg at 2023-01-13T16:36:35+01:00
Update upstream source from tag 'upstream/8.1.1+dfsg'
Update to upstream version '8.1.1+dfsg'
with Debian dir 627945d7abf17e002e5f04f165ced5caa9fb6935
- - - - -
b06271d5 by Bas Couwenberg at 2023-01-13T16:39:58+01:00
New upstream release.
- - - - -
3f62c4ef by Bas Couwenberg at 2023-01-13T17:18:58+01:00
Add patch to fix version detection from release notes.
- - - - -
08183f8f by Bas Couwenberg at 2023-01-13T18:45:02+01:00
Update symbols for amd64.
- - - - -
ada6569f by Bas Couwenberg at 2023-01-13T18:50:48+01:00
Add patch to fix spelling errors.
- - - - -
317ac65b by Bas Couwenberg at 2023-01-13T18:50:48+01:00
Set distribution to unstable.
- - - - -
19 changed files:
- .gitlab-ci.yml
- CI/headers_check.py
- CMakeLists.txt
- + Docker/Dockerfile
- + Docker/system-dependencies.txt
- Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
- Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx
- Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.h
- Modules/IO/IOGDAL/include/otbDEMHandler.h
- Modules/IO/IOGDAL/src/otbDEMHandler.cxx
- Modules/IO/IOGDAL/src/otbGDALRPCTransformer.cxx
- Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest.cxx
- Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx
- RELEASE_NOTES.txt
- debian/changelog
- debian/libotbiogdal-8.1-1.symbols
- + debian/patches/release-notes-version.patch
- + debian/patches/series
- + debian/patches/spelling-errors.patch
Changes:
=====================================
.gitlab-ci.yml
=====================================
@@ -51,6 +51,7 @@ stages:
- build
- report
- deploy
+ - docker
.general:
retry:
@@ -424,3 +425,18 @@ release-container:
--form ref=master
--form variables[OTB_TAG]=$CI_COMMIT_TAG
https://gitlab.orfeo-toolbox.org/api/v4/projects/126/trigger/pipeline
+
+release-docker:
+ image:
+ name: gcr.io/kaniko-project/executor:debug
+ entrypoint: [""]
+ stage: docker
+ only:
+ refs:
+ - /^release-[0-9]+\.[0-9]+$/
+ script:
+ - /kaniko/executor --cleanup
+ --verbosity warn
+ --context $CI_PROJECT_DIR/Docker
+ --dockerfile $CI_PROJECT_DIR/Docker/Dockerfile
+ --destination $CI_REGISTRY_IMAGE/orfeotoolbox/otb:$CI_COMMIT_BRANCH
=====================================
CI/headers_check.py
=====================================
@@ -129,6 +129,8 @@ excludedfiles = set([
'./CMake/exportheader.cmake.in',
'./CMake/pre-commit',
'./CMake/qt.conf.in',
+ './Docker/Dockerfile',
+ './Docker/system-dependencies.txt',
'./Documentation/Cookbook/Art/residual_registration-figure.tex',
'./Documentation/Cookbook/rst/Makefile.in',
'./Documentation/Cookbook/rst/conf.py.in',
=====================================
CMakeLists.txt
=====================================
@@ -153,7 +153,7 @@ set(main_project_name ${_OTBModuleMacros_DEFAULT_LABEL})
# OTB version number.
set(OTB_VERSION_MAJOR "8")
set(OTB_VERSION_MINOR "1")
-set(OTB_VERSION_PATCH "0")
+set(OTB_VERSION_PATCH "1")
set(OTB_VERSION_STRING "${OTB_VERSION_MAJOR}.${OTB_VERSION_MINOR}.${OTB_VERSION_PATCH}")
get_package_name(${OTB_SOURCE_DIR} ${PROJECT_NAME} OTB_VERSION_STRING2)
=====================================
Docker/Dockerfile
=====================================
@@ -0,0 +1,51 @@
+#
+# Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
+#
+# This file is part of Orfeo Toolbox
+#
+# https://www.orfeo-toolbox.org/
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+FROM ubuntu:20.04
+ARG OTB_RELEASE=8.0.0
+
+# Install system dependencies
+COPY system-dependencies.txt .
+RUN apt-get update -y \
+ && apt-get upgrade -y \
+ && cat system-dependencies.txt | DEBIAN_FRONTEND=noninteractive xargs apt-get install -y --no-install-recommends \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/* system-dependencies.txt
+
+# Install pre-compiled OTB binaries
+RUN curl https://www.orfeo-toolbox.org/packages/archives/OTB/OTB-$OTB_RELEASE-Linux64.run -o OTB-$OTB_RELEASE-Linux64.run \
+ && chmod +x OTB-$OTB_RELEASE-Linux64.run \
+ && ./OTB-$OTB_RELEASE-Linux64.run --target /opt/otb \
+ && rm OTB-$OTB_RELEASE-Linux64.run
+
+# Symlink Python library to a known path for OTB
+RUN ln -s /usr/lib/x86_64-linux-gnu/libpython3.8.so /opt/otb/lib/libpython3.8.so.rh-python38-1.0
+
+# Persistant env
+ENV CMAKE_PREFIX_PATH=/opt/otb
+ENV PYTHONPATH=/opt/otb/lib/python
+ENV GDAL_DRIVER_PATH=disable
+ENV GDAL_DATA=/opt/otb/share/gdal
+ENV PROJ_LIB=/opt/otb/share/proj
+ENV PATH=/opt/otb/bin:$PATH
+ENV OTB_APPLICATION_PATH=/opt/otb/lib/otb/applications
+ENV LC_NUMERIC=C
+
+# Default command when using 'docker run' or 'docker create'
+CMD /bin/bash
=====================================
Docker/system-dependencies.txt
=====================================
@@ -0,0 +1,30 @@
+ca-certificates
+curl
+libxcb1
+libxcb-composite0
+libxcb-glx0
+libxcb-icccm4
+libxcb-image0
+libxcb-keysyms1
+libxcb-randr0
+libxcb-render0
+libxcb-render-util0
+libxcb-util1
+libxcb-shm0
+libxcb-xfixes0
+libxcb-xinerama0
+libxcb-xinput0
+libxcb-xkb1
+libxcb-shape0
+libx11-xcb1
+libglu1-mesa
+libxrender1
+libxi6
+libxkbcommon0
+libxkbcommon-x11-0
+libxinerama1
+python3
+python3-dev
+python3-numpy
+libtool
+libopengl0
=====================================
Modules/Applications/AppSegmentation/app/otbSegmentation.cxx
=====================================
@@ -193,8 +193,10 @@ private:
AddParameter(ParameterType_String, "filter.cc.expr", "Condition");
SetParameterDescription("filter.cc.expr",
- "User defined connection condition, written as a mathematical expression. Available variables are p(i)b(i), intensity_p(i) and "
- "distance (example of expression: distance < 10 )");
+ "User defined connection condition, written as a mathematical expression. "
+ "Available variables are 'p(i)b(i)', 'intensity_p(i)' and "
+ "'distance'. Substitute (i) by the desired value. "
+ "Example of expression: intensity_p2 > 0.5.");
// Watershed
AddChoice("filter.watershed", "Watershed");
=====================================
Modules/Filtering/Projection/include/otbPhysicalToRPCSensorModelImageFilter.hxx
=====================================
@@ -22,7 +22,6 @@
#define otbPhysicalToRPCSensorModelImageFilter_hxx
#include "otbPhysicalToRPCSensorModelImageFilter.h"
-#include "otbDEMHandler.h"
namespace otb
{
=====================================
Modules/Filtering/VectorDataManipulation/include/otbVectorDataExtractROI.h
=====================================
@@ -23,7 +23,6 @@
#include "otbVectorDataToVectorDataFilter.h"
#include "otbRemoteSensingRegion.h"
-#include "otbDEMHandler.h"
#include "itkMacro.h"
#include "itkPreOrderTreeIterator.h"
=====================================
Modules/IO/IOGDAL/include/otbDEMHandler.h
=====================================
@@ -22,7 +22,11 @@
#define otbDEMHandler_h
#include "otbImage.h"
-#include "otbGDALDriverManagerWrapper.h"
+#include "otbGDALDatasetWrapper.h"
+#include <string>
+#include <list>
+#include <vector>
+#include <memory>
namespace otb
{
@@ -32,10 +36,15 @@ namespace otb
* \brief Observer design pattern to keep track of DEM configuration changes
* \ingroup OTBIOGDAL
*/
-class DEMObserverInterface {
- public:
- virtual ~DEMObserverInterface() = default;
+class DEMObserverInterface
+{
+public:
virtual void Update() = 0;
+protected:
+ DEMObserverInterface() = default;
+ ~DEMObserverInterface() = default;
+ DEMObserverInterface(DEMObserverInterface const&) = delete;
+ DEMObserverInterface& operator=(DEMObserverInterface const&) = delete;
};
/** \class DEMSubjectInterface
@@ -43,17 +52,26 @@ class DEMObserverInterface {
* \brief Observer design pattern to keep track of DEM configuration changes
* \ingroup OTBIOGDAL
*/
-class DEMSubjectInterface {
- public:
- virtual ~DEMSubjectInterface() = default;
+class DEMSubjectInterface
+{
+public:
virtual void AttachObserver(DEMObserverInterface *observer) = 0;
virtual void DetachObserver(DEMObserverInterface *observer) = 0;
virtual void Notify() const = 0;
+protected:
+ DEMSubjectInterface() = default;
+ ~DEMSubjectInterface() = default;
+ DEMSubjectInterface(DEMSubjectInterface const&) = delete;
+ DEMSubjectInterface& operator=(DEMSubjectInterface const&) = delete;
};
+// Forward declaration of the class at this point. No need to expose the
+// full class definition.
+class DEMHandlerTLS;
+
/** \class DEMHandler
*
- * \brief Single access point for DEM data retrieval
+ * \brief Single access point for DEM data retrieval.
*
* This class is the single configuration and access point for
* elevation handling in images projections and localization
@@ -65,15 +83,15 @@ class DEMSubjectInterface {
* functionalities.
*
* The class allows configuring a directory containing DEM tiles
- * (raster tiles will be opened by GDAL drivers) using the OpenDEMDirectory()
- * method. the OpenGeoidFile() method allows inputting a geoid file as well.
+ * (raster tiles will be opened by GDAL drivers) using the OpenDEMDirectory()
+ * method. the OpenGeoidFile() method allows inputting a geoid file as well.
* Last, a default height above ellipsoid can be set using the
* SetDefaultHeightAboveEllipsoid() method.
*
* The class allows retrieving either height above ellipsoid or
* height above Mean Sea Level (MSL).
*
- * Here is the complete description of both methods output depending
+ * Here is the complete description of both functions output depending
* on the class configuration for the SRTM DEM (in the following, no
* SRTM means DEMDirectory not set, or no coverage for point, or
* srtm_value is no_data).
@@ -95,130 +113,203 @@ class DEMSubjectInterface {
class DEMHandler : public DEMSubjectInterface
{
public:
- using Self = DEMHandler;
- using PointType = itk::Point<double, 2>;
-
- using DatasetUPtr = std::unique_ptr<GDALDataset, void(*)(GDALDataset*)>;
+ using Self = DEMHandler;
+ using PointType = itk::Point<double, 2>;
/** Retrieve the singleton instance */
static DEMHandler & GetInstance();
- /** Try to open the DEM directory.
- * \param path input path
- */
- void OpenDEMFile(const std::string & path);
+ /** Open all raster in the directory.
+ * \param[in] DEMDirectory input directory
+ */
+ void OpenDEMDirectory(std::string DEMDirectory);
- /** Open all raster in the directory.
- * \param DEMDirectory input directory
- */
- void OpenDEMDirectory(const std::string& DEMDirectory);
+ /** Try to open the DEM directory.
+ * \param[in] path input path
+ */
+ void OpenDEMFile(std::string path);
/** Tells whether the directory contains a raster
- * \param DEMDirectory input directory
- */
+ * \param[in] DEMDirectory input directory
+ */
bool IsValidDEMDirectory(const std::string& DEMDirectory) const;
- /** Try to open a geoid file
- * \param geoidFile input geoid path
- */
- bool OpenGeoidFile(const std::string& geoidFile);
+ /** Try to open a geoid file
+ * \param[in] geoidFile input geoid path
+ */
+ bool OpenGeoidFile(std::string geoidFile);
/** Return the height above the ellipsoid :
* - SRTM and geoid both available: srtm_value + geoid_offset
* - No SRTM but geoid available: geoid_offset
* - SRTM available, but no geoid: srtm_value
* - No SRTM and no geoid available: default height above ellipsoid
- * \param lon input longitude
- * \param lat input latitude
+ * \param[in] lon input longitude
+ * \param[in] lat input latitude
* \return height above ellipsoid
*/
double GetHeightAboveEllipsoid(double lon, double lat) const;
double GetHeightAboveEllipsoid(const PointType& geoPoint) const;
-
+
/** Return the height above the mean sea level :
* - SRTM and geoid both available: srtm_value
* - No SRTM but geoid available: 0
* - SRTM available, but no geoid: srtm_value
* - No SRTM and no geoid available: 0
- * \param lon input longitude
- * \param lat input latitude
+ * \param[in] lon input longitude
+ * \param[in] lat input latitude
* \return height above mean sea level
*/
double GetHeightAboveMSL(double lon, double lat) const;
-
double GetHeightAboveMSL(const PointType& geoPoint) const;
+ /** Return the offset information from the Geoid.
+ * \param[in] lon input longitude
+ * \param[in] lat input latitude
+ * \return Geoid offset
+ */
+ double GetGeoidHeight(double lon, double lat) const;
+ double GetGeoidHeight(const PointType& geoPoint) const;
+
/** Return the number of DEM opened */
- unsigned int GetDEMCount() const;
-
- double GetDefaultHeightAboveEllipsoid() const;
+ std::size_t GetDEMCount() const noexcept;
+
+ double GetDefaultHeightAboveEllipsoid() const noexcept;
void SetDefaultHeightAboveEllipsoid(double height);
- /** Get DEM directory
- * \param idx directory index
+ /** Get n-th DEM directory name.
+ * \param[in] idx directory index
* \return the DEM directory corresponding to index idx
+ * \throw std::out_of_range if `idx >= GetNumberOfDEMDirectories()`
*/
- std::string GetDEMDirectory(unsigned int idx = 0) const;
+ std::string const& GetDEMDirectory(std::size_t idx = 0) const;
+
+ std::size_t GetNumberOfDEMDirectories() const noexcept
+ { return m_DEMDirectories.size(); }
/** Get Geoid file */
- std::string GetGeoidFile() const;
+ std::string const& GetGeoidFile() const noexcept;
- /** Clear the DEM list and geoid filename, close all elevation datasets
- * and reset the default height above ellipsoid */
+ /** Clear the DEM list and geoid filename, close all elevation datasets
+ * and reset the default height above ellipsoid.
+ */
void ClearElevationParameters();
-
- /** Add an element to the current list of observers. The obsever will be updated whenever the DEM configuration
- is modified*/
+
+ /** Add an element to the current list of observers.
+ * The obsever will be updated whenever the DEM configuration is
+ * modified
+ */
void AttachObserver(DEMObserverInterface *observer) override {m_ObserverList.push_back(observer);};
-
+
/** Remove an element of the current list of observers. */
void DetachObserver(DEMObserverInterface *observer) override {m_ObserverList.remove(observer);};
-
+
/** Update all observers */
void Notify() const override;
/** Path to the in-memory vrt */
- const std::string DEM_DATASET_PATH = "/vsimem/otb_dem_dataset.vrt";
- const std::string DEM_WARPED_DATASET_PATH = "/vsimem/otb_dem_warped_dataset.vrt";
- const std::string DEM_SHIFTED_DATASET_PATH = "/vsimem/otb_dem_shifted_dataset.vrt";
+ static constexpr char const* DEM_DATASET_PATH = "/vsimem/otb_dem_dataset.vrt";
+ static constexpr char const* DEM_WARPED_DATASET_PATH = "/vsimem/otb_dem_warped_dataset.vrt";
+ static constexpr char const* DEM_SHIFTED_DATASET_PATH = "/vsimem/otb_dem_shifted_dataset.vrt";
-protected:
- DEMHandler();
+ /** Accessor to the current (thread-wise) DEM handler.
+ *
+ * Returns the instance of `DEMHandlerTLS` that is meant to be used
+ * exclusively from the current thread.
+ *
+ * As a microoptimisation, this function is public and can be used
+ * from places like `ThreadedGenerateData()` to extract a local
+ * reference to the instance of the handler, which could then be used
+ * with `GetHeightAboveEllipsoid(DEMHandlerTLS const&, double lon,
+ * double lat)` and so on.
+ *
+ * \internal
+ * If no handler has been attributed to the current thread, one will be
+ * picked from the `m_tlses` pool, or created on the fly thanks to
+ * `DoFetchOrCreateHandler`.
+ *
+ * This function is just a facade that caches the static thread local
+ * `DEMHandlerTLS` attributed to the current thread.
+ */
+ DEMHandlerTLS const& GetHandlerForCurrentThread() const;
+protected:
+ /**
+ * Default constructor.
+ * Takes care of calling `GDALAllRegister()`.
+ */
+ DEMHandler();
+ /** Destructor.
+ * \post `DEM_DATASET_PATH`, `DEM_WARPED_DATASET_PATH` and
+ * `DEM_SHIFTED_DATASET_PATH` files are deleted.
+ * \post release shared ownership of the `DEMHandlerTLS` instances.
+ */
~DEMHandler();
private:
- DEMHandler(const Self&) = delete;
- void operator=(const Self&) = delete;
- void CreateShiftedDataset();
+ /** Internal function to fetch from the pool or create a new
+ * `DEMHandlerTLS.
+ */
+ std::shared_ptr<DEMHandlerTLS> DoFetchOrCreateHandler() const;
+
+ /** (Re)sets GEOID and DEM directory information in the handler.
+ * This function is meant to be called from `DoFetchOrCreateHandler` only:
+ * when a thread needs a new `DEMHandlerTLS` which is created on the fly.
+ * It's not thread safe!
+ *
+ * @warning DO NOT change the GEOID filename or the list of DEM directories
+ * while this function is being executed. These information should only be
+ * changed from a main thread, not from processing threads!
+ */
+ void RegisterConfigurationInHandler(DEMHandlerTLS & handler) const;
- /** Clear the DEM list and close all DEM datasets */
- void ClearDEMs();
-
- /** List of RAII capsules on all opened DEM datasets for memory management */
- std::vector<otb::GDALDatasetWrapper::Pointer> m_DatasetList;
-
- /** Pointer to the DEM dataset */
- DatasetUPtr m_Dataset = DatasetUPtr(nullptr, [](GDALDataset* DS){if(DS){GDALClose(DS);}});
+ DEMHandler(const Self&) = delete;
+ void operator=(const Self&) = delete;
- /** Pointer to the geoid dataset */
- DatasetUPtr m_GeoidDS = DatasetUPtr(nullptr, [](GDALDataset* DS){if(DS){GDALClose(DS);}});
-
/** 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;
+ /** List of RAII capsules on all opened DEM datasets for memory management */
+ std::vector<otb::GDALDatasetWrapper::Pointer> m_DatasetList;
+
/** Filename of the current geoid */
std::string m_GeoidFilename;
/** Observers on the DEM */
std::list<DEMObserverInterface *> m_ObserverList;
+
+ /** Pool of actual thread local DEM handlers. */
+ mutable std::vector<std::shared_ptr<DEMHandlerTLS>> m_tlses;
+
};
+
+/**\name Fast conviennce access functions
+ * \ingroup OTBIOGDAL
+ *
+ * DEM fast conviennce access functions.
+ *
+ * These functions are provided to be used with a `DEMHandlerTLS`
+ * instance that could (and should) be obtained in any
+ * `ThreadedGenerateData()` function where `DEMHandler` would be used.
+ *
+ * \see the eponym functions from `DEMHandler` for what they actually
+ * return
+ */
+/// @{
+double GetHeightAboveEllipsoid(DEMHandlerTLS const&, double lon, double lat);
+double GetHeightAboveMSL (DEMHandlerTLS const&, double lon, double lat);
+double GetGeoidHeight (DEMHandlerTLS const&, double lon, double lat);
+double GetHeightAboveEllipsoid(DEMHandlerTLS const&, itk::Point<double, 2> geoPoint);
+double GetHeightAboveMSL (DEMHandlerTLS const&, itk::Point<double, 2> geoPoint);
+double GetGeoidHeight (DEMHandlerTLS const&, itk::Point<double, 2> geoPoint);
+/// @}
+
}
#endif
=====================================
Modules/IO/IOGDAL/src/otbDEMHandler.cxx
=====================================
@@ -20,7 +20,7 @@
#include "otbDEMHandler.h"
#include "otbGDALDriverManagerWrapper.h"
-#include "boost/filesystem.hpp"
+#include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp>
#include "gdal_utils.h"
@@ -28,22 +28,31 @@
#include "gdalwarper.h"
#include "vrtdataset.h"
+#include "ogr_spatialref.h"
+
//TODO C++ 17 : use std::optional instead
#include <boost/optional.hpp>
#include <mutex>
+#include <thread>
+#include <memory>
+#include <sstream>
-#include "ogr_spatialref.h"
+namespace
+{ // Anonymous namespace
+std::mutex demMutex;
+} // Anonymous namespace
namespace otb {
namespace DEMDetails {
-// Adapted from boost filesystem documentation : https://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html
+// Adapted from boost filesystem documentation:
+// https://www.boost.org/doc/libs/1_53_0/libs/filesystem/doc/reference.html
std::vector<std::string> GetFilesInDirectory(const std::string & directoryPath)
{
std::vector<std::string> fileList;
-
+
if ( !boost::filesystem::exists( directoryPath) )
{
return fileList;
@@ -53,23 +62,23 @@ std::vector<std::string> GetFilesInDirectory(const std::string & directoryPath)
fileList.push_back(directoryPath);
return fileList;
}
-
- // End iterator : default construction yields past-the-end
+
+ // End iterator: default construction yields past-the-end
for ( const auto & item : boost::make_iterator_range(boost::filesystem::directory_iterator(directoryPath), {}) )
{
try
{
if ( boost::filesystem::is_directory(item.status()) )
{
- auto subDirList = GetFilesInDirectory(item.path().string());
- fileList.insert(fileList.end(), subDirList.begin(), subDirList.end());
+ auto subDirList = GetFilesInDirectory(item.path().string());
+ fileList.insert(fileList.end(), subDirList.begin(), subDirList.end());
}
else
{
- fileList.push_back(item.path().string());
+ fileList.push_back(item.path().string());
}
}
- catch (boost::filesystem::filesystem_error& e)
+ catch (boost::filesystem::filesystem_error const& e)
{
otbLogMacro(Warning, << e.what())
}
@@ -78,277 +87,689 @@ std::vector<std::string> GetFilesInDirectory(const std::string & directoryPath)
return fileList;
}
-std::mutex demMutex;
-
-boost::optional<double> GetDEMValue(double lon, double lat, GDALDataset& ds)
+/**
+ * Internal RAII wrapper for providing access to `GDALDataset` and
+ * caching related information (projection for WGS84 case and geo
+ * transformation).
+ *
+ * \invariant if WGS84 then `(m_Dataset != nullptr) == (m_poCT != nullptr)`
+ * \internal
+ */
+struct DatasetCache
{
- const std::lock_guard<std::mutex> lock(demMutex);
+ /**@name `GDALDataset` accessors */
+ /** @{ */
+ GDALDataset * get () const { return m_Dataset.get();}
+ GDALDataset * operator-> () const { return m_Dataset.get();}
+ GDALDataset & operator* () const { assert(m_Dataset); return *m_Dataset;}
+ /** @} */
+
+ /// Tells whether a valid dataset is associated.
+ explicit operator bool() const { return bool(m_Dataset); }
+
+ DatasetCache() = default;
+ ~DatasetCache() = default;
+
+ /** Constructor that takes over a `GDALDataset` ownership.
+ * \post Projection information will have been fetched (if WGS84).
+ * \post Geo Transform information will have been fetched
+ */
+ explicit DatasetCache(GDALDataset *ds)
+ { reset(ds); }
+
+ /** Constructor from a filename.
+ * \post Projection information will have been fetched (if WGS84).
+ * \post Geo Transform information will have been fetched
+ */
+ explicit DatasetCache(std::string const& file)
+ : DatasetCache(static_cast<GDALDataset*>(GDALOpen(file.c_str(), GA_ReadOnly)))
+ {}
+
+ /** Release ownership of the dataset.
+ * And clear projection related information.
+ */
+ void release()
+ {
+ m_Dataset.release();
+ m_poCT.release();
+ m_isWGS84 = false;
+ }
+ /** Takes over a `GDALDataset` ownership.
+ * \post Projection information will have been fetched (if WGS84).
+ * \post Geo Transform information will have been fetched
+ */
+ void reset(GDALDataset* ds)
+ {
+ m_Dataset.reset(ds);
+ if (m_Dataset)
+ {
#if GDAL_VERSION_NUM >= 3000000
- auto srs = ds.GetSpatialRef();
+ auto srs = ds->GetSpatialRef();
#else
- auto projRef = ds.GetProjectionRef();
-
- std::unique_ptr<OGRSpatialReference> srsUniquePtr;
- OGRSpatialReference* srs = nullptr;
- // GetProjectionRef() returns an empty non null string if no projection is available
- if (strlen(projRef) != 0 )
- {
- srsUniquePtr = std::make_unique<OGRSpatialReference>(ds.GetProjectionRef());
- srs = srsUniquePtr.get();
- }
+ auto projRef = ds->GetProjectionRef();
+
+ std::unique_ptr<OGRSpatialReference> srsUniquePtr;
+ OGRSpatialReference* srs = nullptr;
+ // GetProjectionRef() returns an empty non null string if no projection is available
+ if (strlen(projRef) != 0 )
+ {
+ srsUniquePtr = std::make_unique<OGRSpatialReference>(ds->GetProjectionRef());
+ srs = srsUniquePtr.get();
+ }
#endif
- auto wgs84Srs = OGRSpatialReference::GetWGS84SRS();
+ static auto const& wgs84Srs = OGRSpatialReference::GetWGS84SRS(); // 1%
+ m_isWGS84 = false;
- // Convert input lon lat into the coordinates defined by the dataset if needed.
- if (srs && !srs->IsSame(wgs84Srs))
- {
- auto poCT = std::unique_ptr<OGRCoordinateTransformation>
- (OGRCreateCoordinateTransformation(wgs84Srs, srs));
+ // Convert input lon lat into the coordinates defined by the dataset if needed.
+ if (srs && !srs->IsSame(wgs84Srs)) // 10% of the time
+ {
+ m_isWGS84 = true;
+ m_poCT = std::unique_ptr<OGRCoordinateTransformation>
+ (OGRCreateCoordinateTransformation(wgs84Srs, srs));
+ }
+
+ m_Dataset->GetGeoTransform(m_geoTransform);
- if (poCT && !poCT->Transform( 1, &lon, &lat ) )
+ m_NoDataValue = m_Dataset->GetRasterBand(1)->GetNoDataValue();
+ }
+ else
{
- return boost::none;
+ m_poCT.release();
}
}
- double geoTransform[6];
-
- ds.GetGeoTransform(geoTransform);
+ /** Convert {lon, lat} coordinates if WGS84 and projection is
+ * defined.
+ *
+ * \todo what about `isWGS84() == true` and projection is not defined?
+ * Is it even even possible?
+ */
+ bool convert_lon_lat(double & lon, double & lat) const
+ {
+ assert((m_poCT || !isWGS84()) && "Expected: isWGS84() => projection is defined"); // => no need to test isWGS84
+ if (/*isWGS84() &&*/ m_poCT) {
+ return m_poCT->Transform( 1, &lon, &lat );
+ }
+ return true;
+ }
- auto x = (lon - geoTransform[0]) / geoTransform[1] - 0.5;
- auto y = (lat - geoTransform[3]) / geoTransform[5] - 0.5;
+ /// Apply geo transformation to return pixels associated to {lon, * lat}.
+ std::pair<double, double> transform(double lon, double lat) const
+ {
+ auto const x = (lon - m_geoTransform[0]) / m_geoTransform[1] - 0.5;
+ auto const y = (lat - m_geoTransform[3]) / m_geoTransform[5] - 0.5;
+ return std::make_pair(x, y);
+ }
+
+ bool isWGS84() const noexcept { return m_isWGS84; }
+
+ /// Accessors to Geo Transformation.
+ double * getGeoTransform() noexcept { return m_geoTransform;}
+ double const* getGeoTransform() const noexcept { return m_geoTransform;}
+
+ /// Accessor to No Data value
+ double GetNoDataValue() const noexcept { return m_NoDataValue;}
+
+
+ DatasetCache & operator=(DatasetCache const&) = delete;
+ DatasetCache & operator=(DatasetCache && ) = default;
- if (x < 0 || y < 0 || x > ds.GetRasterXSize() || y > ds.GetRasterYSize())
+private:
+ using DatasetUPtr = std::unique_ptr<GDALDataset, void(*)(GDALDataset*)>;
+ using OCT_ptr = std::unique_ptr<OGRCoordinateTransformation>;
+ DatasetUPtr m_Dataset = DatasetUPtr(nullptr, [](GDALDataset* DS){if(DS){GDALClose(DS);}});
+ OCT_ptr m_poCT;
+ bool m_isWGS84 = false;
+ double m_geoTransform[6] = {};
+ double m_NoDataValue = {};
+};
+
+/**
+ * Obtain DEM value from dataset at specified position.
+ *
+ * General operation sequence:
+ * 1. Convert {lon, lat} in WGS84 case
+ * 2. Computed associated pixel coordinates (in floatting point unit)
+ * thanks to geo transformation
+ * 3. Extract 4 pixels around the desired position
+ * 4. Interpolate the final elevation
+ *
+ * \return `boost::none` if {lon, lat} conversion cannot be achieved
+ * \return `boost::none` if {lon, lat} conversion cannot be achieved
+ * \return `boost::none` if pixel extractions from file fails
+ * \return elevation according to DEM at {lot, lat} position
+ * \internal
+ */
+boost::optional<double> GetDEMValue(double lon, double lat, DatasetCache const& dsc)
+{
+ if (!dsc.convert_lon_lat(lon, lat))
{
return boost::none;
}
- auto x_int = static_cast<int>(x);
- auto y_int = static_cast<int>(y);
+ // C++17 use: `auto const [x,y] = dsc.transform(lon, lat);`
+ auto const xy = dsc.transform(lon, lat);
+ auto const x = xy.first;
+ auto const y = xy.second;
- auto deltaX = x - x_int;
- auto deltaY = y - y_int;
+ auto is_out_raster = [&](auto x, auto y, GDALDataset & ds) {
+ return x < 0
+ || y < 0
+ || 1+x > ds.GetRasterXSize() // no need to test x > size
+ || 1+y > ds.GetRasterYSize(); // no need to test Y > size
+ };
- if (x < 0 || y < 0 || x+1 > ds.GetRasterXSize() || y+1 > ds.GetRasterYSize())
+ if (is_out_raster(x, y, *dsc))
{
return boost::none;
}
-
+
+ auto const x_int = static_cast<int>(x);
+ auto const y_int = static_cast<int>(y);
+
+ auto const deltaX = x - x_int;
+ auto const deltaY = y - y_int;
+
// 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, nullptr);
+
+ auto const err = dsc->GetRasterBand(1)->RasterIO( GF_Read, x_int, y_int, 2, 2,
+ elevData, 2, 2, GDT_Float64,
+ 0, 0, nullptr);
if (err)
{
return boost::none;
}
- // 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++)
+ // Test for no data. Don't return a value if any pixel of the
+ // interpolation has no data.
+ auto const no_data = dsc.GetNoDataValue();
+ auto const has_no_data = [=](auto const v){ return v == no_data; };
+ if(std::any_of(std::begin(elevData), std::end(elevData), has_no_data))
{
- if (elevData[i] == ds.GetRasterBand(1)->GetNoDataValue())
- {
- return boost::none;
- }
+ return boost::none;
}
- auto xBil1 = elevData[0] * (1-deltaX) + elevData[1] * deltaX;
- auto xBil2 = elevData[2] * (1-deltaX) + elevData[3] * deltaX;
+ // C++20: use std::lerp for better precision (expected to be slower)
+ auto const xBil1 = elevData[0] * (1.0 - deltaX) + elevData[1] * deltaX;
+ auto const xBil2 = elevData[2] * (1.0 - deltaX) + elevData[3] * deltaX;
- auto yBil = xBil1 * (1.0 - deltaY) + xBil2 * deltaY;
+ auto const yBil = xBil1 * (1.0 - deltaY) + xBil2 * deltaY;
return yBil;
}
+/**
+ * Tells whether the dataset has a Geo Transformation.
+ * \internal
+ */
+bool HasGeoTransform(GDALDataset & gdalds)
+{
+ std::array<double, 6> a;
+ return gdalds.GetGeoTransform(a.data()) == CE_None;
+}
+
} // namespace DEMDetails
+
+/** Internal actual instance of DEM handling wrapper for current thread.
+ * \ingroup OTBIOGDAL
+ *
+ * `GDALDataset` isn't thread safe. However, several datasets can be
+ * opened to the same image. Instances of this class are meant to
+ * provide the final access to `GDALDataset` and live as singletons
+ * in each thread.
+ *
+ * \internal This class is not exposed to other code. It's meant to be
+ * used through `DEMHandler` singleton.
+ *
+ * The current design has one `DEMHandlerTLS` per actual thread. In case
+ * threads are terminated and restarted multiple time (this is the case
+ * with default old ITK 4 architecture that will terminate and respawn
+ * thread for new OTB stream), `DEMHandlerTLS` instance will be
+ * destroyed and re-recreated instead of being reused.
+ *
+ * To reuse the instances of `DEMHandlerTLS` we could:
+ * - have a kind of pool of `DEMHandlerTLS` instances, and a
+ * thread_local pointer of the instance attributed to the current
+ * thread. Attributing an instance the first time would require a lock
+ * to search a free instance in the pool. The TLS object could be a
+ * RAII capsule that returns the `DEMHandlerTLS` instance to the pool.
+ */
+class DEMHandlerTLS
+{
+public:
+ double GetHeightAboveEllipsoid(double lon, double lat, double defaultHeight) const;
+ boost::optional<double> GetHeightAboveMSL(double lon, double lat) const;
+ boost::optional<double> GetGeoidHeight(double lon, double lat) const;
+
+ DEMHandlerTLS() {
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandlerTLS::DEMHandlerTLS() --> " << this);
+ }
+ ~DEMHandlerTLS() {
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandlerTLS::~DEMHandlerTLS() --> " << this);
+ }
+
+ bool OpenDEMVRTFile();
+ void CloseDEMVRTFile();
+
+ /** Try to open a geoid file
+ * \param geoidFile input geoid path
+ */
+ bool OpenGeoidFile(std::string const& geoidFile);
+
+ /** Clear the DEM list and geoid filename, close all elevation datasets
+ * and reset the default height above ellipsoid */
+ void ClearElevationParameters();
+
+ void CreateShiftedDatasetOnce() const;
+
+private:
+ DEMHandlerTLS(DEMHandlerTLS const&) = delete;
+ void operator=(DEMHandlerTLS const&) = delete;
+
+ using DatasetUPtr = std::unique_ptr<GDALDataset, void(*)(GDALDataset*)>;
+
+ /** Pointer to the DEM dataset */
+ DEMDetails::DatasetCache m_DEMDS;
+
+ /** Pointer to the geoid dataset */
+ DEMDetails::DatasetCache m_GeoidDS;
+};
+
+DEMHandlerTLS const& DEMHandler::GetHandlerForCurrentThread() const
+{
+ static thread_local auto tls = DoFetchOrCreateHandler(); // no need to lock as this is a static TLS
+ return *tls;
+}
+
+std::shared_ptr<DEMHandlerTLS> DEMHandler::DoFetchOrCreateHandler() const
+{
+ // DEMHandlerTLS instances are shared between the global DEMHandler
+ // singleton and the (unique) thread they are associated to.
+ // When a thread terminates, its TLS are destroyed. And as such the
+ // shared_ptr DEMHandlerTLS are destroyed, which decrements the owning count
+ // by 1.
+ // When the DEMHandler singleton is destroyed, each DEMHandlerTLS shared_ptr
+ // is destroyed, and the count is decreased by 1.
+ // When the count reaches 0, the DEMHandlerTLS is actually destroyed.
+ // Infortunately we cannot be sure TLS variables are destroyed before the
+ // DEMHandler singleton. Hence this convoluted approach with
+ // shared_ptr.
+
+ // With the chosen (shared_ptr based) approach, when the owning count is 1,
+ // this means only the DEMHandler singleton owns the TLS handler. And as
+ // such, it could be attributed to another thread.
+ auto handler_is_not_attributed_to_a_thread = [](auto const& h) { return h.use_count() == 1; };
+
+ std::unique_lock<std::mutex> lock(demMutex); // protecting m_tlses
+ for (auto & tls : m_tlses) {
+ if (handler_is_not_attributed_to_a_thread(tls)) {
+ return tls;
+ }
+ }
+ m_tlses.emplace_back(std::make_shared<DEMHandlerTLS>());
+ auto res = m_tlses.back();
+ lock.unlock(); // No need to keep the lock any more thanks to the copy
+ // of the shared_ptr `res` from the vector that could
+ // be resized... (which would invalidate any reference
+ // to back())
+ RegisterConfigurationInHandler(*res);
+ return res;
+}
+
+void DEMHandler::RegisterConfigurationInHandler(DEMHandlerTLS & tls) const
+{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::RegisterConfigurationInHandler(" << &tls <<")");
+ if (! m_DatasetList.empty()) {
+ if (! tls.OpenDEMVRTFile())
+ {
+ otbLogMacro(Warning, << "An unexpected situation has occured: trying to open a VRT created from incompatible DEM files");
+ assert(false);
+ // The following should not be necessary. In the impossible case
+ // the VRT file could not be opened, we just clear everything in
+ // Release mode (i.e. without assertions)
+ // Yes, the clearing has an extremely dirty use of const_cast...
+ const_cast<DEMHandler*>(this)->m_DatasetList.clear();
+ const_cast<DEMHandler*>(this)->m_DEMDirectories.clear();
+ }
+ }
+ if (!m_GeoidFilename.empty()) {
+ tls.OpenGeoidFile(m_GeoidFilename);
+ }
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::RegisterConfigurationInHandler(" << &tls <<") END");
+}
+
// Meyer singleton design pattern
-DEMHandler & DEMHandler::GetInstance()
+DEMHandler & DEMHandler::GetInstance()
{
static DEMHandler s_instance;
return s_instance;
}
-DEMHandler::DEMHandler() : m_DefaultHeightAboveEllipsoid(0.0)
+DEMHandler::DEMHandler()
+: m_DefaultHeightAboveEllipsoid(0.0)
{
GDALAllRegister();
}
DEMHandler::~DEMHandler()
{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::destructor()");
+
// Close all elevation datasets
ClearElevationParameters();
- VSIUnlink(DEM_DATASET_PATH.c_str());
- VSIUnlink(DEM_WARPED_DATASET_PATH.c_str());
- VSIUnlink(DEM_SHIFTED_DATASET_PATH.c_str());
+ // As elevation dataset have been closed, we can remove these files
+ VSIUnlink(DEMHandler::DEM_DATASET_PATH);
+ VSIUnlink(DEMHandler::DEM_WARPED_DATASET_PATH);
+ VSIUnlink(DEMHandler::DEM_SHIFTED_DATASET_PATH);
+
+ { // {} makes sure clearing m_tlses is synchronized
+ const std::lock_guard<std::mutex> lock(demMutex);
+ m_tlses.clear();
+ }
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::destructor() END");
+}
+
+void DEMHandlerTLS::CloseDEMVRTFile()
+{
+ m_DEMDS.release();
+}
+
+bool DEMHandlerTLS::OpenDEMVRTFile()
+{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandlerTLS::OpenDEMVRTFile() --> " << this);
+ // As we are reopening the same file: we should close it first!
+ assert(! m_DEMDS);
+ m_DEMDS = DEMDetails::DatasetCache(DEMHandler::DEM_DATASET_PATH);
+
+ // Note: we don't try to call CreateShiftedDatasetOnce() as the
+ // current implementation of DEMHandler::OpenGeoidFile() indirectly
+ // makes sure to do so by enforcing the existence of a DEMHandlerTLS
+ // instance. This will then trigger the call to
+ // CreateShiftedDatasetOnce() either from DEMHandler::OpenGeoidFile()
+ // and DEMHandler::OpenDEMDirectory()
+ // So... we can just exit
+ return !! m_DEMDS;
}
-void DEMHandler::OpenDEMFile(const std::string& path)
+void DEMHandler::OpenDEMFile(std::string path)
{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::OpenDEMFile("<<path<<")");
+
+ std::unique_lock<std::mutex> lock(demMutex); // protecting m_tlses
m_DatasetList.push_back(otb::GDALDriverManagerWrapper::GetInstance().Open(path));
- std::vector<GDALDatasetH> vrtDatasetList(1);
- vrtDatasetList[0] = m_DatasetList[0]->GetDataSet();
- auto close_me = GDALBuildVRT(DEM_DATASET_PATH.c_str(), 1, vrtDatasetList.data(),
- nullptr, nullptr, nullptr);
+ for (auto tls : m_tlses) {
+ tls->CloseDEMVRTFile();
+ }
+ // TODO: why [0] and not back()???
+ std::array<GDALDatasetH, 1> vrtDatasetList { m_DatasetList[0]->GetDataSet() };
+ auto close_me = GDALBuildVRT(DEMHandler::DEM_DATASET_PATH, 1, vrtDatasetList.data(),
+ nullptr, nullptr, nullptr);
// Need to close the dataset, so it is flushed into memory.
GDALClose(close_me);
- m_Dataset.reset(static_cast<GDALDataset*>(GDALOpen(DEM_DATASET_PATH.c_str(), GA_ReadOnly)));
- m_DEMDirectories.push_back(path);
-
- if(m_GeoidDS)
+ for (auto tls : m_tlses)
{
- CreateShiftedDataset();
+ if (! tls->OpenDEMVRTFile())
+ {
+ // Sometimes ungeoreferenced images are pushed into the VRT files,
+ // but as they are not supported, no VRT is produced
+ m_DatasetList.clear();
+ return ; // no push_back, no notification
+ }
}
-
+ m_DEMDirectories.push_back(move(path));
+ lock.unlock();
Notify();
}
-void DEMHandler::OpenDEMDirectory(const std::string& DEMDirectory)
+void DEMHandler::OpenDEMDirectory(std::string DEMDirectory)
{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::OpenDEMDirectory("<<DEMDirectory<<")");
auto isSameDirectory = [&DEMDirectory](std::string const& s)
- {
- return s == DEMDirectory;
- };
+ {
+ return s == DEMDirectory;
+ };
if(std::any_of(std::begin(m_DEMDirectories), std::end(m_DEMDirectories), isSameDirectory))
{
- otbLogMacro(Info, << "Directory '"<< DEMDirectory << "' already opened.")
+ otbLogMacro(Info, << "DEM Directory '"<< DEMDirectory << "' is already opened.");
return;
}
-
- // Free the previous in-memory dataset (if any)
- if (!m_DatasetList.empty())
- VSIUnlink(DEM_DATASET_PATH.c_str());
auto demFiles = DEMDetails::GetFilesInDirectory(DEMDirectory);
+ std::size_t nb_new_DEM_opened = 0;
+ // Check and open every dem files found in DEMDirectory
for (const auto & file : demFiles)
{
+ otbMsgDevMacro("Try to open DEM image: " << file);
auto ds = otb::GDALDriverManagerWrapper::GetInstance().Open(file);
if (ds)
{
- m_DatasetList.push_back(ds );
+ if (DEMDetails::HasGeoTransform(*ds->GetDataSet()))
+ {
+ m_DatasetList.push_back(ds);
+ ++nb_new_DEM_opened;
+ }
+ else
+ {
+ // GDAL VRT files cannot contain references to ungeoreferenced
+ // images, otherwise GDAL will issue messages like:
+ // > 662: Warning 1: gdalbuildvrt does not support ungeoreferenced image. Skipping BLA/BLA.TIF
+ // > ERROR 4: No such file or directory
+ otbLogMacro(Debug, << "Input image "<< file << " will not be used because it is ungeoreferenced.");
+ }
+ }
+ else
+ {
+ otbMsgDevMacro("Ignoring DEM image: " << file);
}
}
-
- int vrtSize = m_DatasetList.size();
-
+
// Don't build a vrt if there is no dataset
- if (m_DatasetList.empty())
+ if (nb_new_DEM_opened == 0)
{
- m_Dataset.reset(nullptr);
otbLogMacro(Warning, << "No DEM found in "<< DEMDirectory)
}
else
{
+ otbLogMacro(Info, << nb_new_DEM_opened << " DEM found in "<< DEMDirectory)
+ m_DEMDirectories.push_back(move(DEMDirectory)); // => parameter voluntary taken by value
+
+ // Clean before anything else: Free the previous in-memory dataset (if any)
+ if (m_DatasetList.size() != nb_new_DEM_opened)
+ {
+ const std::lock_guard<std::mutex> lock(demMutex);
+ for (auto tls : m_tlses) {
+ tls->CloseDEMVRTFile();
+ }
+ VSIUnlink(DEMHandler::DEM_DATASET_PATH);
+ }
+
+ // (Re-)Create the VRT from a list of opened dataset
+ std::size_t const vrtSize = m_DatasetList.size();
std::vector<GDALDatasetH> vrtDatasetList(vrtSize);
- for (int i = 0; i < vrtSize; i++)
+ for (std::size_t i = 0; i < vrtSize; i++)
{
vrtDatasetList[i] = m_DatasetList[i]->GetDataSet();
}
- auto close_me = GDALBuildVRT(DEM_DATASET_PATH.c_str(), vrtSize, vrtDatasetList.data(),
- nullptr, nullptr, nullptr);
+ otbMsgDevMacro("Building VRT from " << vrtSize << " datasets: " << DEMHandler::DEM_DATASET_PATH);
+ auto close_me = GDALBuildVRT(DEMHandler::DEM_DATASET_PATH, vrtSize, vrtDatasetList.data(),
+ nullptr, nullptr, nullptr);
// Need to close the dataset, so it is flushed into memory.
GDALClose(close_me);
- m_Dataset.reset(static_cast<GDALDataset*>(GDALOpen(DEM_DATASET_PATH.c_str(), GA_ReadOnly)));
- m_DEMDirectories.push_back(DEMDirectory);
- }
- if(m_GeoidDS)
- {
- CreateShiftedDataset();
+ const std::lock_guard<std::mutex> lock(demMutex);
+ {
+ // Check all requirements are satisfied to open de the VRT file.
+ // If not, clear everything.
+ DEMDetails::DatasetCache vrt(DEMHandler::DEM_DATASET_PATH);
+ // +--> TODO: DatasetCache will also try to check the
+ // projection... Can't we do better?
+ if (!vrt)
+ {
+ // Note: DEMDirectory has been moved into m_DEMDirectories
+ otbLogMacro(Warning, << "Input images from '"<< m_DEMDirectories.back() <<"' cannot be used to create a DEM VRT file, and as such they will be ignored.");
+ m_DatasetList.clear();
+ m_DEMDirectories.clear();
+ return ;
+ }
+ } // make sure to close the vrt (thanks to RAII)
+
+ for (auto tls : m_tlses)
+ {
+ if (! tls->OpenDEMVRTFile())
+ {
+ assert(false); // Should have been handled by the previous tests
+ // (HasGeoTransform + VRT validity tests)
+ // Sometimes ungeoreferenced images are pushed into the VRT files,
+ // but as they are not supported, no VRT is produced
+ m_DatasetList.clear();
+ m_DEMDirectories.clear();
+ return ;
+ }
+ }
+
+ if(!m_GeoidFilename.empty()) // still locked
+ { // Should be done from only one thread, and ... once!!
+ assert(! m_tlses.empty()); // Given OpenGeoidFile() implementation
+ // (where an instance of DEMHandlerTLS
+ // is fetched locally (to be sure there
+ // is at least one), we know that
+ // !m_GeoidFilename.empty() =>
+ // !m_tlses.empty()
+ m_tlses.front()->CreateShiftedDatasetOnce();
+ }
}
+
Notify();
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::OpenDEMDirectory() END");
}
-bool DEMHandler::OpenGeoidFile(const std::string& geoidFile)
+
+
+bool HasInputProjection(GDALDataset const& gdalds)
{
- auto gdalds = static_cast<GDALDataset*>(GDALOpen(geoidFile.c_str(), GA_ReadOnly));
+#if GDAL_VERSION_NUM >= 3000000
+ return gdalds.GetSpatialRef() && ! gdalds.GetSpatialRef()->IsEmpty()
+#else
+ GDALDataset& gdal_ds_for_v2_API=const_cast<GDALDataset&>(gdalds);
+ return gdal_ds_for_v2_API.GetProjectionRef()[0] != '\0' // strlen(gdalds.GetProjectionRef()) != 0
+#endif
+ ;
+}
+
+bool DEMHandlerTLS::OpenGeoidFile(const std::string& geoidFile)
+{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandlerTLS::OpenGeoidFile("<<geoidFile<<") --> " << this);
+ DEMDetails::DatasetCache gdalds(geoidFile);
if (!gdalds)
{
- otbLogMacro(Warning, << "Cannot open geoid file "<< geoidFile)
+ otbLogMacro(Warning, << "Cannot open geoid file "<< geoidFile);
return false;
}
-#if GDAL_VERSION_NUM >= 3000000
- if (!(gdalds->GetSpatialRef()) || gdalds->GetSpatialRef()->IsEmpty())
-#else
- if (strlen(gdalds->GetProjectionRef()) == 0 )
-#endif
+ if (! HasInputProjection(*gdalds))
{
- otbLogMacro(Warning, << "input geoid file "<< geoidFile << " will not be used because it has no input projection.")
+ otbLogMacro(Warning, << "Input geoid file "<< geoidFile << " will not be used because it has no input projection.");
return false;
}
- m_GeoidDS.reset(gdalds);
- m_GeoidFilename = geoidFile;
+ m_GeoidDS = std::move(gdalds);
+
+ return true;
+}
+
+bool DEMHandler::OpenGeoidFile(std::string geoidFile)
+{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandler::OpenGeoidFile("<<geoidFile<<")");
+
+ // In case the geoid is not valid, we still try to open it for real,
+ // even if the DEMHandlerTLS will not serve to anything...
+ // tls will also serve to call CreateShiftedDatasetOnce()
+ auto & tls = GetHandlerForCurrentThread();
+ (void) tls;
- if(m_Dataset)
+ int nb_success = 0;
{
- CreateShiftedDataset();
+ const std::lock_guard<std::mutex> lock(demMutex);
+ for (auto tls : m_tlses)
+ {
+ nb_success += tls->OpenGeoidFile(geoidFile) ? 1 : 0;
+ // if any is true, all should be!
+ }
+ } // <- release lock
+
+ if (nb_success != 0)
+ {
+ m_GeoidFilename = move(geoidFile); // => parameter voluntary taken by value
+ if (! m_DatasetList.empty())
+ { // In that case, we could expect TLS.m_DEMDS to be non-null
+ const std::lock_guard<std::mutex> lock(demMutex);
+ assert(!m_tlses.empty()); //
+ if (! m_DatasetList.empty())
+ {
+ // We just need to create it once, in any thread. The one created
+ // locally being good enough...
+ tls.CreateShiftedDatasetOnce();
+ }
+ }
}
-
Notify();
- return true;
+ return nb_success != 0;
}
-
-void DEMHandler::CreateShiftedDataset()
+void DEMHandlerTLS::CreateShiftedDatasetOnce() const
{
+ otbMsgDevMacro(<<std::this_thread::get_id() << " § DEMHandlerTLS::CreateShiftedDatasetOnce() --> " << this);
- // WIP : no data is not handed at the moment
-
- double geoTransform[6];
- m_Dataset->GetGeoTransform(geoTransform);
+ assert(m_DEMDS);
+ assert(m_GeoidDS);
+ // WIP : no data is not handled at the moment
// Warp geoid dataset
auto warpOptions = GDALCreateWarpOptions();;
- warpOptions->hSrcDS = m_GeoidDS.get();
- //warpOptions->hDstDS = m_Dataset;
- warpOptions->eResampleAlg = GRA_Bilinear;
+ warpOptions->hSrcDS = m_GeoidDS.get();
+ //warpOptions->hDstDS = m_Dataset;
+ warpOptions->eResampleAlg = GRA_Bilinear;
warpOptions->eWorkingDataType = GDT_Float64;
- warpOptions->nBandCount = 1;
- warpOptions->panSrcBands =
- (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount );
- warpOptions->panSrcBands[0] = 1;
- warpOptions->panDstBands =
- (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount );
- warpOptions->panDstBands[0] = 1;
+ warpOptions->nBandCount = 1;
+ warpOptions->panSrcBands = (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount );
+ warpOptions->panSrcBands[0] = 1;
+ warpOptions->panDstBands = (int *) CPLMalloc(sizeof(int) * warpOptions->nBandCount );
+ warpOptions->panDstBands[0] = 1;
// Establish reprojection transformer.
warpOptions->pTransformerArg =
- GDALCreateGenImgProjTransformer( m_GeoidDS.get(),
- GDALGetProjectionRef(m_GeoidDS.get()),
- m_Dataset.get(),
- GDALGetProjectionRef(m_Dataset.get()),
- FALSE, 0.0, 1 );
+ GDALCreateGenImgProjTransformer(
+ m_GeoidDS.get(), GDALGetProjectionRef(m_GeoidDS.get()),
+ m_DEMDS.get(), GDALGetProjectionRef(m_DEMDS.get()),
+ FALSE, 0.0, 1 );
warpOptions->pfnTransformer = GDALGenImgProjTransform;
auto ds = static_cast<GDALDataset *> (GDALCreateWarpedVRT(m_GeoidDS.get(),
- m_Dataset->GetRasterXSize(),
- m_Dataset->GetRasterYSize(),
- geoTransform,
- warpOptions));
+ m_DEMDS->GetRasterXSize(),
+ m_DEMDS->GetRasterYSize(),
+ const_cast<double*>(m_DEMDS.getGeoTransform()), // not const-correct?
+ warpOptions));
- ds->SetDescription(DEM_WARPED_DATASET_PATH.c_str());
+ ds->SetDescription(DEMHandler::DEM_WARPED_DATASET_PATH);
GDALClose(ds);
GDALDriver *poDriver = (GDALDriver *) GDALGetDriverByName( "VRT" );
GDALDataset *poVRTDS;
- poVRTDS = poDriver->Create( DEM_SHIFTED_DATASET_PATH.c_str(), m_Dataset->GetRasterXSize(), m_Dataset->GetRasterYSize(), 0, GDT_Float64, NULL );
+ poVRTDS = poDriver->Create( DEMHandler::DEM_SHIFTED_DATASET_PATH, m_DEMDS->GetRasterXSize(), m_DEMDS->GetRasterYSize(), 0, GDT_Float64, NULL );
- poVRTDS->SetGeoTransform(geoTransform);
+ poVRTDS->SetGeoTransform(const_cast<double*>(m_DEMDS.getGeoTransform()));
- poVRTDS->SetProjection(m_Dataset->GetProjectionRef());
+ poVRTDS->SetProjection(m_DEMDS->GetProjectionRef());
- char** derivedBandOptions = NULL;
+ char** derivedBandOptions = nullptr;
derivedBandOptions = CSLAddNameValue(derivedBandOptions, "subclass", "VRTDerivedRasterBand");
derivedBandOptions = CSLAddNameValue(derivedBandOptions, "PixelFunctionType", "sum");
@@ -356,92 +777,102 @@ void DEMHandler::CreateShiftedDataset()
GDALRasterBand *poBand = poVRTDS->GetRasterBand( 1 );
-// TODO use std string (and boost format ?) or stream
+ // TODO use std string (and boost format ?) or stream
char demVrtXml[10000];
-
- sprintf( demVrtXml,
- "<SimpleSource>"
- " <SourceFilename>%s</SourceFilename>"
- " <SourceBand>1</SourceBand>"
- "</SimpleSource>",
- DEM_DATASET_PATH.c_str());
+ snprintf( demVrtXml, sizeof(demVrtXml),
+ "<SimpleSource>"
+ " <SourceFilename>%s</SourceFilename>"
+ " <SourceBand>1</SourceBand>"
+ "</SimpleSource>",
+ DEMHandler::DEM_DATASET_PATH);
poBand->SetMetadataItem( "source_0", demVrtXml, "new_vrt_sources" );
-
char geoidVrtXml[10000];
-
- sprintf( geoidVrtXml,
- "<SimpleSource>"
- " <SourceFilename>%s</SourceFilename>"
- " <SourceBand>1</SourceBand>"
- "</SimpleSource>",
- DEM_WARPED_DATASET_PATH.c_str());
-
+ snprintf( geoidVrtXml, sizeof(geoidVrtXml),
+ "<SimpleSource>"
+ " <SourceFilename>%s</SourceFilename>"
+ " <SourceBand>1</SourceBand>"
+ "</SimpleSource>",
+ DEMHandler::DEM_WARPED_DATASET_PATH);
poBand->SetMetadataItem( "source_1", geoidVrtXml, "new_vrt_sources" );
GDALClose(poVRTDS);
}
+boost::optional<double> DEMHandlerTLS::GetHeightAboveMSL(double lon, double lat) const
+{
+ if (m_DEMDS)
+ {
+ return DEMDetails::GetDEMValue(lon, lat, m_DEMDS);
+ }
+ return boost::none;
+}
-double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) const
+boost::optional<double> DEMHandlerTLS::GetGeoidHeight(double lon, double lat) const
{
- double result = 0.;
- boost::optional<double> DEMresult;
- boost::optional<double> geoidResult;
+ if (m_GeoidDS)
+ {
+ return DEMDetails::GetDEMValue(lon, lat, m_GeoidDS);
+ }
+ return boost::none;
+}
+
+double DEMHandlerTLS::GetHeightAboveEllipsoid(double lon, double lat, double defaultHeight) const
+{
+ boost::optional<double> DEMresult = GetHeightAboveMSL(lon, lat);
+ boost::optional<double> geoidResult = GetGeoidHeight(lon, lat);
- if (m_Dataset)
+ if (DEMresult || geoidResult)
{
- DEMresult = DEMDetails::GetDEMValue(lon, lat, *m_Dataset);
+ double result = 0.;
if (DEMresult)
{
result += *DEMresult;
}
- }
-
- if (m_GeoidDS)
- {
- geoidResult = DEMDetails::GetDEMValue(lon, lat, *m_GeoidDS);
if (geoidResult)
{
result += *geoidResult;
}
- }
-
- if (DEMresult || geoidResult)
return result;
+ }
else
- return m_DefaultHeightAboveEllipsoid;
+ return defaultHeight;
}
+double DEMHandler::GetHeightAboveEllipsoid(double lon, double lat) const
+{
+ auto & tls = GetHandlerForCurrentThread();
+ return tls.GetHeightAboveEllipsoid(lon, lat, m_DefaultHeightAboveEllipsoid);
+}
double DEMHandler::GetHeightAboveEllipsoid(const PointType& geoPoint) const
{
return GetHeightAboveEllipsoid(geoPoint[0], geoPoint[1]);
}
-double DEMHandler::GetHeightAboveMSL(double lon, double lat) const
+double DEMHandler::GetGeoidHeight(double lon, double lat) const
{
- if (m_Dataset)
- {
- auto result = DEMDetails::GetDEMValue(lon, lat, *m_Dataset);
-
- if (result)
- {
- return *result;
- }
- }
-
- return 0;
+ auto & tls = GetHandlerForCurrentThread();
+ return tls.GetGeoidHeight(lon, lat).value_or(0);
+}
+double DEMHandler::GetGeoidHeight(const PointType& geoPoint) const
+{
+ return GetGeoidHeight(geoPoint[0], geoPoint[1]);
}
+double DEMHandler::GetHeightAboveMSL(double lon, double lat) const
+{
+ auto & tls = GetHandlerForCurrentThread();
+ return tls.GetHeightAboveMSL(lon, lat).value_or(0);
+}
double DEMHandler::GetHeightAboveMSL(const PointType& geoPoint) const
{
return GetHeightAboveMSL(geoPoint[0], geoPoint[1]);
}
-unsigned int DEMHandler::GetDEMCount() const
+std::size_t DEMHandler::GetDEMCount() const noexcept
{
return m_DatasetList.size();
}
@@ -461,41 +892,49 @@ bool DEMHandler::IsValidDEMDirectory(const std::string& DEMDirectory) const
return false;
}
-std::string DEMHandler::GetDEMDirectory(unsigned int idx) const
+std::string const& DEMHandler::GetDEMDirectory(std::size_t idx) const
{
if (idx >= m_DEMDirectories.size())
{
std::ostringstream oss;
- oss << "Requested DEM diectory " << idx
- << ", but only "<< m_DEMDirectories.size() << "have been set.";
+ oss << "Requested DEM directory " << idx
+ << ", but only "<< m_DEMDirectories.size() << " have been set.";
+ // TODO: std::out_of_range is a logic (i.e. a programming) error =>
+ // use another exception type!
throw std::out_of_range (oss.str());
}
-
+
return m_DEMDirectories[idx];
-
}
-std::string DEMHandler::GetGeoidFile() const
+std::string const& DEMHandler::GetGeoidFile() const noexcept
{
return m_GeoidFilename;
}
-void DEMHandler::ClearDEMs()
+void DEMHandlerTLS::ClearElevationParameters()
{
- m_DEMDirectories.clear();
-
- // This will call GDALClose on all datasets
- m_DatasetList.clear();
- Notify();
+ m_GeoidDS.release();
+ m_DEMDS.release();
}
void DEMHandler::ClearElevationParameters()
{
m_DefaultHeightAboveEllipsoid = 0.;
m_GeoidFilename.clear();
- m_GeoidDS.reset(nullptr);
- ClearDEMs(); // ClearDEMs calls Notify()
+ // This will call GDALClose on all datasets
+ m_DatasetList.clear();
+ {
+ const std::lock_guard<std::mutex> lock(demMutex);
+ for (auto tls : m_tlses) {
+ tls->ClearElevationParameters();
+ }
+ m_DEMDirectories.clear();
+ }
+ // TODO: ¿ shouldn't we erase the files as well ?
+
+ Notify();
}
@@ -505,7 +944,7 @@ void DEMHandler::SetDefaultHeightAboveEllipsoid(double height)
Notify();
}
-double DEMHandler::GetDefaultHeightAboveEllipsoid() const
+double DEMHandler::GetDefaultHeightAboveEllipsoid() const noexcept
{
return m_DefaultHeightAboveEllipsoid;
}
@@ -518,4 +957,23 @@ void DEMHandler::Notify() const
}
};
+
+double GetHeightAboveEllipsoid(DEMHandlerTLS const& tls, double lon, double lat)
+{ return tls.GetHeightAboveEllipsoid(lon, lat, DEMHandler::GetInstance().GetDefaultHeightAboveEllipsoid()); }
+
+double GetHeightAboveMSL (DEMHandlerTLS const& tls, double lon, double lat)
+{ return tls.GetHeightAboveMSL(lon, lat).value_or(0); }
+
+double GetGeoidHeight (DEMHandlerTLS const& tls, double lon, double lat)
+{ return tls.GetGeoidHeight(lon, lat).value_or(0); }
+
+double GetHeightAboveEllipsoid(DEMHandlerTLS const& tls, itk::Point<double, 2> geoPoint)
+{ return GetHeightAboveEllipsoid(tls, geoPoint[0], geoPoint[1]); }
+
+double GetHeightAboveMSL (DEMHandlerTLS const& tls, itk::Point<double, 2> geoPoint)
+{ return GetHeightAboveMSL(tls, geoPoint[0], geoPoint[1]); }
+
+double GetGeoidHeight (DEMHandlerTLS const& tls, itk::Point<double, 2> geoPoint)
+{ return GetGeoidHeight(tls, geoPoint[0], geoPoint[1]); }
+
} // namespace otb
=====================================
Modules/IO/IOGDAL/src/otbGDALRPCTransformer.cxx
=====================================
@@ -104,11 +104,11 @@ void GDALRPCTransformer::Update()
{
if (demHandler.GetGeoidFile().empty())
{
- this->SetOption("RPC_DEM", demHandler.DEM_DATASET_PATH);
+ this->SetOption("RPC_DEM", DEMHandler::DEM_DATASET_PATH);
}
else
{
- this->SetOption("RPC_DEM", demHandler.DEM_SHIFTED_DATASET_PATH);
+ this->SetOption("RPC_DEM", DEMHandler::DEM_SHIFTED_DATASET_PATH);
}
this->SetOption("RPC_DEM_MISSING_VALUE", std::to_string(demHandler.GetDefaultHeightAboveEllipsoid()));
}
=====================================
Modules/IO/IOGDAL/test/otbGDALRPCTransformerTest.cxx
=====================================
@@ -32,27 +32,27 @@ int otbGDALRPCTransformerTest(int itkNotUsed(argc), char* argv[])
double LineOffset = 16201.0, SampleOffset = 15184.0,
LatOffset = 39.7792, LonOffset = 125.7510, HeightOffset = 97.0,
LineScale = 16480.0, SampleScale = 15217.0,
- LatScale = 0.0900, LonScale = 0.1096, HeightScale = 501.0;
+ LatScale = 0.0900, LonScale = 0.1096, HeightScale = 501.0;
const double line_num_coeff[20] = {
- +5.105608E-04, -2.921055E-02, -1.010407E+00, -1.743729E-02, -6.604239E-05,
- -7.871396E-05, +3.027877E-04, -4.323587E-04, -2.624751E-04, +6.186490E-06,
- +1.084676E-06, +5.389738E-05, +4.145232E-06, +3.911486E-07, +1.772434E-05,
- +3.302960E-06, +3.006106E-06, +1.662606E-05, +6.051677E-06, -2.657667E-08};
+ +5.105608E-04, -2.921055E-02, -1.010407E+00, -1.743729E-02, -6.604239E-05,
+ -7.871396E-05, +3.027877E-04, -4.323587E-04, -2.624751E-04, +6.186490E-06,
+ +1.084676E-06, +5.389738E-05, +4.145232E-06, +3.911486E-07, +1.772434E-05,
+ +3.302960E-06, +3.006106E-06, +1.662606E-05, +6.051677E-06, -2.657667E-08};
const double line_den_coeff[20] = {
- +1.000000E+00, -9.652128E-05, +2.488346E-04, +3.089019E-04, -2.120170E-06,
- +4.117913E-07, +1.370009E-06, +1.357281E-05, -4.174324E-06, -3.146787E-06,
- -7.724587E-06, +3.524480E-04, -1.303224E-05, -8.507679E-07, -1.670972E-05,
- +6.781061E-06, +5.602262E-07, +1.161421E-05, +4.681872E-06, +5.593931E-08};
+ +1.000000E+00, -9.652128E-05, +2.488346E-04, +3.089019E-04, -2.120170E-06,
+ +4.117913E-07, +1.370009E-06, +1.357281E-05, -4.174324E-06, -3.146787E-06,
+ -7.724587E-06, +3.524480E-04, -1.303224E-05, -8.507679E-07, -1.670972E-05,
+ +6.781061E-06, +5.602262E-07, +1.161421E-05, +4.681872E-06, +5.593931E-08};
const double samp_num_coeff[20] = {
- -2.429563E-04, +1.028320E+00, -3.360972E-02, +3.519600E-03, -6.568341E-04,
- +5.951139E-04, -3.875716E-04, +1.260622E-04, -5.273817E-05, -4.418981E-06,
- -3.520581E-06, -2.502760E-04, -4.167704E-05, -5.973233E-05, -1.438949E-04,
- +7.603041E-06, +2.358136E-06, -2.275274E-05, +1.602657E-06, -1.716541E-07};
+ -2.429563E-04, +1.028320E+00, -3.360972E-02, +3.519600E-03, -6.568341E-04,
+ +5.951139E-04, -3.875716E-04, +1.260622E-04, -5.273817E-05, -4.418981E-06,
+ -3.520581E-06, -2.502760E-04, -4.167704E-05, -5.973233E-05, -1.438949E-04,
+ +7.603041E-06, +2.358136E-06, -2.275274E-05, +1.602657E-06, -1.716541E-07};
const double samp_den_coeff[20] = {
- +1.000000E+00, +7.765620E-05, +6.568707E-04, -6.270621E-04, +5.163170E-05,
- +6.979463E-06, +2.476334E-07, +1.083558E-04, -4.043734E-05, -5.819288E-05,
- +1.778201E-07, +5.665202E-05, +6.927205E-06, +6.793485E-07, +3.604209E-05,
- -4.057103E-07, -8.291254E-07, +1.010650E-05, -2.875552E-06, +5.142751E-08};
+ +1.000000E+00, +7.765620E-05, +6.568707E-04, -6.270621E-04, +5.163170E-05,
+ +6.979463E-06, +2.476334E-07, +1.083558E-04, -4.043734E-05, -5.819288E-05,
+ +1.778201E-07, +5.665202E-05, +6.927205E-06, +6.793485E-07, +3.604209E-05,
+ -4.057103E-07, -8.291254E-07, +1.010650E-05, -2.875552E-06, +5.142751E-08};
otb::GDALRPCTransformer transformer(LineOffset, SampleOffset, LatOffset, LonOffset, HeightOffset,
LineScale, SampleScale, LatScale, LonScale, HeightScale,
@@ -165,7 +165,7 @@ int otbGDALRPCTransformerTest(int itkNotUsed(argc), char* argv[])
zePoint[2] = 0.0;
exp_x = 125.64828521533849;
exp_y = 39.869345204440144;
- transformer.SetOption("RPC_DEM", dem.DEM_DATASET_PATH);
+ transformer.SetOption("RPC_DEM", otb::DEMHandler::DEM_DATASET_PATH);
transformer.SetOption("RPC_HEIGHT_SCALE", "2");
std::cout << "Test ForwardTransform with DEM." << '\n';
=====================================
Modules/Registration/Stereo/include/otbStereorectificationDisplacementFieldSource.hxx
=====================================
@@ -296,6 +296,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
// Setup the DEM handler if needed
auto & demHandler = DEMHandler::GetInstance();
+ auto const& threadDemHandler = demHandler.GetHandlerForCurrentThread();
// Set-up a transform to use the DEMHandler
typedef otb::GenericRSTransform<> RSTransform2DType;
@@ -463,7 +464,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
RSTransform2DType::InputPointType tmpPoint;
tmpPoint[0] = currentPoint1[0];
tmpPoint[1] = currentPoint1[1];
- localElevation = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
+ localElevation = GetHeightAboveEllipsoid(threadDemHandler, leftToGroundTransform->TransformPoint(tmpPoint));
}
currentPoint1[2] = localElevation;
@@ -489,7 +490,7 @@ void StereorectificationDisplacementFieldSource<TInputImage, TOutputImage>::Gene
RSTransform2DType::InputPointType tmpPoint;
tmpPoint[0] = nextLineStart1[0];
tmpPoint[1] = nextLineStart1[1];
- nextLineStart1[2] = demHandler.GetHeightAboveEllipsoid(leftToGroundTransform->TransformPoint(tmpPoint));
+ nextLineStart1[2] = GetHeightAboveEllipsoid(threadDemHandler, leftToGroundTransform->TransformPoint(tmpPoint));
}
=====================================
RELEASE_NOTES.txt
=====================================
@@ -1,3 +1,14 @@
+OTB-v8.1.1 - Changes since version 8.1.0 (Wednesday 13th, 2023)
+
+Bugs fixed:
+ * !933: Improve DEMHandler performances which fixes #2307 Spatial shifting with Orthorectifcation of Sentinel 1 products by Luc Hermitte
+
+Documentation:
+ * !944: Update OTB-Data link in the documentation by Thibaut ROMAIN
+
+CI:
+ * Update ZLIB to 1.2.13 by Thibaut ROMAIN (backport from !902)
+
OTB-v 8.1.0 - Changes since version 8.0.1 (September 14th, 2022)
---------------------------------------------------------------------
=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+otb (8.1.1+dfsg-1) unstable; urgency=medium
+
+ * Team upload.
+ * New upstream release.
+ * Add patch to fix version detection from release notes.
+ * Update symbols for amd64.
+ * Add patch to fix spelling errors.
+
+ -- Bas Couwenberg <sebastic at debian.org> Fri, 13 Jan 2023 16:40:55 +0100
+
otb (8.1.0+dfsg-1) unstable; urgency=medium
* Team upload.
=====================================
debian/libotbiogdal-8.1-1.symbols
=====================================
@@ -1,6 +1,8 @@
-# SymbolsHelper-Confirmed: 8.1.0 amd64
+# SymbolsHelper-Confirmed: 8.1.1 amd64
libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
* Build-Depends-Package: libotb-dev
+ _ZGRZN3otb10DEMDetails12DatasetCache5resetEP11GDALDatasetE8wgs84Srs_ at Base 8.1.1
+ _ZGVZN3otb10DEMDetails12DatasetCache5resetEP11GDALDatasetE8wgs84Srs at Base 8.1.1
_ZGVZN3otb24GDALDriverManagerWrapper11GetInstanceEvE17theUniqueInstance at Base 6.2.0
_ZGVZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE15system_instance at Base 8.0.0
_ZGVZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE16generic_instance at Base 8.0.0
@@ -129,24 +131,20 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
(optional=templinst)_ZN3itk8TreeNodeINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEED1Ev at Base 6.2.0
(optional=templinst)_ZN3itk8TreeNodeINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEED2Ev at Base 6.2.0
(optional=templinst|arch=i386)_ZN3itklsIdLj2EEERSoS1_RKNS_5PointIT_XT0_EEE at Base 6.6.1
- _ZN3otb10DEMDetails11GetDEMValueEddR11GDALDataset at Base 8.0.0
+ _ZN3otb10DEMDetails11GetDEMValueEddRKNS0_12DatasetCacheE at Base 8.1.1
+ _ZN3otb10DEMDetails12DatasetCache9m_DatasetMUlP11GDALDatasetE_4_FUNES3_ at Base 8.1.1
+ _ZN3otb10DEMDetails15HasGeoTransformER11GDALDataset at Base 8.1.1
_ZN3otb10DEMDetails19GetFilesInDirectoryERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
- _ZN3otb10DEMDetails8demMutexE at Base 8.0.0
_ZN3otb10DEMHandler11GetInstanceEv at Base 8.0.0
- _ZN3otb10DEMHandler11OpenDEMFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
- _ZN3otb10DEMHandler13OpenGeoidFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
+ _ZN3otb10DEMHandler11OpenDEMFileENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.1.1
+ _ZN3otb10DEMHandler13OpenGeoidFileENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.1.1
_ZN3otb10DEMHandler14AttachObserverEPNS_20DEMObserverInterfaceE at Base 8.0.0
_ZN3otb10DEMHandler14DetachObserverEPNS_20DEMObserverInterfaceE at Base 8.0.0
- _ZN3otb10DEMHandler16OpenDEMDirectoryERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
- _ZN3otb10DEMHandler20CreateShiftedDatasetEv at Base 8.0.0
+ _ZN3otb10DEMHandler16OpenDEMDirectoryENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.1.1
_ZN3otb10DEMHandler24ClearElevationParametersEv at Base 8.0.0
_ZN3otb10DEMHandler30SetDefaultHeightAboveEllipsoidEd at Base 8.0.0
- _ZN3otb10DEMHandler9ClearDEMsEv at Base 8.0.0
- _ZN3otb10DEMHandler9m_DatasetMUlP11GDALDatasetE_4_FUNES2_ at Base 8.0.0
- _ZN3otb10DEMHandler9m_GeoidDSMUlP11GDALDatasetE_4_FUNES2_ at Base 8.0.0
_ZN3otb10DEMHandlerC1Ev at Base 8.0.0
_ZN3otb10DEMHandlerC2Ev at Base 8.0.0
- _ZN3otb10DEMHandlerD0Ev at Base 8.0.0
_ZN3otb10DEMHandlerD1Ev at Base 8.0.0
_ZN3otb10DEMHandlerD2Ev at Base 8.0.0
(optional=templinst)_ZN3otb10ObjectListINS_7PolygonIdEEE8PushBackEPS2_ at Base 6.2.0
@@ -221,6 +219,14 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZN3otb11OGRIOHelperD0Ev at Base 5.2.0
_ZN3otb11OGRIOHelperD1Ev at Base 5.2.0
_ZN3otb11OGRIOHelperD2Ev at Base 5.2.0
+ _ZN3otb13DEMHandlerTLS13OpenGeoidFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.1.1
+ _ZN3otb13DEMHandlerTLS14OpenDEMVRTFileEv at Base 8.1.1
+ _ZN3otb13DEMHandlerTLS15CloseDEMVRTFileEv at Base 8.1.1
+ _ZN3otb13DEMHandlerTLS24ClearElevationParametersEv at Base 8.1.1
+ _ZN3otb13DEMHandlerTLSD1Ev at Base 8.1.1
+ _ZN3otb13DEMHandlerTLSD2Ev at Base 8.1.1
+ _ZN3otb14GetGeoidHeightERKNS_13DEMHandlerTLSEN3itk5PointIdLj2EEE at Base 8.1.1
+ _ZN3otb14GetGeoidHeightERKNS_13DEMHandlerTLSEdd at Base 8.1.1
_ZN3otb15GetConfigOptionB5cxx11EPKc at Base 6.2.0
_ZN3otb15OGRVectorDataIO23CloseInternalDataSourceEv at Base 5.2.0
_ZN3otb15OGRVectorDataIO4ReadEPN3itk10DataObjectE at Base 5.2.0
@@ -233,6 +239,8 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZN3otb16VectorDataIOBase11SetFileNameEPKc at Base 6.2.0
_ZN3otb16VectorDataIOBase11SetFileNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 6.2.0
_ZN3otb16VectorDataIOBase12SetByteOrderENS0_9ByteOrderE at Base 6.2.0
+ _ZN3otb17GetHeightAboveMSLERKNS_13DEMHandlerTLSEN3itk5PointIdLj2EEE at Base 8.1.1
+ _ZN3otb17GetHeightAboveMSLERKNS_13DEMHandlerTLSEdd at Base 8.1.1
_ZN3otb17ImageMetadataBaseC1ERKS0_ at Base 8.0.0
_ZN3otb17ImageMetadataBaseC2ERKS0_ at Base 8.0.0
_ZN3otb17ImageMetadataBaseD1Ev at Base 8.0.0
@@ -260,9 +268,9 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZN3otb18GDALRPCTransformerC1EddddddddddRA20_KdS3_S3_S3_b at Base 8.0.0
_ZN3otb18GDALRPCTransformerC2ERKNS_10Projection8RPCParamEb at Base 8.0.0
_ZN3otb18GDALRPCTransformerC2EddddddddddRA20_KdS3_S3_S3_b at Base 8.0.0
- _ZN3otb18GDALRPCTransformerD0Ev at Base 8.0.0
_ZN3otb18GDALRPCTransformerD1Ev at Base 8.0.0
_ZN3otb18GDALRPCTransformerD2Ev at Base 8.0.0
+ _ZN3otb18HasInputProjectionERK11GDALDataset at Base 8.1.1
(optional=templinst)_ZN3otb19RemoteSensingRegionIdED0Ev at Base 6.2.0
(optional=templinst)_ZN3otb19RemoteSensingRegionIdED1Ev at Base 6.2.0
(optional=templinst)_ZN3otb19RemoteSensingRegionIdED2Ev at Base 6.2.0
@@ -288,6 +296,8 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZN3otb22OGRVectorDataIOFactoryD0Ev at Base 5.2.0
_ZN3otb22OGRVectorDataIOFactoryD1Ev at Base 5.2.0
_ZN3otb22OGRVectorDataIOFactoryD2Ev at Base 5.2.0
+ _ZN3otb23GetHeightAboveEllipsoidERKNS_13DEMHandlerTLSEN3itk5PointIdLj2EEE at Base 8.1.1
+ _ZN3otb23GetHeightAboveEllipsoidERKNS_13DEMHandlerTLSEdd at Base 8.1.1
_ZN3otb24GDALDriverManagerWrapper11GetInstanceEv at Base 6.2.0
_ZN3otb24GDALDriverManagerWrapperC1Ev at Base 6.2.0
_ZN3otb24GDALDriverManagerWrapperC2Ev at Base 6.2.0
@@ -486,13 +496,18 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
(optional=templinst)_ZNK3itk8TreeNodeINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEE14GetNameOfClassEv at Base 6.2.0
_ZNK3otb10DEMHandler11GetDEMCountEv at Base 8.0.0
_ZNK3otb10DEMHandler12GetGeoidFileB5cxx11Ev at Base 8.0.0
+ _ZNK3otb10DEMHandler14GetGeoidHeightERKN3itk5PointIdLj2EEE at Base 8.1.1
+ _ZNK3otb10DEMHandler14GetGeoidHeightEdd at Base 8.1.1
_ZNK3otb10DEMHandler15GetDEMDirectoryB5cxx11Ej at Base 8.0.0
_ZNK3otb10DEMHandler17GetHeightAboveMSLERKN3itk5PointIdLj2EEE at Base 8.0.0
_ZNK3otb10DEMHandler17GetHeightAboveMSLEdd at Base 8.0.0
_ZNK3otb10DEMHandler19IsValidDEMDirectoryERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
+ _ZNK3otb10DEMHandler22DoFetchOrCreateHandlerEv at Base 8.1.1
_ZNK3otb10DEMHandler23GetHeightAboveEllipsoidERKN3itk5PointIdLj2EEE at Base 8.0.0
_ZNK3otb10DEMHandler23GetHeightAboveEllipsoidEdd at Base 8.0.0
+ _ZNK3otb10DEMHandler26GetHandlerForCurrentThreadEv at Base 8.1.1
_ZNK3otb10DEMHandler30GetDefaultHeightAboveEllipsoidEv at Base 8.0.0
+ _ZNK3otb10DEMHandler30RegisterConfigurationInHandlerERNS_13DEMHandlerTLSE at Base 8.1.1
_ZNK3otb10DEMHandler6NotifyEv at Base 8.0.0
(optional=templinst)_ZNK3otb10ObjectListINS_7PolygonIdEEE13CreateAnotherEv at Base 6.2.0
(optional=templinst|arch=amd64)_ZNK3otb10ObjectListINS_7PolygonIdEEE13GetNthElementEj at Base 6.6.1
@@ -537,6 +552,10 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZNK3otb11OGRIOHelper26ConvertGeometryToPointNodeEPK11OGRGeometryN3itk12SmartPointerINS_8DataNodeIdLj2EdEEEE at Base 5.2.0
_ZNK3otb11OGRIOHelper28ConvertGeometryToPolygonNodeEPK11OGRGeometryN3itk12SmartPointerINS_8DataNodeIdLj2EdEEEE at Base 6.2.0
_ZNK3otb11OGRIOHelper29ConvertOGRLayerToDataTreeNodeEP8OGRLayerPN3itk8TreeNodeINS3_12SmartPointerINS_8DataNodeIdLj2EdEEEEEE at Base 5.2.0
+ _ZNK3otb13DEMHandlerTLS14GetGeoidHeightEdd at Base 8.1.1
+ _ZNK3otb13DEMHandlerTLS17GetHeightAboveMSLEdd at Base 8.1.1
+ _ZNK3otb13DEMHandlerTLS23GetHeightAboveEllipsoidEddd at Base 8.1.1
+ _ZNK3otb13DEMHandlerTLS24CreateShiftedDatasetOnceEv at Base 8.1.1
_ZNK3otb15OGRVectorDataIO11CanReadFileEPKc at Base 5.2.0
_ZNK3otb15OGRVectorDataIO12CanWriteFileEPKc at Base 5.2.0
_ZNK3otb15OGRVectorDataIO13CreateAnotherEv at Base 6.2.0
@@ -657,9 +676,20 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
(optional=templinst|subst)_ZNSt10_HashtableINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESaIS8_ENSt8__detail10_Select1stESt8equal_toIS5_ESt4hashIS5_ENSA_18_Mod_range_hashingENSA_20_Default_ranged_hashENSA_20_Prime_rehash_policyENSA_17_Hashtable_traitsILb1ELb0ELb1EEEE9_M_rehashE{size_t}RK{size_t}@Base 8.0.0
(optional=templinst)_ZNSt10_HashtableINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESaIS8_ENSt8__detail10_Select1stESt8equal_toIS5_ESt4hashIS5_ENSA_18_Mod_range_hashingENSA_20_Default_ranged_hashENSA_20_Prime_rehash_policyENSA_17_Hashtable_traitsILb1ELb0ELb1EEEED1Ev at Base 8.0.0
(optional=templinst)_ZNSt10_HashtableINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESaIS8_ENSt8__detail10_Select1stESt8equal_toIS5_ESt4hashIS5_ENSA_18_Mod_range_hashingENSA_20_Default_ranged_hashENSA_20_Prime_rehash_policyENSA_17_Hashtable_traitsILb1ELb0ELb1EEEED2Ev at Base 8.0.0
+ (optional=templinst)_ZNSt10shared_ptrIN3otb13DEMHandlerTLSEED1Ev at Base 8.1.1
+ (optional=templinst)_ZNSt10shared_ptrIN3otb13DEMHandlerTLSEED2Ev at Base 8.1.1
+ (optional=templinst)_ZNSt11unique_lockISt5mutexE6unlockEv at Base 8.1.1
(optional=templinst)_ZNSt12_Destroy_auxILb0EE9__destroyIPN3otb26CoordinateConversionRecordEEEvT_S5_ at Base 8.0.0
(optional=templinst)_ZNSt12_Destroy_auxILb0EE9__destroyIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvT_S9_ at Base 7.2.0~rc2
(optional=templinst)_ZNSt13_Bvector_baseISaIbEE13_M_deallocateEv at Base 5.2.0
+ (optional=templinst)_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEv at Base 8.1.1
+ (optional=templinst)_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE24_M_release_last_use_coldEv at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE14_M_get_deleterERKSt9type_info at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EED0Ev at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EED1Ev at Base 8.1.1
+ (optional=templinst)_ZNSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EED2Ev at Base 8.1.1
(optional=templinst)_ZNSt3mapIN3otb5MDNumEdSt4lessIS1_ESaISt4pairIKS1_dEEEixEOS1_ at Base 8.0.0
(optional=templinst)_ZNSt3mapIPKN5boost6system14error_categoryESt10unique_ptrINS1_6detail12std_categoryESt14default_deleteIS7_EENS6_12cat_ptr_lessESaISt4pairIKS4_SA_EEED1Ev at Base 8.0.0
(optional=templinst)_ZNSt3mapIPKN5boost6system14error_categoryESt10unique_ptrINS1_6detail12std_categoryESt14default_deleteIS7_EENS6_12cat_ptr_lessESaISt4pairIKS4_SA_EEED2Ev at Base 8.0.0
@@ -689,10 +719,14 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
(optional=templinst|arch=amd64 i386)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12emplace_backIJS5_EEEvDpOT_ at Base 8.0.0
(optional=templinst)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJRKS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ at Base 6.2.0
(optional=templinst)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJRPcEEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ at Base 7.0.0
+ (optional=templinst)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_insertIJS5_EEEvN9__gnu_cxx17__normal_iteratorIPS5_S7_EEDpOT_ at Base 8.1.1
(optional=templinst)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED1Ev at Base 5.2.0
(optional=templinst)_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED2Ev at Base 5.2.0
(optional=templinst)_ZNSt6vectorIP8OGRLayerSaIS1_EE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S3_EEDpOT_ at Base 6.2.0
(optional=templinst)_ZNSt6vectorIPKcSaIS1_EE17_M_realloc_insertIJS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S3_EEDpOT_ at Base 6.6.0
+ (optional=templinst)_ZNSt6vectorISt10shared_ptrIN3otb13DEMHandlerTLSEESaIS3_EE17_M_realloc_insertIJS3_EEEvN9__gnu_cxx17__normal_iteratorIPS3_S5_EEDpOT_ at Base 8.1.1
+ (optional=templinst)_ZNSt6vectorISt10shared_ptrIN3otb13DEMHandlerTLSEESaIS3_EED1Ev at Base 8.1.1
+ (optional=templinst)_ZNSt6vectorISt10shared_ptrIN3otb13DEMHandlerTLSEESaIS3_EED2Ev at Base 8.1.1
(optional=templinst)_ZNSt6vectorISt4pairIjjESaIS1_EE17_M_realloc_insertIJRKS1_EEEvN9__gnu_cxx17__normal_iteratorIPS1_S3_EEDpOT_ at Base 6.2.0
(optional=templinst)_ZNSt6vectorIdSaIdEE17_M_realloc_insertIJRKdEEEvN9__gnu_cxx17__normal_iteratorIPdS1_EEDpOT_ at Base 6.2.0
(optional=templinst)_ZNSt6vectorIdSaIdEE17_M_realloc_insertIJdEEEvN9__gnu_cxx17__normal_iteratorIPdS1_EEDpOT_ at Base 7.2.0
@@ -781,7 +815,10 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZTIN5boost6system6detail22generic_error_categoryE at Base 8.0.0
_ZTIN5boost9exceptionE at Base 8.0.0
_ZTINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
+ _ZTISt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
_ZTISt12_Vector_baseIN3itk15ContinuousIndexIdLj2EEESaIS2_EE at Base 6.2.0
+ _ZTISt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
+ _ZTISt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
_ZTISt6vectorIN3itk15ContinuousIndexIdLj2EEESaIS2_EE at Base 6.2.0
_ZTSN3itk12TreeAddEventINS_13TreeContainerINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEEEEE at Base 6.2.0
_ZTSN3itk13TreeContainerINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEEE at Base 6.2.0
@@ -855,7 +892,11 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZTSNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE at Base 8.0.0
_ZTSPKN3itk10DataObjectE at Base 8.0.0
_ZTSPN3itk8PointSetIdLj2ENS_23DefaultStaticMeshTraitsIdLj2ELj2EffdEEEE at Base 8.0.0
+ _ZTSSt11_Mutex_baseILN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
_ZTSSt12_Vector_baseIN3itk15ContinuousIndexIdLj2EEESaIS2_EE at Base 6.2.0
+ _ZTSSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
+ _ZTSSt19_Sp_make_shared_tag at Base 8.1.1
+ _ZTSSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
_ZTSSt6vectorIN3itk15ContinuousIndexIdLj2EEESaIS2_EE at Base 6.2.0
_ZTVN3itk12TreeAddEventINS_13TreeContainerINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEEEEE at Base 6.2.0
_ZTVN3itk13TreeContainerINS_12SmartPointerIN3otb8DataNodeIdLj2EdEEEEEE at Base 6.2.0
@@ -910,12 +951,15 @@ libOTBIOGDAL-8.1.so.1 #PACKAGE# #MINVER#
_ZTVN5boost6system6detail21system_error_categoryE at Base 8.0.0
_ZTVN5boost6system6detail22generic_error_categoryE at Base 8.0.0
_ZTVN5boost9exceptionE at Base 8.0.0
+ _ZTVSt23_Sp_counted_ptr_inplaceIN3otb13DEMHandlerTLSESaIvELN9__gnu_cxx12_Lock_policyE2EE at Base 8.1.1
+ _ZZN3otb10DEMDetails12DatasetCache5resetEP11GDALDatasetE8wgs84Srs at Base 8.1.1
_ZZN3otb24GDALDriverManagerWrapper11GetInstanceEvE17theUniqueInstance at Base 6.2.0
_ZZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE15system_instance at Base 8.0.0
_ZZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE16generic_instance at Base 8.0.0
_ZZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE4map_ at Base 8.0.0
_ZZN5boost6system6detail15to_std_categoryERKNS0_14error_categoryEE7map_mx_ at Base 8.0.0
_ZZN5boost6system6detail16is_generic_valueEiE3gen at Base 8.0.0
+ _ZZNSt19_Sp_make_shared_tag5_S_tiEvE5__tag at Base 8.1.1
(c++)"non-virtual thunk to boost::wrapexcept<boost::bad_any_cast>::~wrapexcept()@Base" 8.0.0
(c++)"non-virtual thunk to boost::wrapexcept<boost::bad_lexical_cast>::~wrapexcept()@Base" 8.0.0
(c++)"non-virtual thunk to boost::wrapexcept<std::out_of_range>::~wrapexcept()@Base" 8.0.0
=====================================
debian/patches/release-notes-version.patch
=====================================
@@ -0,0 +1,13 @@
+Description: Fix version detection from release notes.
+Author: Bas Couwenberg <sebastic at debian.org>
+Forwarded: https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/issues/2324#note_104067
+
+--- a/RELEASE_NOTES.txt
++++ b/RELEASE_NOTES.txt
+@@ -1,4 +1,5 @@
+-OTB-v8.1.1 - Changes since version 8.1.0 (Wednesday 13th, 2023)
++OTB-v 8.1.1 - Changes since version 8.1.0 (Wednesday 13th, 2023)
++---------------------------------------------------------------------
+
+ Bugs fixed:
+ * !933: Improve DEMHandler performances which fixes #2307 Spatial shifting with Orthorectifcation of Sentinel 1 products by Luc Hermitte
=====================================
debian/patches/series
=====================================
@@ -0,0 +1,2 @@
+release-notes-version.patch
+spelling-errors.patch
=====================================
debian/patches/spelling-errors.patch
=====================================
@@ -0,0 +1,16 @@
+Description: Fix spelling errors.
+ * occured -> occurred
+Author: Bas Couwenberg <sebastic at debian.org>
+Forwarded: https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/issues/2324#note_104067
+
+--- a/Modules/IO/IOGDAL/src/otbDEMHandler.cxx
++++ b/Modules/IO/IOGDAL/src/otbDEMHandler.cxx
+@@ -426,7 +426,7 @@ void DEMHandler::RegisterConfigurationIn
+ if (! m_DatasetList.empty()) {
+ if (! tls.OpenDEMVRTFile())
+ {
+- otbLogMacro(Warning, << "An unexpected situation has occured: trying to open a VRT created from incompatible DEM files");
++ otbLogMacro(Warning, << "An unexpected situation has occurred: trying to open a VRT created from incompatible DEM files");
+ assert(false);
+ // The following should not be necessary. In the impossible case
+ // the VRT file could not be opened, we just clear everything in
View it on GitLab: https://salsa.debian.org/debian-gis-team/otb/-/compare/f85376773db515ed9c3b296184e1e7be9e6c7a2d...317ac65b3790673a0e125f22bb43b7295902971c
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/otb/-/compare/f85376773db515ed9c3b296184e1e7be9e6c7a2d...317ac65b3790673a0e125f22bb43b7295902971c
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20230113/0640aeed/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list