File: otbImageMetadata.h

package info (click to toggle)
otb 8.1.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,030,436 kB
  • sloc: xml: 231,007; cpp: 224,490; ansic: 4,592; sh: 1,790; python: 1,131; perl: 92; makefile: 72
file content (367 lines) | stat: -rw-r--r-- 12,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
/*
 * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef otbImageMetadata_h
#define otbImageMetadata_h

#include "otbGeometryMetadata.h"
#include "otbSARMetadata.h"
#include "otbMetaDataKey.h"
#include "OTBMetadataExport.h"
#include "otbMacro.h"

#include <boost/any.hpp>
#include <vector>
#include <string>
#include <map>
#include <unordered_map>

namespace otb
{

/** \class ImageMetadataBase
 *
 *  \brief Metadata hybrid dictionary
 *
 *  Contains a dict of geometry parameters, several typed dictionaries for
 *  double, string, and other types. The different metadatas are retrieved
 *  with enum classes ( one for each type stored in the dictionary).
 *
 * \ingroup OTBMetadata
 */
class OTBMetadata_EXPORT ImageMetadataBase
{
public:
  /** type of dictionary used internally */
  template <class TKey, class TVal>
  using DictType = std::map<TKey, TVal>;

  using Keywordlist = std::unordered_map<std::string, std::string>;

  /** Stack of geometry parameters, sorted by decreasing priority
   *  Cases with corresponding enum values:
   *    - projected
   *        * MDGeom::ProjectionWKT   -> WKT (string)
   *        * MDGeom::ProjectionEPSG  -> EPSG (integer)
   *        * MDGeom::ProjectionProj  -> proj4 (string)
   *    - sensor
   *        * MDGeom::RPC             -> RPCParam
   *        * MDGeom::SAR             -> SARParam
   *        * MDGeom::Adjustment      -> optional adjustment param (TBD)
   *        * MDGeom::GCP             -> GCPParam
   *        * MDGeom::SensorGeometry  -> other sensor model represented by a std::string (need a factory to deal with it)
   *    - epipolar ?
   *        + epipolar rectification grid
   *
   * Corner cases we may encounter:
   *   - sensor refinement: [RPC, GCP, adjustment]
   *   - piece-wise sensor model: [compound_RPC] ( handled as MDGeom::SensorGeometry)
   *   - raw georeferencing: [GCP]
   *   - Fine registration : [WKT, adjustment grid]
   */
  DictType<MDGeom, boost::any> GeometryKeys;

  DictType<MDNum, double> NumericKeys;

  DictType<MDStr, std::string> StringKeys;

  DictType<MDL1D, MetaData::LUT1D> LUT1DKeys;

  DictType<MDL2D, MetaData::LUT2D> LUT2DKeys;

  DictType<MDTime, MetaData::TimePoint> TimeKeys;

  DictType<std::string, std::string> ExtraKeys;

  // Constructor
  ImageMetadataBase();
  ImageMetadataBase(DictType<MDGeom, boost::any> geometryKeys,
                    DictType<MDNum, double> numericKeys,
                    DictType<MDStr, std::string> stringKeys,
                    DictType<MDL1D, MetaData::LUT1D> lut1DKeys,
                    DictType<MDL2D, MetaData::LUT2D> lut2DKeys,
                    DictType<MDTime, MetaData::TimePoint> timeKeys,
                    DictType<std::string, std::string> extraKeys);

  // -------------------- Geom utility function ----------------------------

  /** Read-only accessor to geometric keys */
  const boost::any & operator[](const MDGeom& key) const;

  const Projection::GCPParam & GetGCPParam() const;
  const Projection::RPCParam & GetRPCParam() const;
  const SARParam & GetSARParam() const;

  std::string GetProjectedGeometry() const;

  std::string GetProjectionWKT() const;
  
  std::string GetProjectionProj() const;
  
  /** Setter for geometric keys */
  void Add(const MDGeom& key, const boost::any &value);
  
  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDGeom& key);

  size_t RemoveSensorGeometry();

  size_t RemoveProjectedGeometry();
  
  /** Test if a key is available */
  bool Has(const MDGeom& key) const;

  bool HasSensorGeometry() const;

  bool HasProjectedGeometry() const;

  // -------------------- Double utility function ----------------------------

  /** Read-only accessor to numeric keys */
  const double & operator[](const MDNum& key) const;
  
  /** Setter for numeric keys */
  void Add(const MDNum& key, const double &value);
  
  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDNum& key);
  
  /** Test if a key is available */
  bool Has(const MDNum& key) const;

  /** Return the list of valid keys */
  std::string GetKeyListNum() const;
  
  // -------------------- String utility function ----------------------------

  /** Read-only accessor to string keys */
  const std::string & operator[](const MDStr& key) const;
  
  /** Setter for string keys */
  void Add(const MDStr& key, const std::string &value);
  
  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDStr& key);
  
  /** Test if a key is available */
  bool Has(const MDStr& key) const;

  /** Return the list of valid keys */
  std::string GetKeyListStr() const;
  
  // -------------------- LUT1D utility function ----------------------------

  /** Read-only accessor to 1D LUT keys */
  const MetaData::LUT1D & operator[](const MDL1D& key) const;
  
  /** Setter for 1D LUT keys */
  void Add(const MDL1D& key, const MetaData::LUT1D &value);
  
  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDL1D& key);
  
  /** Test if a key is available */
  bool Has(const MDL1D& key) const;

  /** Return the list of valid keys */
  std::string GetKeyListL1D() const;
  
  // -------------------- 2D LUT utility function ----------------------------

  /** Read-only accessor to 2D LUT keys */
  const MetaData::LUT2D & operator[](const MDL2D& key) const;
  
  /** Setter for 2D LUT keys */
  void Add(const MDL2D& key, const MetaData::LUT2D &value);
  
  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDL2D& key);
  
  /** Test if a key is available */
  bool Has(const MDL2D& key) const;

  /** Return the list of valid keys */
//  std::string GetKeyListL2D() const;
  
  // -------------------- Time utility function ----------------------------

  /** Read-only accessor to time keys */
  const MetaData::TimePoint & operator[](const MDTime& key) const;
  
  /** Setter for time keys */
  void Add(const MDTime& key, const MetaData::TimePoint &value);

  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const MDTime& key);

  /** Test if a key is available */
  bool Has(const MDTime& key) const;

  /** Return the list of valid keys */
  std::string GetKeyListTime() const;

  // -------------------- Extra keys utility function --------------------------

  /** Read-only accessor to extra keys */
  const std::string & operator[](const std::string & key) const;

  /** Setter for extra keys */
  void Add(const std::string& key, const std::string &value);

  /** Remove a key from the dictionary (even if the key is already missing) */
  size_t Remove(const std::string& key);

  /** Test if a key is available */
  bool Has(const std::string& key) const;

  // -------------------- Other --------------------------

  /** Fill a KeywordList with the metadata */
  void ToKeywordlist(Keywordlist&) const;
  
  /** Format the metadata to JSON */
  std::string ToJSON(bool multiline=false) const;

  /** Import metadata from a string keywordlist.
   * Will skip MDGeom::SensorGeometry, MDGeom::RPC and MDGeom::GCP.
   * Returns True if all keywords were parsed correctly.
   */
  bool FromKeywordlist(const Keywordlist&);

  /** Merge with another ImageMetadataBase
   * If a key exists in both ImageMetadataBase, keeps the value of this ImageMetadataBase. */
  void Fuse(const ImageMetadataBase& );

  /** Return the band that should be displayed by default, using the information contained in the
   *  input ImageMetadata (MDNum::RedDisplayChannel, GreenDisplayChannel and BlueDisplayChannel)
   *  the first channel being indexed as 0.
   *  If no information is available the default order (0,1,2) is returned instead */
  std::vector<unsigned int> GetDefaultDisplay() const;

  /** Return the number of elements in the ImageMetadataBase */
  int GetSize() const;

};


/** \class ImageMetadata
 *
 * \brief Generic class containing image metadata used in OTB
 *
 * \ingroup OTBMetadata
 */
class OTBMetadata_EXPORT ImageMetadata: public ImageMetadataBase
{
public:
  /** Metadata object as a vector of Keywordlist */
  using KeywordlistVector = std::vector<ImageMetadata::Keywordlist>;

  /** Band-specific metadatas */
  using ImageMetadataBandsType = std::vector<ImageMetadataBase>;
  ImageMetadataBandsType Bands;

  // Constructor
  ImageMetadata() = default;
  ImageMetadata(DictType<MDGeom, boost::any> geometryKeys,
                DictType<MDNum, double> numericKeys,
                DictType<MDStr, std::string> stringKeys,
                DictType<MDL1D, MetaData::LUT1D> lut1DKeys,
                DictType<MDL2D, MetaData::LUT2D> lut2DKeys,
                DictType<MDTime, MetaData::TimePoint> timeKeys,
                DictType<std::string, std::string> extraKeys,
                ImageMetadataBandsType bands);

  // utility functions
  /** Extract metadata from a subset of the bands */
  ImageMetadata slice(int start, int end) const;

  /** concatenate with an other ImageMetadata
   * If a key exists in both ImageMetadata, keeps the value of this ImageMetadata.*/
  void append(const ImageMetadata& );

  /** if all bands share the same value of a key, put it at top level */
  void compact();

  /** merge with another ImageMetadata
   * If a key exists in both ImageMetadata, keeps the value of this ImageMetadata.
   * */
  void Merge(const ImageMetadata& );
  
  /** Append the Metadata to a vector of KeywordList.
   *  The first KeywordList contains the metadata common to all the bands.
   *  The following KeywordList contains the metadata of the bands.
   */
  void AppendToKeywordlists(KeywordlistVector&) const;

  /** Append the bands of the Metadata to a vector of KeywordList.
   *  Each KeywordList contain the metadata of a band.
   */
  void AppendToBandKeywordlists(KeywordlistVector&) const;

  /** Import metadata from a vector of keywordlist.
   *  The first KeywordList contains the metadata common to all the bands.
   *  The following KeywordList contains the metadata of the bands.
   *  Will skip MDGeom::SensorGeometry.
   *  Returns True if all keywords were parsed correctly.
   */
  bool FromKeywordlists(const KeywordlistVector&);

  /** Setter for numeric keys on each band*/
  using ImageMetadataBase::Add;
  void Add(const MDNum&, const MetaDataKey::VariableLengthVectorType);

  /** Getter for numeric keys on each band*/
  itk::VariableLengthVector<double> GetAsVector(const MDNum & key) const;

  /** test whether the metadata corresponding to key is present on each band */
  bool HasBandMetadata(const MDNum & key) const;

  /** test whether the metadata corresponding to key is present on each band */
  bool HasBandMetadata(const MDL1D & key) const;

  /** Return a vector containing the name of each band of the ImageMetadata or an empty 
   * vector if at least one band name is missing */
  std::vector<std::string> GetBandNames() const;

  /** Return a vector containing the name of each band of the ImageMetadata or an empty 
   * vector if at least one band name is missing */
  std::vector<std::string> GetEnhancedBandNames() const;

  /** Return the number of elements in the ImageMetadata */
  int GetSize() const;
};

extern OTBMetadata_EXPORT std::ostream& operator<<(std::ostream& os, const otb::ImageMetadataBase& imd);

extern OTBMetadata_EXPORT std::ostream& operator<<(std::ostream& os, const otb::ImageMetadata& imd);

OTBMetadata_EXPORT bool HasOpticalSensorMetadata(const ImageMetadata & imd);
OTBMetadata_EXPORT bool HasSARSensorMetadata(const ImageMetadata & imd);

OTBMetadata_EXPORT void WriteImageMetadataToGeomFile(const ImageMetadata & imd, const std::string & filename);

/** Comparison test */
bool HasSameRPCModel(const ImageMetadataBase& a, const ImageMetadataBase& b);
bool HasSameSARModel(const ImageMetadataBase& a, const ImageMetadataBase& b);
bool HasSameSensorModel(const ImageMetadataBase& a, const ImageMetadataBase& b);

} // end namespace otb

#endif