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
|