Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Read metadata (mainly the remote sensing imagery) from files of
5 : * different providers like DigitalGlobe, GeoEye etc.
6 : * Author: Dmitry Baryshnikov, polimax@mail.ru
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2014-2015, NextGIS info@nextgis.ru
10 : *
11 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #ifndef GDAL_MDREADER_H_INCLUDED
15 : #define GDAL_MDREADER_H_INCLUDED
16 :
17 : #include "cpl_port.h"
18 : #include "gdal_priv.h"
19 :
20 : #include <map>
21 :
22 : /** Name of the metadata domain that holds information from IMD side-car files.
23 : * @deprecated Use GDAL_MDD_IMD
24 : */
25 : #define MD_DOMAIN_IMD GDAL_MDD_IMD /**< image metadata section */
26 :
27 : /** Name of the metadata domain that holds Rational Polynomial Coefficients
28 : * (RPC)
29 : * @deprecated Use GDAL_MDD_RPC
30 : */
31 : #define MD_DOMAIN_RPC GDAL_MDD_RPC /**< rpc metadata section */
32 :
33 : /** Name of the metadata domain that holds GDAL-standardized metadata items
34 : * for satellite or aerial imagery.
35 : * @deprecated Use GDAL_MDD_IMAGERY
36 : */
37 : #define MD_DOMAIN_IMAGERY GDAL_MDD_IMAGERY /**< imagery metadata section */
38 :
39 : /** Name of the default metadata domain.
40 : * @deprecated Use GDAL_MDD_DEFAULT
41 : */
42 : #define MD_DOMAIN_DEFAULT GDAL_MDD_DEFAULT
43 :
44 : /** Metadata item for image acquisition date time in UTC, in the
45 : * GDAL_MDD_IMAGERY domain.
46 : * @deprecated GDALMD_ACQUISITIONDATETIME
47 : */
48 : #define MD_NAME_ACQDATETIME GDALMD_ACQUISITIONDATETIME
49 :
50 : /** Metadata item for satellite/scanner ID, in the GDAL_MDD_IMAGERY domain.
51 : * @deprecated GDALMD_SATELLITEID
52 : */
53 : #define MD_NAME_SATELLITE GDALMD_SATELLITEID
54 :
55 : /** Metadata item for cloud cover, in the GDAL_MDD_IMAGERY domain.
56 : * The value is between 0 and 100, or 999 if not available
57 : * @deprecated GDALMD_CLOUDCOVER
58 : */
59 : #define MD_NAME_CLOUDCOVER GDALMD_CLOUDCOVER
60 :
61 : #define MD_NAME_MDTYPE \
62 : "METADATATYPE" /**< Metadata reader type property name. The reader \
63 : processed this metadata */
64 :
65 : #define MD_DATETIMEFORMAT "%Y-%m-%d %H:%M:%S" /**< Date time format */
66 : #define MD_CLOUDCOVER_NA "999" /**< The value if cloud cover is n/a */
67 :
68 : /**
69 : * RPC/RPB specific defines
70 : */
71 :
72 : #define RPC_ERR_BIAS "ERR_BIAS"
73 : #define RPC_ERR_RAND "ERR_RAND"
74 : #define RPC_LINE_OFF "LINE_OFF"
75 : #define RPC_SAMP_OFF "SAMP_OFF"
76 : #define RPC_LAT_OFF "LAT_OFF"
77 : #define RPC_LONG_OFF "LONG_OFF"
78 : #define RPC_HEIGHT_OFF "HEIGHT_OFF"
79 : #define RPC_LINE_SCALE "LINE_SCALE"
80 : #define RPC_SAMP_SCALE "SAMP_SCALE"
81 : #define RPC_LAT_SCALE "LAT_SCALE"
82 : #define RPC_LONG_SCALE "LONG_SCALE"
83 : #define RPC_HEIGHT_SCALE "HEIGHT_SCALE"
84 : #define RPC_LINE_NUM_COEFF "LINE_NUM_COEFF"
85 : #define RPC_LINE_DEN_COEFF "LINE_DEN_COEFF"
86 : #define RPC_SAMP_NUM_COEFF "SAMP_NUM_COEFF"
87 : #define RPC_SAMP_DEN_COEFF "SAMP_DEN_COEFF"
88 :
89 : /* Optional */
90 : #define RPC_MIN_LONG "MIN_LONG"
91 : #define RPC_MIN_LAT "MIN_LAT"
92 : #define RPC_MAX_LONG "MAX_LONG"
93 : #define RPC_MAX_LAT "MAX_LAT"
94 :
95 : /* Pleiades Neo nomenclature */
96 : #define RPC_LAT_NUM_COEFF "LAT_NUM_COEFF"
97 : #define RPC_LAT_DEN_COEFF "LAT_DEN_COEFF"
98 : #define RPC_LON_NUM_COEFF "LON_NUM_COEFF"
99 : #define RPC_LON_DEN_COEFF "LON_DEN_COEFF"
100 :
101 : /**
102 : * Enumerator of metadata readers
103 : */
104 :
105 : typedef enum
106 : {
107 : MDR_None = 0x00000000, /**< no reader */
108 : MDR_DG = 0x00000001, /**< Digital Globe, METADATATYPE=DG */
109 : MDR_GE = 0x00000002, /**< Geo Eye, METADATATYPE=GE */
110 : MDR_OV = 0x00000004, /**< Orb View, METADATATYPE=OV */
111 : MDR_PLEIADES = 0x00000008, /**< Pleiades, METADATATYPE=DIMAP */
112 : MDR_SPOT = 0x00000010, /**< Spot, METADATATYPE=DIMAP */
113 : MDR_RDK1 = 0x00000020, /**< Resurs DK1, METADATATYPE=MSP */
114 : MDR_LS = 0x00000040, /**< Landsat, METADATATYPE=ODL */
115 : MDR_RE = 0x00000080, /**< RapidEye, METADATATYPE=RE */
116 : MDR_KOMPSAT = 0x00000100, /**< Kompsat, METADATATYPE=KARI */
117 : MDR_EROS = 0x00000200, /**< EROS, METADATATYPE=EROS */
118 : MDR_ALOS = 0x00000400, /**< ALOS, METADATATYPE=ALOS */
119 : MDR_ANY = MDR_DG | MDR_GE | MDR_OV | MDR_PLEIADES | MDR_SPOT | MDR_RDK1 |
120 : MDR_LS | MDR_RE | MDR_KOMPSAT | MDR_EROS |
121 : MDR_ALOS /**< any reader */
122 : } MDReaders;
123 :
124 : /**
125 : * The base class for all metadata readers
126 : */
127 : class CPL_DLL GDALMDReaderBase
128 : {
129 :
130 : CPL_DISALLOW_COPY_ASSIGN(GDALMDReaderBase)
131 :
132 : static bool
133 : ReadXMLToListFirstPass(const CPLXMLNode *psNode,
134 : std::map<std::string, int> &oMapCountKeysFull,
135 : const std::string &osPrefixFull, int nDepth);
136 :
137 : char **ReadXMLToList(const CPLXMLNode *psNode, char **papszList,
138 : const std::map<std::string, int> &oMapCountKeysFullRef,
139 : std::map<std::string, int> &oMapCountKeysFull,
140 : std::map<std::string, int> &oMapCountKeys,
141 : const std::string &osPrefix,
142 : const std::string &osPrefixFull);
143 :
144 : public:
145 : GDALMDReaderBase(const char *pszPath, CSLConstList papszSiblingFiles);
146 : virtual ~GDALMDReaderBase();
147 :
148 : /**
149 : * @brief Get specified metadata domain
150 : * @param pszDomain The metadata domain to return
151 : * @return List of metadata items
152 : */
153 : virtual char **GetMetadataDomain(const char *pszDomain);
154 : /**
155 : * @brief Fill provided metadata store class
156 : * @param poMDMD Metadata store class
157 : * @return true on success or false
158 : */
159 : virtual bool FillMetadata(GDALMultiDomainMetadata *poMDMD);
160 : /**
161 : * @brief Determine whether the input parameter correspond to the particular
162 : * provider of remote sensing data completely
163 : * @return True if all needed sources files found
164 : */
165 : virtual bool HasRequiredFiles() const = 0;
166 : /**
167 : * @brief Get metadata file names. The caller become owner of returned list
168 : * and have to free it via CSLDestroy.
169 : * @return A file name list
170 : */
171 : virtual char **GetMetadataFiles() const = 0;
172 :
173 : protected:
174 : /**
175 : * @brief Load metadata to the correspondent IMD, RPB, IMAGERY and DEFAULT
176 : * domains
177 : */
178 : virtual void LoadMetadata();
179 : /**
180 : * @brief Convert string like 2012-02-25T00:25:59.9440000Z to time
181 : * @param pszDateTime String to convert
182 : * @return value in second sinc epoch 1970-01-01 00:00:00
183 : */
184 : virtual GIntBig GetAcquisitionTimeFromString(const char *pszDateTime);
185 : /**
186 : * @brief ReadXMLToList Transform xml to list of NULL terminated name=value
187 : * strings
188 : * @param psNode A xml node to process
189 : * @param papszList A list to fill with name=value strings
190 : * @param pszName A name of parent node. For root xml node should be empty.
191 : * If name is not empty, the sibling nodes will not proceed
192 : * @return An input list filled with values
193 : */
194 : virtual char **ReadXMLToList(CPLXMLNode *psNode, char **papszList,
195 : const char *pszName = "");
196 : /**
197 : * @brief AddXMLNameValueToList Execute from ReadXMLToList to add name and
198 : * value to list. One can override this function for special
199 : * processing input values before add to list.
200 : * @param papszList A list to fill with name=value strings
201 : * @param pszName A name to add
202 : * @param pszValue A value to add
203 : * @return An input list filled with values
204 : */
205 : virtual char **AddXMLNameValueToList(char **papszList, const char *pszName,
206 : const char *pszValue);
207 :
208 : protected:
209 : //! @cond Doxygen_Suppress
210 : char **m_papszIMDMD = nullptr;
211 : char **m_papszRPCMD = nullptr;
212 : char **m_papszIMAGERYMD = nullptr;
213 : char **m_papszDEFAULTMD = nullptr;
214 : bool m_bIsMetadataLoad = false;
215 : //! @endcond
216 : };
217 :
218 : /**
219 : * The metadata reader main class.
220 : * The main purpose of this class is to provide an correspondent reader
221 : * for provided path.
222 : */
223 6066 : class CPL_DLL GDALMDReaderManager
224 : {
225 :
226 : CPL_DISALLOW_COPY_ASSIGN(GDALMDReaderManager)
227 :
228 : public:
229 : GDALMDReaderManager();
230 : virtual ~GDALMDReaderManager();
231 :
232 : /**
233 : * @brief Try to detect metadata reader correspondent to the provided
234 : * datasource path
235 : * @param pszPath a path to GDALDataset
236 : * @param papszSiblingFiles file list for metadata search purposes
237 : * @param nType a preferable reader type (may be the OR of MDReaders)
238 : * @return an appropriate reader or NULL if no such reader or error.
239 : * The pointer delete by the GDALMDReaderManager, so the user have not
240 : * delete it.
241 : */
242 : virtual GDALMDReaderBase *GetReader(const char *pszPath,
243 : CSLConstList papszSiblingFiles,
244 : GUInt32 nType = MDR_ANY);
245 :
246 : protected:
247 : //! @cond Doxygen_Suppress
248 : GDALMDReaderBase *m_pReader = nullptr;
249 : //! @endcond
250 : };
251 :
252 : // misc
253 : CPLString CPLStrip(const CPLString &osString, const char cChar);
254 : CPLString CPLStripQuotes(const CPLString &osString);
255 : char **GDALLoadRPBFile(const CPLString &osFilePath);
256 : char CPL_DLL **GDALLoadRPCFile(const CPLString &osFilePath);
257 : char **GDALLoadIMDFile(const CPLString &osFilePath);
258 : bool GDALCheckFileHeader(const CPLString &soFilePath, const char *pszTestString,
259 : int nBufferSize = 256);
260 :
261 : CPLErr GDALWriteRPBFile(const char *pszFilename, CSLConstList papszMD);
262 : CPLErr CPL_DLL GDALWriteRPCTXTFile(const char *pszFilename,
263 : CSLConstList papszMD);
264 : CPLErr GDALWriteIMDFile(const char *pszFilename, CSLConstList papszMD);
265 :
266 : #endif // GDAL_MDREADER_H_INCLUDED
|