From 4e247983a905bd20df1a1fbecc2154a5d3d9f492 Mon Sep 17 00:00:00 2001
From: Julien Osman <julien.osman@c-s.fr>
Date: Mon, 27 Apr 2020 19:07:06 +0200
Subject: [PATCH] REFAC: Implement method ImageMetadata.compact for NumericKeys

---
 .../Core/Metadata/src/otbImageMetadata.cxx    | 35 ++++++++++++++++++-
 Modules/Core/Metadata/test/CMakeLists.txt     | 12 +++++--
 .../Metadata/test/otbImageMetadataTest.cxx    | 30 ++++++++++++----
 3 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/Modules/Core/Metadata/src/otbImageMetadata.cxx b/Modules/Core/Metadata/src/otbImageMetadata.cxx
index de4c724fbb..b23d290e0c 100644
--- a/Modules/Core/Metadata/src/otbImageMetadata.cxx
+++ b/Modules/Core/Metadata/src/otbImageMetadata.cxx
@@ -465,7 +465,40 @@ void ImageMetadata::append(const ImageMetadata& imd)
 /** if all bands share the same value of a key, put it at top level */
 void ImageMetadata::compact()
 {
-  // TODO
+  if (this->Bands.size() < 2)
+    return;
+  bool compactVal;
+  // TODO Compact the GeometryKeys when comparisons exists
+  // TODO Compact NumericKeys
+  for (const auto& kv : this->Bands.front().NumericKeys)
+  {
+    compactVal = true;
+    auto bandIt = this->Bands.cbegin();
+    ++bandIt;
+    for ( ; bandIt != this->Bands.cend() ; ++bandIt)
+    {
+      auto otherKey = bandIt->NumericKeys.find(kv.first);
+      if ((otherKey == bandIt->NumericKeys.end())
+       || !(std::fabs(otherKey->second != kv.second) <= std::numeric_limits<double>::epsilon()))
+      {
+        compactVal = false;
+        break;
+      }
+    }
+    if (compactVal)
+    {
+      this->Add(kv.first, kv.second);
+      for (auto& band : this->Bands)
+      {
+        band.NumericKeys.erase(kv.first);
+      }
+    }
+  }
+  // TODO Compact StringKeys
+  // TODO Compact LUT1DKeys when comparisons exists
+  // TODO Compact LUT2DKeys when comparisons exists
+  // TODO Compact TimeKeys
+  // TODO Compact ExtraKeys
 }
 
 void ImageMetadata::AppendToKeywordlists(KeywordlistVector& kwlVect) const
diff --git a/Modules/Core/Metadata/test/CMakeLists.txt b/Modules/Core/Metadata/test/CMakeLists.txt
index 744b9c485a..2c4bc35905 100644
--- a/Modules/Core/Metadata/test/CMakeLists.txt
+++ b/Modules/Core/Metadata/test/CMakeLists.txt
@@ -370,15 +370,23 @@ otb_add_test(NAME ioTuImageMetadataSliceTest COMMAND otbMetadataTestDriver
   --compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTuImageMetadataSliceTest.txt
   ${TEMP}/ioTuImageMetadataSliceTest.txt
   otbImageMetadataTest
-  otbImageMatadataSliceTest
+  otbImageMetadataSliceTest
   ${TEMP}/ioTuImageMetadataSliceTest.txt
   )
   
+otb_add_test(NAME ioTuImageMetadataCompactTest COMMAND otbMetadataTestDriver
+  --compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTuImageMetadataCompactTest.txt
+  ${TEMP}/ioTuImageMetadataCompactTest.txt
+  otbImageMetadataTest
+  otbImageMetadataCompactTest
+  ${TEMP}/ioTuImageMetadataCompactTest.txt
+  )
+  
 otb_add_test(NAME ioTuImageMetadataAppendTest COMMAND otbMetadataTestDriver
   --compare-ascii ${NOTOL} ${BASELINE_FILES}/ioTuImageMetadataAppendTest.txt
   ${TEMP}/ioTuImageMetadataAppendTest.txt
   otbImageMetadataTest
-  otbImageMatadataAppendTest
+  otbImageMetadataAppendTest
   ${TEMP}/ioTuImageMetadataAppendTest.txt
   )
   
diff --git a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
index f69f9d5102..9d0898ceec 100644
--- a/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
+++ b/Modules/Core/Metadata/test/otbImageMetadataTest.cxx
@@ -176,7 +176,7 @@ void otbMetadataKeyTest(char* argv[])
   outfile.close();
 }
 
-void otbImageMatadataSliceTest(char* argv[])
+void otbImageMetadataSliceTest(char* argv[])
 {
   using namespace otb;
 
@@ -191,7 +191,7 @@ void otbImageMatadataSliceTest(char* argv[])
   outfile.close();
 }
 
-void otbImageMatadataAppendTest(char* argv[])
+void otbImageMetadataAppendTest(char* argv[])
 {
   using namespace otb;
 
@@ -241,6 +241,22 @@ void otbImageMetadataToFromKeywordlistTest(char* argv[])
   outfile.close();
 }
 
+void otbImageMetadataCompactTest(char* argv[])
+{
+  using namespace otb;
+
+  const char*   outFileName = argv[2];
+  std::ofstream outfile(outFileName);
+
+  ImageMetadata md;
+  md.compact();
+  SetUpImageMetadata(md, 3);
+
+  md.compact();
+  outfile << md;
+  outfile.close();
+}
+
 int otbImageMetadataTest(int argc, char* argv[])
 {
   if (argc < 2)
@@ -249,12 +265,14 @@ int otbImageMetadataTest(int argc, char* argv[])
   std::string testName(argv[1]);
   if(testName == "otbMetadataKeyTest")
 	  otbMetadataKeyTest(argv);
-  else if (testName == "otbImageMatadataSliceTest")
-	  otbImageMatadataSliceTest(argv);
-  else if (testName == "otbImageMatadataAppendTest")
-	  otbImageMatadataAppendTest(argv);
+  else if (testName == "otbImageMetadataSliceTest")
+	  otbImageMetadataSliceTest(argv);
+  else if (testName == "otbImageMetadataAppendTest")
+	  otbImageMetadataAppendTest(argv);
   else if (testName == "otbImageMetadataToFromKeywordlistTest")
 	  otbImageMetadataToFromKeywordlistTest(argv);
+  else if (testName == "otbImageMetadataCompactTest")
+	  otbImageMetadataCompactTest(argv);
   else
   {
     std::cout << "Unknown test name " << testName;
-- 
GitLab