diff --git a/source/data_model/gdal/include/configure.hpp.in b/source/data_model/gdal/include/configure.hpp.in index 6f70f09be..9589a2ac1 100644 --- a/source/data_model/gdal/include/configure.hpp.in +++ b/source/data_model/gdal/include/configure.hpp.in @@ -1 +1,16 @@ #pragma once +#include + + +#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#define LUE_GDAL_SUPPORTS_64BIT_INTEGERS 1 +#else +#define LUE_GDAL_SUPPORTS_64BIT_INTEGERS 0 +#endif + + +namespace lue::gdal { + + static constexpr bool supports_64bit_integers{LUE_GDAL_SUPPORTS_64BIT_INTEGERS}; + +} // namespace lue::gdal diff --git a/source/data_model/gdal/include/lue/gdal.hpp b/source/data_model/gdal/include/lue/gdal.hpp index 4483b3f39..ea74bbfa4 100644 --- a/source/data_model/gdal/include/lue/gdal.hpp +++ b/source/data_model/gdal/include/lue/gdal.hpp @@ -1,4 +1,5 @@ #pragma once +#include "lue/gdal/configure.hpp" #include "lue/gdal/dataset.hpp" #include "lue/gdal/driver.hpp" #include "lue/gdal/raster.hpp" diff --git a/source/data_model/gdal/include/lue/gdal/raster.hpp b/source/data_model/gdal/include/lue/gdal/raster.hpp index e685e6324..a58ec0f55 100644 --- a/source/data_model/gdal/include/lue/gdal/raster.hpp +++ b/source/data_model/gdal/include/lue/gdal/raster.hpp @@ -30,6 +30,12 @@ namespace lue::gdal { [[nodiscard]] auto data_type() const -> GDALDataType; + template + [[nodiscard]] auto no_data_value() const -> std::tuple + { + return gdal::no_data_value(*_band); + } + [[nodiscard]] auto blocks() const -> Blocks; auto read_block(Offset const& block_offset, void* buffer) const -> void; diff --git a/source/data_model/gdal/include/lue/gdal/raster_band.hpp b/source/data_model/gdal/include/lue/gdal/raster_band.hpp index 44832e083..e45a3580f 100644 --- a/source/data_model/gdal/include/lue/gdal/raster_band.hpp +++ b/source/data_model/gdal/include/lue/gdal/raster_band.hpp @@ -29,7 +29,7 @@ namespace lue::gdal { } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS // "An explicit specialization of a function template is inline only if it is declared // with the inline specifier (or defined as deleted), it doesn't matter if the primary // template is inline." @@ -56,7 +56,7 @@ namespace lue::gdal { } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS // "An explicit specialization of a function template is inline only if it is declared // with the inline specifier (or defined as deleted), it doesn't matter if the primary // template is inline." diff --git a/source/data_model/gdal/include/lue/gdal/type_traits.hpp b/source/data_model/gdal/include/lue/gdal/type_traits.hpp index 0d50558db..8fdfad428 100644 --- a/source/data_model/gdal/include/lue/gdal/type_traits.hpp +++ b/source/data_model/gdal/include/lue/gdal/type_traits.hpp @@ -67,7 +67,7 @@ namespace lue::gdal { }; -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS template<> class TypeTraits { diff --git a/source/data_model/gdal/src/dataset.cpp b/source/data_model/gdal/src/dataset.cpp index 45fe882cd..387b43ccb 100644 --- a/source/data_model/gdal/src/dataset.cpp +++ b/source/data_model/gdal/src/dataset.cpp @@ -147,7 +147,20 @@ namespace lue::gdal { if (band_ptr == nullptr) { - throw std::runtime_error(fmt::format("Band {} cannot be obtained", band_nr)); + Count const nr_bands{nr_raster_bands(dataset)}; + + if (band_nr < 0 || band_nr > nr_bands) + { + throw std::runtime_error(fmt::format( + "Requested raster band ({}) is outside the valid range ([{} - {}]", + band_nr, + 1, + nr_bands)); + } + else + { + throw std::runtime_error(fmt::format("Band {} cannot be obtained", band_nr)); + } } return band_ptr; diff --git a/source/data_model/gdal/src/driver.cpp b/source/data_model/gdal/src/driver.cpp index 862a85570..2a4f5b749 100644 --- a/source/data_model/gdal/src/driver.cpp +++ b/source/data_model/gdal/src/driver.cpp @@ -1,4 +1,5 @@ #include "lue/gdal/driver.hpp" +#include namespace lue::gdal { diff --git a/source/data_model/gdal/src/raster.cpp b/source/data_model/gdal/src/raster.cpp index 65be02fe8..9afdb85c3 100644 --- a/source/data_model/gdal/src/raster.cpp +++ b/source/data_model/gdal/src/raster.cpp @@ -1,5 +1,6 @@ #include "lue/gdal/raster.hpp" #include +#include namespace lue::gdal { @@ -211,9 +212,6 @@ namespace lue::gdal { auto Raster::band(Count const band_nr) const -> Band { - assert(band_nr > 0); - assert(band_nr <= nr_bands()); - return Raster::Band{raster_band(*_dataset_ptr, band_nr)}; } diff --git a/source/data_model/translate/include/lue/translate/format/gdal_stack.hpp b/source/data_model/translate/include/lue/translate/format/gdal_stack.hpp index 91b7c57c2..788774eee 100644 --- a/source/data_model/translate/include/lue/translate/format/gdal_stack.hpp +++ b/source/data_model/translate/include/lue/translate/format/gdal_stack.hpp @@ -1,6 +1,6 @@ #pragma once +#include "lue/gdal.hpp" #include "lue/hl/raster_stack.hpp" -#include "lue/translate/format/gdal_raster.hpp" #include "lue/utility/progress_indicator.hpp" #include @@ -8,7 +8,7 @@ namespace lue { namespace utility { - GDALDatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name); + gdal::DatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name); class GDALStack { diff --git a/source/data_model/translate/src/format/gdal.cpp b/source/data_model/translate/src/format/gdal.cpp index 18ce7412b..350e08839 100644 --- a/source/data_model/translate/src/format/gdal.cpp +++ b/source/data_model/translate/src/format/gdal.cpp @@ -36,7 +36,7 @@ namespace lue::utility { result = hdf5::native_datatype(); break; } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS case GDT_UInt64: { result = hdf5::native_datatype(); @@ -92,7 +92,7 @@ namespace lue::utility { { result = gdal::data_type_v; } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS else if (data_type == hdf5::native_uint64) { result = gdal::data_type_v; @@ -734,7 +734,7 @@ namespace lue::utility { gdal_to_lue(gdal_raster_band, lue_raster_layer); break; } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS case GDT_UInt64: { gdal_to_lue(gdal_raster_band, lue_raster_layer); diff --git a/source/data_model/translate/src/format/gdal_stack.cpp b/source/data_model/translate/src/format/gdal_stack.cpp index 3a0534ad4..980a1a9c7 100644 --- a/source/data_model/translate/src/format/gdal_stack.cpp +++ b/source/data_model/translate/src/format/gdal_stack.cpp @@ -16,7 +16,7 @@ namespace lue { namespace underscore { - GDALDatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name) + gdal::DatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name) { // What makes a raster a stack: // - dataset_name matches one of the folowing patterns: @@ -30,7 +30,7 @@ namespace lue { auto const dataset_path = std::filesystem::path{dataset_name}; auto const directory_path = dataset_path.parent_path(); - GDALDatasetPtr result; + gdal::DatasetPtr result; auto stack_rule = utility::stack_rule(dataset_name); // This only works with Boost >= 1.62.0 @@ -108,7 +108,7 @@ namespace lue { } - GDALDatasetPtr open_slice_for_read( + gdal::DatasetPtr open_slice_for_read( std::string const& dataset_name, GDALStack::SliceIndex const slice_idx) { return open_gdal_raster_dataset_for_read(slice_dataset_name(dataset_name, slice_idx)); @@ -117,12 +117,12 @@ namespace lue { } // namespace underscore - GDALDatasetPtr open_slice_for_read( + gdal::DatasetPtr open_slice_for_read( GDALStack::NamingConvention const naming_convention, std::string const& dataset_name, GDALStack::SliceIndex const slice_idx) { - GDALDatasetPtr result; + gdal::DatasetPtr result; switch (naming_convention) { @@ -144,7 +144,7 @@ namespace lue { @return A pointer to a ::GDALDataset instance if the dataset can be opened. Otherwise a pointer containing nullptr. */ - GDALDatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name) + gdal::DatasetPtr try_open_gdal_raster_stack_dataset_for_read(std::string const& dataset_name) { auto result = underscore::try_open_gdal_raster_stack_dataset_for_read(dataset_name); @@ -365,7 +365,7 @@ namespace lue { write(raster_stack_band, progress_indicator); break; } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS case GDT_UInt64: { write(raster_stack_band, progress_indicator); @@ -408,7 +408,7 @@ namespace lue { { // Open the stack and read the domain and discretization information - GDALDatasetPtr raster_dataset; + gdal::DatasetPtr raster_dataset; switch (_naming_convention) { diff --git a/source/data_model/translate/src/translate.cpp b/source/data_model/translate/src/translate.cpp index ba398214a..138c5f8c6 100644 --- a/source/data_model/translate/src/translate.cpp +++ b/source/data_model/translate/src/translate.cpp @@ -1,7 +1,7 @@ #include "lue/translate/translate.hpp" +#include "lue/gdal.hpp" #include "lue/translate/command.hpp" #include -#include #include @@ -87,7 +87,7 @@ namespace lue { // lots of messages we usually don't care about. H5Eset_auto(H5E_DEFAULT, nullptr, nullptr); - GDALAllRegister(); + gdal::register_gdal_drivers(); } diff --git a/source/framework/io/src/raster.cpp b/source/framework/io/src/raster.cpp index 4ddf13e13..ba84f1901 100644 --- a/source/framework/io/src/raster.cpp +++ b/source/framework/io/src/raster.cpp @@ -427,14 +427,13 @@ namespace lue { Element no_data_value; { - gdal::DatasetPtr dataset_ptr{gdal::open_dataset(name, ::GA_ReadOnly)}; - - array_shape[0] = dataset_ptr->GetRasterYSize(); - array_shape[1] = dataset_ptr->GetRasterXSize(); - - gdal::RasterBandPtr band_ptr{gdal::raster_band(*dataset_ptr)}; + gdal::Raster raster{gdal::open_dataset(name, ::GA_ReadOnly)}; + gdal::Raster::Band raster_band{raster.band(1)}; - std::tie(no_data_value, no_data_value_is_valid) = lue::no_data_value(*band_ptr); + auto const raster_shape = raster.shape(); + array_shape[0] = static_cast(raster_shape[0]); + array_shape[1] = static_cast(raster_shape[1]); + std::tie(no_data_value, no_data_value_is_valid) = raster_band.no_data_value(); } using Functor = ReadPartitionsPerLocality; @@ -595,7 +594,7 @@ namespace lue { INSTANTIATE(uint8_t) INSTANTIATE(uint32_t) INSTANTIATE(int32_t) -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS INSTANTIATE(uint64_t) INSTANTIATE(int64_t) #endif diff --git a/source/framework/python/src/gdal/from_gdal.cpp b/source/framework/python/src/gdal/from_gdal.cpp index 56378cc5e..1a564750b 100644 --- a/source/framework/python/src/gdal/from_gdal.cpp +++ b/source/framework/python/src/gdal/from_gdal.cpp @@ -61,7 +61,7 @@ namespace lue::framework { { result = from_gdal(name, static_partition_shape); } -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) +#if LUE_GDAL_SUPPORTS_64BIT_INTEGERS else if (data_type == GDT_UInt64) { result = from_gdal(name, static_partition_shape); diff --git a/source/framework/python/src/gdal/to_gdal.cpp b/source/framework/python/src/gdal/to_gdal.cpp index c7db401c4..8585e1901 100644 --- a/source/framework/python/src/gdal/to_gdal.cpp +++ b/source/framework/python/src/gdal/to_gdal.cpp @@ -1,6 +1,6 @@ #include "lue/framework/io/raster.hpp" +#include "lue/gdal.hpp" #include -#include using namespace pybind11::literals; @@ -13,10 +13,11 @@ namespace lue::framework { module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); -#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3, 5, 0) - module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); - module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); -#endif + if constexpr (gdal::supports_64bit_integers) + { + module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); + module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); + } module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); module.def("to_gdal", write, "array"_a, "name"_a, "clone_name"_a = ""); }