Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
David Youssefi
otb
Commits
b1c95ce7
Commit
b1c95ce7
authored
Jul 10, 2020
by
Julien Osman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ENH: Read Sentinel1 metadata + add docstrings
parent
360b8f16
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
102 additions
and
30 deletions
+102
-30
Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
...ne/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
+4
-0
Modules/Core/Metadata/include/otbGeometryMetadata.h
Modules/Core/Metadata/include/otbGeometryMetadata.h
+2
-3
Modules/Core/Metadata/include/otbMetaDataKey.h
Modules/Core/Metadata/include/otbMetaDataKey.h
+1
-1
Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
...ore/Metadata/include/otbSentinel1ImageMetadataInterface.h
+17
-12
Modules/Core/Metadata/include/otbXMLMetadataSupplier.h
Modules/Core/Metadata/include/otbXMLMetadataSupplier.h
+44
-3
Modules/Core/Metadata/src/otbMetaDataKey.cxx
Modules/Core/Metadata/src/otbMetaDataKey.cxx
+1
-1
Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
.../Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
+25
-4
Modules/Core/Metadata/src/otbXMLMetadataSupplier.cxx
Modules/Core/Metadata/src/otbXMLMetadataSupplier.cxx
+8
-6
No files found.
Data/Baseline/OTB/Files/ioTvImageMetadataInterfaceTest_Sentinel1.txt
View file @
b1c95ce7
...
...
@@ -14,6 +14,10 @@ OrbitNumber 6447
NumberOfLines 31106
NumberOfColumns 17663
AverageSceneHeight 19
CalScale 1
PRF 1663.48
RadarFrequency 5.405e+09
CenterIncidenceAngle 44.7171
LineSpacing 4.08568
PixelSpacing 3.19483
AcquisitionDate 2015-06-19T19:50:43.223221Z
...
...
Modules/Core/Metadata/include/otbGeometryMetadata.h
View file @
b1c95ce7
...
...
@@ -215,10 +215,9 @@ struct OTBMetadata_EXPORT SARParam
{
std
::
vector
<
OTB_azimuthFmRate
>
azimuthFmRate
;
double
absoluteCalibrationConstant
;
std
::
vector
<
OTB_calibrationVector
>
calibrationVectors
;
MetaData
::
Time
s
tartTime
;
MetaData
::
Time
s
topTime
;
MetaData
::
Time
calibrationS
tartTime
;
MetaData
::
Time
calibrationS
topTime
;
std
::
vector
<
OTB_dopplerCentroid
>
dopplerCentroid
;
...
...
Modules/Core/Metadata/include/otbMetaDataKey.h
View file @
b1c95ce7
...
...
@@ -153,7 +153,7 @@ enum class MDNum
PRF
,
RSF
,
RadarFrequency
,
CenterIn
dic
enceAngle
,
CenterIn
cid
enceAngle
,
RescalingFactor
,
AntennaPatternNewGainPolyDegX
,
AntennaPatternNewGainPolyDegY
,
...
...
Modules/Core/Metadata/include/otbSentinel1ImageMetadataInterface.h
View file @
b1c95ce7
...
...
@@ -93,30 +93,35 @@ public:
/*get lookup data for calculating backscatter */
void
CreateCalibrationLookupData
(
const
short
type
)
override
;
void
Parse
(
const
MetadataSupplierInterface
*
)
override
;
protected:
/* class ctor */
Sentinel1ImageMetadataInterface
();
/* class dtor */
~
Sentinel1ImageMetadataInterface
()
override
{
}
/* Fetch the AzimuthFmRate metadata */
std
::
vector
<
OTB_azimuthFmRate
>
GetAzimuthFmRate
(
XMLMetadataSupplier
)
const
;
/* Fetch the DopplerCentroid metadata */
std
::
vector
<
OTB_dopplerCentroid
>
GetDopplerCentroid
(
XMLMetadataSupplier
)
const
;
/* Fetch the Orbits metadata */
std
::
vector
<
OTB_Orbit
>
GetOrbits
(
XMLMetadataSupplier
)
const
;
/* Fetch the Calibration metadata */
std
::
vector
<
OTB_calibrationVector
>
GetCalibrationVector
(
XMLMetadataSupplier
)
const
;
/*
f
etch the noise LUTs */
/*
F
etch the noise LUTs */
std
::
vector
<
OTB_SARNoise
>
GetNoiseVector
(
XMLMetadataSupplier
)
const
;
/* Compute the mean terrain elevation */
double
getBandTerrainHeight
(
XMLMetadataSupplier
)
const
;
void
Parse
(
const
MetadataSupplierInterface
*
)
override
;
protected:
/* class ctor */
Sentinel1ImageMetadataInterface
();
/* class dtor */
~
Sentinel1ImageMetadataInterface
()
override
{
}
private:
Sentinel1ImageMetadataInterface
(
const
Self
&
)
=
delete
;
void
operator
=
(
const
Self
&
)
=
delete
;
...
...
Modules/Core/Metadata/include/otbXMLMetadataSupplier.h
View file @
b1c95ce7
...
...
@@ -44,13 +44,40 @@ class OTBMetadata_EXPORT XMLMetadataSupplier
public:
XMLMetadataSupplier
(
const
std
::
string
&
);
/** Get the metadata value corresponding to a given path
* Returns NULL when path is not found
* If band >= 0, the metadata value is looked in the specified band*/
/**
* @brief Get the metadata value corresponding to a given path
*
* @param path The path to look for
* @param hasValue True if path is found
* @param band not used
* @return The value corresponding to path. Empty string if not found.
*/
const
std
::
string
GetMetadataValue
(
const
std
::
string
path
,
bool
&
hasValue
,
int
band
=
1
)
const
override
;
/**
* @brief Get the first metadata value corresponding to a given path
*
* @param path The path to look for
* @param hasValue True if path is found
* @return The value corresponding to path. Empty string if not found.
*/
const
std
::
string
GetFirstMetadataValue
(
const
std
::
string
paths
,
bool
&
hasValue
)
const
;
/**
* @brief Get the metadata value corresponding to a given path
* converted to the given type
*
* This method can look for a value in a list, using the _# jocker. For exemple,
* looking for "value" in a dictionary like this :
* foo_1.bar=42
* foo_1.doo=99
* foo_2.value=8
* One can specify this path : foo_#.value, the method will then return 8.
*
* @param path The path to look for.
* @return The value corresponding to path.
* @raises otb::Error if path not found
*/
template
<
typename
T
>
T
GetFirstAs
(
std
::
string
path
)
const
{
bool
hasValue
;
...
...
@@ -73,6 +100,11 @@ public:
int
GetNbBands
()
const
override
;
/**
* @brief Writes the content of the XML file into a string
*
* @return A std::string
*/
std
::
string
PrintSelf
();
protected:
...
...
@@ -90,6 +122,15 @@ protected:
virtual
char
**
ReadXMLToList
(
CPLXMLNode
*
psNode
,
char
**
papszList
,
const
char
*
pszName
=
""
);
/**
* @brief In a StringList of “Name=Value” pairs, look for the values
* associated with a name containing the specified string
*
* @param papszStrList A StringList that will be searched
* @param pszName A string that will be looked for in the keys
* @return A StringList containing only the pairs from papszStrList whose key
* contain pszName
*/
char
**
CSLFetchPartialNameValueMultiple
(
char
**
papszStrList
,
const
char
*
pszName
)
const
;
private:
...
...
Modules/Core/Metadata/src/otbMetaDataKey.cxx
View file @
b1c95ce7
...
...
@@ -338,7 +338,7 @@ MDNumBmType MDNumNames = bimapGenerator<MDNum>(std::map<MDNum, std::string> {
{
MDNum
::
PRF
,
"PRF"
},
{
MDNum
::
RSF
,
"RSF"
},
{
MDNum
::
RadarFrequency
,
"RadarFrequency"
},
{
MDNum
::
CenterIn
dic
enceAngle
,
"CenterIn
dic
enceAngle"
},
{
MDNum
::
CenterIn
cid
enceAngle
,
"CenterIn
cid
enceAngle"
},
{
MDNum
::
RescalingFactor
,
"RescalingFactor"
},
{
MDNum
::
AntennaPatternNewGainPolyDegX
,
"AntennaPatternNewGainPolyDegX"
},
{
MDNum
::
AntennaPatternNewGainPolyDegY
,
"AntennaPatternNewGainPolyDegY"
},
...
...
Modules/Core/Metadata/src/otbSentinel1ImageMetadataInterface.cxx
View file @
b1c95ce7
...
...
@@ -355,12 +355,15 @@ double Sentinel1ImageMetadataInterface::GetCenterIncidenceAngle() const
std
::
vector
<
OTB_azimuthFmRate
>
Sentinel1ImageMetadataInterface
::
GetAzimuthFmRate
(
XMLMetadataSupplier
xmlMS
)
const
{
std
::
vector
<
OTB_azimuthFmRate
>
azimuthFmRateVector
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"product.generalAnnotation.azimuthFmRateList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"product.generalAnnotation.azimuthFmRateList.azimuthFmRate_"
+
oss
.
str
();
OTB_azimuthFmRate
afr
;
std
::
istringstream
(
xmlMS
.
GetAs
<
std
::
string
>
(
path_root
+
".azimuthTime"
))
>>
afr
.
azimuthTime
;
...
...
@@ -375,12 +378,15 @@ std::vector<OTB_azimuthFmRate> Sentinel1ImageMetadataInterface::GetAzimuthFmRate
std
::
vector
<
OTB_dopplerCentroid
>
Sentinel1ImageMetadataInterface
::
GetDopplerCentroid
(
XMLMetadataSupplier
xmlMS
)
const
{
std
::
vector
<
OTB_dopplerCentroid
>
dopplerCentroidVector
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"product.dopplerCentroid.dcEstimateList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"product.dopplerCentroid.dcEstimateList.dcEstimate_"
+
oss
.
str
();
OTB_dopplerCentroid
dopplerCent
;
std
::
istringstream
(
xmlMS
.
GetAs
<
std
::
string
>
(
path_root
+
".azimuthTime"
))
>>
dopplerCent
.
azimuthTime
;
...
...
@@ -397,12 +403,15 @@ std::vector<OTB_dopplerCentroid> Sentinel1ImageMetadataInterface::GetDopplerCent
std
::
vector
<
OTB_Orbit
>
Sentinel1ImageMetadataInterface
::
GetOrbits
(
XMLMetadataSupplier
xmlMS
)
const
{
std
::
vector
<
OTB_Orbit
>
orbitVector
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"product.generalAnnotation.orbitList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"product.generalAnnotation.orbitList.orbit_"
+
oss
.
str
();
OTB_Orbit
orbit
;
std
::
istringstream
(
xmlMS
.
GetAs
<
std
::
string
>
(
path_root
+
".time"
))
>>
orbit
.
time
;
...
...
@@ -420,12 +429,15 @@ std::vector<OTB_Orbit> Sentinel1ImageMetadataInterface::GetOrbits(XMLMetadataSup
std
::
vector
<
OTB_calibrationVector
>
Sentinel1ImageMetadataInterface
::
GetCalibrationVector
(
XMLMetadataSupplier
xmlMS
)
const
{
std
::
vector
<
OTB_calibrationVector
>
calibrationVector
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"calibration.calibrationVectorList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"calibration.calibrationVectorList.calibrationVector_"
+
oss
.
str
();
OTB_calibrationVector
calVect
;
...
...
@@ -469,12 +481,15 @@ std::vector<OTB_calibrationVector> Sentinel1ImageMetadataInterface::GetCalibrati
std
::
vector
<
OTB_SARNoise
>
Sentinel1ImageMetadataInterface
::
GetNoiseVector
(
XMLMetadataSupplier
xmlMS
)
const
{
std
::
vector
<
OTB_SARNoise
>
noiseVector
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"noise.noiseVectorList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"noise.noiseVectorList.noiseVector_"
+
oss
.
str
();
OTB_SARNoise
noiseVect
;
std
::
istringstream
(
xmlMS
.
GetAs
<
std
::
string
>
(
path_root
+
".azimuthTime"
))
>>
noiseVect
.
azimuthTime
;
...
...
@@ -494,16 +509,19 @@ std::vector<OTB_SARNoise> Sentinel1ImageMetadataInterface::GetNoiseVector(XMLMet
double
Sentinel1ImageMetadataInterface
::
getBandTerrainHeight
(
XMLMetadataSupplier
xmlMS
)
const
{
double
heightSum
=
0.0
;
// Number of entries in the vector
int
listCount
=
xmlMS
.
GetAs
<
int
>
(
"product.generalAnnotation.terrainHeightList.count"
);
// This streams wild hold the iteration number
std
::
ostringstream
oss
;
for
(
int
listId
=
1
;
listId
<=
listCount
;
++
listId
)
{
oss
.
str
(
""
);
oss
<<
listId
;
// Base path to the data, that depends on the iteration number
std
::
string
path_root
=
"product.generalAnnotation.terrainHeightList.terrainHeight_"
+
oss
.
str
();
heightSum
+=
xmlMS
.
GetAs
<
double
>
((
path_root
+
".value"
).
c_str
());
}
return
heightSum
/
listCount
;
return
heightSum
/
(
double
)
listCount
;
}
void
Sentinel1ImageMetadataInterface
::
Parse
(
const
MetadataSupplierInterface
*
mds
)
...
...
@@ -559,6 +577,9 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds
m_Imd
.
Add
(
MDNum
::
NumberOfLines
,
AnnotationMS
.
GetAs
<
int
>
(
"product.imageAnnotation.imageInformation.numberOfLines"
));
m_Imd
.
Add
(
MDNum
::
NumberOfColumns
,
AnnotationMS
.
GetAs
<
int
>
(
"product.imageAnnotation.imageInformation.numberOfSamples"
));
m_Imd
.
Add
(
MDNum
::
AverageSceneHeight
,
this
->
getBandTerrainHeight
(
AnnotationFilePath
));
m_Imd
.
Add
(
MDNum
::
RadarFrequency
,
AnnotationMS
.
GetAs
<
double
>
(
"product.generalAnnotation.productInformation.radarFrequency"
));
m_Imd
.
Add
(
MDNum
::
PRF
,
AnnotationMS
.
GetAs
<
double
>
(
"product.imageAnnotation.imageInformation.azimuthFrequency"
));
m_Imd
.
Add
(
MDNum
::
CenterIncidenceAngle
,
AnnotationMS
.
GetAs
<
double
>
(
"product.imageAnnotation.imageInformation.incidenceAngleMidSwath"
));
// Calibration file
std
::
string
CalibrationFilePath
=
itksys
::
SystemTools
::
GetFilenamePath
(
AnnotationFilePath
)
...
...
@@ -567,10 +588,10 @@ void Sentinel1ImageMetadataInterface::Parse(const MetadataSupplierInterface *mds
if
(
CalibrationFilePath
.
empty
())
otbGenericExceptionMacro
(
MissingMetadataException
,
<<
"Missing Calibration file for band '"
<<
swath
<<
"'"
);
XMLMetadataSupplier
CalibrationMS
=
XMLMetadataSupplier
(
CalibrationFilePath
);
sarParam
.
absoluteCalibrationConstant
=
CalibrationMS
.
GetAs
<
double
>
(
"calibration.calibrationInformation.absoluteCalibrationConstant"
);
m_Imd
.
Add
(
MDNum
::
CalScale
,
CalibrationMS
.
GetAs
<
double
>
(
"calibration.calibrationInformation.absoluteCalibrationConstant"
)
)
;
sarParam
.
calibrationVectors
=
this
->
GetCalibrationVector
(
CalibrationMS
);
std
::
istringstream
(
CalibrationMS
.
GetAs
<
std
::
string
>
(
"calibration.adsHeader.startTime"
))
>>
sarParam
.
s
tartTime
;
std
::
istringstream
(
CalibrationMS
.
GetAs
<
std
::
string
>
(
"calibration.adsHeader.stopTime"
))
>>
sarParam
.
s
topTime
;
std
::
istringstream
(
CalibrationMS
.
GetAs
<
std
::
string
>
(
"calibration.adsHeader.startTime"
))
>>
sarParam
.
calibrationS
tartTime
;
std
::
istringstream
(
CalibrationMS
.
GetAs
<
std
::
string
>
(
"calibration.adsHeader.stopTime"
))
>>
sarParam
.
calibrationS
topTime
;
// Noise file
std
::
string
NoiseFilePath
=
itksys
::
SystemTools
::
GetFilenamePath
(
AnnotationFilePath
)
...
...
Modules/Core/Metadata/src/otbXMLMetadataSupplier.cxx
View file @
b1c95ce7
...
...
@@ -27,12 +27,7 @@ XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName)
{
CPLXMLNode
*
psNode
=
CPLParseXMLFile
(
m_FileName
.
c_str
());
if
(
psNode
!=
nullptr
)
{
//if(std::string(psNode->pszValue) == "?xml")
// if(EQUAL(psNode->pszValue, "?xml"))
// psNode = psNode->psNext;
m_MetadataDic
=
ReadXMLToList
(
psNode
,
m_MetadataDic
);
}
else
{
otbLogMacro
(
Warning
,
<<
"Unable to parse XML file "
<<
fileName
);
...
...
@@ -56,13 +51,19 @@ const std::string XMLMetadataSupplier::GetMetadataValue(const std::string path,
const
std
::
string
XMLMetadataSupplier
::
GetFirstMetadataValue
(
const
std
::
string
path
,
bool
&
hasValue
)
const
{
// Search for the first joker
std
::
size_t
found
=
path
.
find
(
"_#"
);
// Looking for the keys corresponding to the part of the path before the first joker
char
**
values
=
this
->
CSLFetchPartialNameValueMultiple
(
m_MetadataDic
,
path
.
substr
(
0
,
found
).
c_str
());
// Position of the beginning of the path after the joker
std
::
size_t
start
=
found
+
2
;
// While a joker is found
while
(
found
!=
std
::
string
::
npos
)
{
found
=
path
.
find
(
"_#"
,
found
+
2
);
// Look for the next joker
found
=
path
.
find
(
"_#"
,
start
);
// Look for the keys corresponding to the part of the path between the two jokers
values
=
this
->
CSLFetchPartialNameValueMultiple
(
values
,
path
.
substr
(
start
,
found
).
c_str
());
start
=
found
+
2
;
}
...
...
@@ -71,6 +72,7 @@ const std::string XMLMetadataSupplier::GetFirstMetadataValue(const std::string p
{
hasValue
=
true
;
std
::
string
ret
=
std
::
string
(
values
[
0
]);
// Return the value part
return
ret
.
substr
(
ret
.
find
(
'='
)
+
1
);
}
else
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment