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