From 3ec03180e521b41b7084ffb7e33f355f12b73c8b Mon Sep 17 00:00:00 2001
From: Julien Osman <julien.osman@csgroup.eu>
Date: Thu, 9 Jul 2020 14:04:58 +0200
Subject: [PATCH] WIP: Read more Sentinel1 metadata

---
 .../Metadata/include/otbGeometryMetadata.h    | 17 +++-
 .../Core/Metadata/include/otbMetaDataKey.h    |  2 +
 .../otbSentinel1ImageMetadataInterface.h      |  4 +
 Modules/Core/Metadata/src/otbMetaDataKey.cxx  |  2 +
 .../otbSentinel1ImageMetadataInterface.cxx    | 98 ++++++++++++++-----
 5 files changed, 98 insertions(+), 25 deletions(-)

diff --git a/Modules/Core/Metadata/include/otbGeometryMetadata.h b/Modules/Core/Metadata/include/otbGeometryMetadata.h
index bd69ba3e98..ceb22447b5 100644
--- a/Modules/Core/Metadata/include/otbGeometryMetadata.h
+++ b/Modules/Core/Metadata/include/otbGeometryMetadata.h
@@ -91,10 +91,10 @@ struct OTBMetadata_EXPORT OTB_calibrationVector
 
 struct OTBMetadata_EXPORT OTB_dopplerCentroid
 {
+  MetaData::Time azimuthTime;
+  double t0;
   std::vector<double> dopCoef;
   std::vector<double> geoDopCoef;
-  MetaData::Time geoDopCoefTime;
-  double slantRangeTime;
 };
 
 struct OTBMetadata_EXPORT OTB_SARNoise
@@ -104,6 +104,17 @@ struct OTBMetadata_EXPORT OTB_SARNoise
   MetaData::LUT1D noiseLut;
 };
 
+struct OTBMetadata_EXPORT OTB_Orbit
+{
+  MetaData::Time time;
+  double posX;
+  double posY;
+  double posZ;
+  double velX;
+  double velY;
+  double velZ;
+};
+
 namespace Projection
 {
 
@@ -212,6 +223,8 @@ struct OTBMetadata_EXPORT SARParam
   std::vector<OTB_dopplerCentroid> dopplerCentroid;
 
   std::vector<OTB_SARNoise> noiseVector;
+
+  std::vector<OTB_Orbit> orbits;
 };
 
 } // end namespace Projection
diff --git a/Modules/Core/Metadata/include/otbMetaDataKey.h b/Modules/Core/Metadata/include/otbMetaDataKey.h
index 40540b840d..2794c05e7a 100644
--- a/Modules/Core/Metadata/include/otbMetaDataKey.h
+++ b/Modules/Core/Metadata/include/otbMetaDataKey.h
@@ -132,6 +132,8 @@ enum class MDNum
   DataType,
   NoData,
   OrbitNumber,
+  NumberOfLines,
+  NumberOfColumns,
 // optical section
   PhysicalGain,
   PhysicalBias,
diff --git a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
index 74a2740ce5..2cf3416536 100644
--- a/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
+++ b/Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
@@ -95,6 +95,10 @@ public:
 
   std::vector<OTB_azimuthFmRate> GetAzimuthFmRate(XMLMetadataSupplier) const;
 
+  std::vector<OTB_dopplerCentroid> GetDopplerCentroid(XMLMetadataSupplier) const;
+
+  std::vector<OTB_Orbit> GetOrbits(XMLMetadataSupplier) const;
+
   std::vector<OTB_calibrationVector> GetCalibrationVector(XMLMetadataSupplier) const;
 
   /* fetch the noise LUTs */
diff --git a/Modules/Core/Metadata/src/otbMetaDataKey.cxx b/Modules/Core/Metadata/src/otbMetaDataKey.cxx
index f602848da5..379c96ea59 100644
--- a/Modules/Core/Metadata/src/otbMetaDataKey.cxx
+++ b/Modules/Core/Metadata/src/otbMetaDataKey.cxx
@@ -318,6 +318,8 @@ MDNumBmType MDNumNames = bimapGenerator<MDNum>(std::map<MDNum, std::string> {
   {MDNum::TileHintY,"TileHintY"},
   {MDNum::DataType,"DataType"},
   {MDNum::NoData, "NoData"},
+  {MDNum::NumberOfLines,"NumberOfLines"},
+  {MDNum::NumberOfColumns,"NumberOfColumns"},
   {MDNum::OrbitNumber, "OrbitNumber"},
   {MDNum::PhysicalGain,"PhysicalGain"},
   {MDNum::PhysicalBias,"PhysicalBias"},
diff --git a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
index f43fe7ea3c..d19dbe2272 100644
--- a/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
+++ b/Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
@@ -372,6 +372,51 @@ std::vector<OTB_azimuthFmRate> Sentinel1ImageMetadataInterface::GetAzimuthFmRate
   return azimuthFmRateVector;
 }
 
+std::vector<OTB_dopplerCentroid> Sentinel1ImageMetadataInterface::GetDopplerCentroid(XMLMetadataSupplier xmlMS) const
+{
+  std::vector<OTB_dopplerCentroid> dopplerCentroidVector;
+  int listCount = xmlMS.GetAs<double>("product.dopplerCentroid.dcEstimateList.count");
+  std::ostringstream oss;
+  for (int listId = 1 ; listId <= listCount ; ++listId)
+  {
+    oss.str("");
+    oss << listId;
+    std::string path_root = "product.dopplerCentroid.dcEstimateList.dcEstimate_" + oss.str();
+    OTB_dopplerCentroid dopplerCent;
+    std::istringstream(xmlMS.GetAs<std::string>(path_root + ".azimuthTime")) >> dopplerCent.azimuthTime;
+    dopplerCent.t0 = xmlMS.GetAs<double>(path_root + ".t0");
+    dopplerCent.dopCoef = xmlMS.GetAsVector<double>(path_root + ".dataDcPolynomial",
+    		' ', xmlMS.GetAs<int>((path_root + ".dataDcPolynomial.count").c_str()));
+	dopplerCent.geoDopCoef = xmlMS.GetAsVector<double>(path_root + ".geometryDcPolynomial",
+    		' ', xmlMS.GetAs<int>((path_root + ".geometryDcPolynomial.count").c_str()));
+	dopplerCentroidVector.push_back(dopplerCent);
+  }
+  return dopplerCentroidVector;
+}
+
+std::vector<OTB_Orbit> Sentinel1ImageMetadataInterface::GetOrbits(XMLMetadataSupplier xmlMS) const
+{
+  std::vector<OTB_Orbit> orbitVector;
+  int listCount = xmlMS.GetAs<double>("product.generalAnnotation.orbitList.count");
+  std::ostringstream oss;
+  for (int listId = 1 ; listId <= listCount ; ++listId)
+  {
+    oss.str("");
+    oss << listId;
+    std::string path_root = "product.generalAnnotation.orbitList.orbit_" + oss.str();
+    OTB_Orbit orbit;
+    std::istringstream(xmlMS.GetAs<std::string>(path_root + ".time")) >> orbit.time;
+    orbit.posX = xmlMS.GetAs<double>(path_root + "1.position.x");
+    orbit.posY = xmlMS.GetAs<double>(path_root + "1.position.y");
+    orbit.posZ = xmlMS.GetAs<double>(path_root + "1.position.z");
+    orbit.velX = xmlMS.GetAs<double>(path_root + "1.velocity.x");
+    orbit.velY = xmlMS.GetAs<double>(path_root + "1.velocity.y");
+    orbit.velZ = xmlMS.GetAs<double>(path_root + "1.velocity.z");
+    orbitVector.push_back(orbit);
+  }
+  return orbitVector;
+}
+
 std::vector<OTB_calibrationVector> Sentinel1ImageMetadataInterface::GetCalibrationVector(XMLMetadataSupplier xmlMS) const
 {
   std::vector<OTB_calibrationVector> calibrationVector;
@@ -489,29 +534,36 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds
     std::string AnnotationFilePath = mds->GetResourceFile(std::string("annotation[/\\\\]s1[ab].*-")
                                                           + itksys::SystemTools::LowerCase(swath)
                                                           + std::string("-.*\\.xml"));
-    if (!AnnotationFilePath.empty())
-    {
-      XMLMetadataSupplier AnnotationMS = XMLMetadataSupplier(AnnotationFilePath);
-
-      sarParam.azimuthFmRate = this->GetAzimuthFmRate(AnnotationMS);
-
-      // Calibration file
-      std::string CalibrationFilePath = itksys::SystemTools::GetFilenamePath(AnnotationFilePath)
-                                        + "/calibration/calibration-"
-                                        + itksys::SystemTools::GetFilenameName(AnnotationFilePath);
-      XMLMetadataSupplier CalibrationMS = XMLMetadataSupplier(CalibrationFilePath);
-      sarParam.absoluteCalibrationConstant = CalibrationMS.GetAs<double>("calibration.calibrationInformation.absoluteCalibrationConstant");
-      sarParam.calibrationVectors = this->GetCalibrationVector(CalibrationMS);
-      std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.startTime")) >> sarParam.startTime;
-      std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.stopTime")) >> sarParam.stopTime;
-
-      // Noise file
-      std::string NoiseFilePath = itksys::SystemTools::GetFilenamePath(AnnotationFilePath)
-                                              + "/calibration/noise-"
-                                              + itksys::SystemTools::GetFilenameName(AnnotationFilePath);
-      XMLMetadataSupplier NoiseMS = XMLMetadataSupplier(NoiseFilePath);
-      sarParam.noiseVector = this->GetNoiseVector(NoiseMS);
-    }
+    if (AnnotationFilePath.empty())
+      otbGenericExceptionMacro(MissingMetadataException,<<"Missing Annotation file for band '"<<swath<<"'");
+    XMLMetadataSupplier AnnotationMS = XMLMetadataSupplier(AnnotationFilePath);
+
+    sarParam.azimuthFmRate = this->GetAzimuthFmRate(AnnotationMS);
+    sarParam.dopplerCentroid = this->GetDopplerCentroid(AnnotationMS);
+    sarParam.orbits = this->GetOrbits(AnnotationMS);
+    m_Imd.Add(MDNum::NumberOfLines, AnnotationMS.GetAs<int>("product.imageAnnotation.imageInformation.numberOfLines"));
+    m_Imd.Add(MDNum::NumberOfColumns, AnnotationMS.GetAs<int>("product.imageAnnotation.imageInformation.numberOfSamples"));
+
+    // Calibration file
+    std::string CalibrationFilePath = itksys::SystemTools::GetFilenamePath(AnnotationFilePath)
+                                      + "/calibration/calibration-"
+                                      + itksys::SystemTools::GetFilenameName(AnnotationFilePath);
+    if (CalibrationFilePath.empty())
+          otbGenericExceptionMacro(MissingMetadataException,<<"Missing Calibration file for band '"<<swath<<"'");
+    XMLMetadataSupplier CalibrationMS = XMLMetadataSupplier(CalibrationFilePath);
+    sarParam.absoluteCalibrationConstant = CalibrationMS.GetAs<double>("calibration.calibrationInformation.absoluteCalibrationConstant");
+    sarParam.calibrationVectors = this->GetCalibrationVector(CalibrationMS);
+    std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.startTime")) >> sarParam.startTime;
+    std::istringstream(CalibrationMS.GetAs<std::string>("calibration.adsHeader.stopTime")) >> sarParam.stopTime;
+
+    // Noise file
+    std::string NoiseFilePath = itksys::SystemTools::GetFilenamePath(AnnotationFilePath)
+                                            + "/calibration/noise-"
+                                            + itksys::SystemTools::GetFilenameName(AnnotationFilePath);
+    if (NoiseFilePath.empty())
+          otbGenericExceptionMacro(MissingMetadataException,<<"Missing Noise file for band '"<<swath<<"'");
+    XMLMetadataSupplier NoiseMS = XMLMetadataSupplier(NoiseFilePath);
+
     m_Imd.Bands[bandId].Add(MDGeom::SAR, sarParam);
   }
 }
-- 
GitLab