From f312b81c8ac429e21b0fdde8254f5583d6faaf33 Mon Sep 17 00:00:00 2001 From: Julien Osman <julien.osman@c-s.fr> Date: Mon, 20 Apr 2020 17:31:30 +0200 Subject: [PATCH] REFAC: LUT1D and LUT2D can now serialize. ToKeywordlist updated to use serialized LUT. Fixed typo Axes to Axis --- .../OTB/Files/ioTvcoreImageMetadataTest.txt | 9 +- .../Core/Metadata/include/otbMetaDataKey.h | 9 +- .../Core/Metadata/src/otbImageMetadata.cxx | 14 +-- Modules/Core/Metadata/src/otbMetaDataKey.cxx | 87 ++++++++++++++++++- .../Metadata/test/otbImageMetadataTest.cxx | 6 +- 5 files changed, 109 insertions(+), 16 deletions(-) diff --git a/Data/Baseline/OTB/Files/ioTvcoreImageMetadataTest.txt b/Data/Baseline/OTB/Files/ioTvcoreImageMetadataTest.txt index e049285504..ce22958d22 100644 --- a/Data/Baseline/OTB/Files/ioTvcoreImageMetadataTest.txt +++ b/Data/Baseline/OTB/Files/ioTvcoreImageMetadataTest.txt @@ -36,10 +36,13 @@ md3_append: {{"Extra.Comment": "Test Extrakeys", "ProjectionEPSG": "4326", "ProjectionWKT": "UTM projRef", "ProjectionProj": "+proj=longlat +datum=WGS84 +no_defs ", -"SpectralSensitivity": "{"Axes": [{"Size": "3", "Origin": "0", "Spacing": "1", "Values": []}, ], "Array": [1, 2, 3, ]}", -"RPC": "{"LineOffset": "0", "SampleOffset": "0", "LatOffset": "0", "LonOffset": "0", "HeightOffset": "0", "LineScale": "0", "SampleScale": "0", "LatScale": "0", "LonScale": "0", "HeightScale": "0", "LineNum": [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", ], "LineDen": [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", ], "SampleNum": [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", ], "SampleDen": [ "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", ], }", +"SpectralSensitivity": "LUT1D.DIM0.SIZE = 3 +LUT1D.DIM0.ORIGIN = 0 +LUT1D.DIM0.SPACING = 1 +LUT1D.ARRAY = 1 2 3 " +"RPC": "<RPCParam>", "ProductionDate": "2009-08-10T10:30:08.142149Z", -"GCP": "{"Projection": "", [{"GCP_Id": "", "GCP_Info": "", "GCP_Row": "0", "GCP_Col": "0", "GCP_X": "0", "GCP_Y": "0", "GCP_Z": "0", }, ]}", +"GCP": "<GCPParam>", "SensorID": "PHR", }Bands[{"PhysicalBias": "1", "BandName": "B3", diff --git a/Modules/Core/Metadata/include/otbMetaDataKey.h b/Modules/Core/Metadata/include/otbMetaDataKey.h index 4c612da182..8bb71f79e7 100644 --- a/Modules/Core/Metadata/include/otbMetaDataKey.h +++ b/Modules/Core/Metadata/include/otbMetaDataKey.h @@ -26,6 +26,7 @@ #include <cstdio> #include <boost/bimap.hpp> +#include <boost/algorithm/string.hpp> #include "itkDataObject.h" #include "itkVariableLengthVector.h" @@ -242,11 +243,15 @@ struct LUTAxis template <unsigned int VDim> class LUT { public: - LUTAxis Axes[VDim]; + LUTAxis Axis[VDim]; std::vector<double> Array; - std::string ToJSON(bool multiline=false) const; + std::string OTBMetadata_EXPORT ToJSON(bool multiline=false) const; + + std::string OTBMetadata_EXPORT ToString() const; + + void OTBMetadata_EXPORT FromString(std::string); }; typedef LUT<1> LUT1D; diff --git a/Modules/Core/Metadata/src/otbImageMetadata.cxx b/Modules/Core/Metadata/src/otbImageMetadata.cxx index d61ba6196b..927ecd99aa 100644 --- a/Modules/Core/Metadata/src/otbImageMetadata.cxx +++ b/Modules/Core/Metadata/src/otbImageMetadata.cxx @@ -218,8 +218,9 @@ void ImageMetadataBase::ToKeywordlist(Keywordlist& kwl) const if (kv.first == MDGeom::RPC) { - Projection::RPCParam rpcStruct = boost::any_cast<Projection::RPCParam>(kv.second); - cast_string = rpcStruct.ToJSON(); +// Projection::RPCParam rpcStruct = boost::any_cast<Projection::RPCParam>(kv.second); +// cast_string = rpcStruct.ToJSON(); + cast_string = std::string("<RPCParam>"); } else if (kv.first == MDGeom::ProjectionEPSG) { @@ -227,8 +228,9 @@ void ImageMetadataBase::ToKeywordlist(Keywordlist& kwl) const } else if (kv.first == MDGeom::GCP) { - Projection::GCPParam gcpStruct = boost::any_cast<Projection::GCPParam>(kv.second); - cast_string = gcpStruct.ToJSON(); +// Projection::GCPParam gcpStruct = boost::any_cast<Projection::GCPParam>(kv.second); +// cast_string = gcpStruct.ToJSON(); + cast_string = std::string("<GCPParam>"); } // TODO : MDGeom::SensorGeometry (should be exported as "<typeinfo>" where typeinfo is boost::any::type().name() // TODO : MDGeom::SAR @@ -255,12 +257,12 @@ void ImageMetadataBase::ToKeywordlist(Keywordlist& kwl) const // Converting the LUT1DKeys for (const auto& kv : LUT1DKeys) { - kwl.emplace(MetaData::MDL1DNames[kv.first], kv.second.ToJSON()); + kwl.emplace(MetaData::MDL1DNames[kv.first], kv.second.ToString()); } // Convereting the LUT2DKeys for (const auto& kv : LUT2DKeys) { - kwl.emplace(MetaData::MDL2DNames[kv.first], kv.second.ToJSON()); + kwl.emplace(MetaData::MDL2DNames[kv.first], kv.second.ToString()); } // Converting the TimeKeys for (const auto& kv : TimeKeys) diff --git a/Modules/Core/Metadata/src/otbMetaDataKey.cxx b/Modules/Core/Metadata/src/otbMetaDataKey.cxx index 4db371acfe..bc34eb734b 100644 --- a/Modules/Core/Metadata/src/otbMetaDataKey.cxx +++ b/Modules/Core/Metadata/src/otbMetaDataKey.cxx @@ -216,9 +216,9 @@ std::string LUT<VDim>::ToJSON(bool multiline) const sep = "\n"; } oss << "{" - << "\"Axes\": ["; + << "\"Axis\": ["; for (unsigned int loop = 0 ; loop < VDim ; loop++) - oss << Axes[loop].ToJSON(multiline) << ", "; + oss << Axis[loop].ToJSON(multiline) << ", "; oss << "], " << sep << "\"Array\": ["; for (const auto& value : Array) @@ -227,6 +227,89 @@ std::string LUT<VDim>::ToJSON(bool multiline) const return oss.str(); } +template <unsigned int VDim> +std::string LUT<VDim>::ToString() const +{ + std::ostringstream oss; + for (unsigned int dim = 0 ; dim < VDim ; dim++) + { + oss << "LUT" << VDim << "D.DIM" << dim << ".SIZE = " << Axis[dim].Size << "\n"; + if (Axis[dim].Values.size() > 0) + // Irregular sampling + { + oss << "LUT" << VDim << "D.DIM" << dim << ".VALUES = "; + for (const auto& value : Axis[dim].Values) + oss << value << " "; + oss << "\n"; + } + else + { + // Regular sampling + oss << "LUT" << VDim << "D.DIM" << dim << ".ORIGIN = " << Axis[dim].Origin << "\n" + << "LUT" << VDim << "D.DIM" << dim << ".SPACING = " << Axis[dim].Spacing << "\n"; + } + } + oss << "LUT" << VDim << "D.ARRAY = "; + for (const auto& value : Array) + oss << value << " "; + return oss.str(); +} + +template <unsigned int VDim> +void LUT<VDim>::FromString(std::string str) +{ + std::vector<std::string> lines; + std::vector<std::string> parts; + boost::split(lines, str, [](char c){return c == '\n';}); + for (std::string line : lines) + { + boost::split(parts, line, [](char c){return c == '=';}); + if (std::stoi(parts[0].substr(3, 1)) != VDim) + throw std::invalid_argument("Wrong LUT dimension"); + std::string element = parts[0].substr(6, 5); + if(parts[0].substr(6, 5) == "ARRAY") + // this->Array + { + std::vector<std::string> str_array; + boost::split(str_array, parts[1], [](char c){return c == ' ';}); + Array.reserve(str_array.size()); + std::transform(str_array.begin(), str_array.end(), back_inserter(Array), + [](std::string const& val) {return std::stod(val);}); + } + else + { + unsigned int dim = std::stoi(parts[0].substr(9, 1)); + if (dim > VDim) + throw std::invalid_argument("LUT dimension higher than expected"); + element = parts[0].substr(11); + if (element == "SIZE ") + // this->Axis[dim].Size + { + Axis[dim].Size = std::stoi(parts[1]); + } + else if (element == "VALUES ") + // this->Axis[dim].Values + { + std::vector<std::string> str_array; + boost::split(str_array, parts[1], [](char c){return c == ' ';}); + Axis[dim].Values.reserve(str_array.size()); + std::transform(str_array.begin(), str_array.end(), back_inserter(Axis[dim].Values), + [](std::string const& val) {return std::stod(val);}); + } + else if (element == "ORIGIN") + // this->Axis[dim].Origin + { + Axis[dim].Origin = std::stoi(parts[1]); + } + else if (element == "SPACING") + // this->Axis[dim].Spacing + { + Axis[dim].Spacing = std::stoi(parts[1]); + } + } + } +} + template class LUT<1>; template class LUT<2>; diff --git a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx index dc00543683..8aa8cbb147 100644 --- a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx +++ b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx @@ -199,9 +199,9 @@ int otbImageMetadataTest(int argc, char* argv[]) gcpStruct.GCPs.push_back(OTB_GCP()); md4.Add(MDGeom::GCP, gcpStruct); MetaData::LUT1D lut1d; - lut1d.Axes[0].Size = 3; - lut1d.Axes[0].Origin = 0; - lut1d.Axes[0].Spacing = 1; + lut1d.Axis[0].Size = 3; + lut1d.Axis[0].Origin = 0; + lut1d.Axis[0].Spacing = 1; std::vector<double>array({1.0, 2.0, 3.0}); lut1d.Array = {1.0, 2.0, 3.0}; md4.Add(MDL1D::SpectralSensitivity, lut1d); -- GitLab