1 /******************************************************************************
2  * $Id: gdal_mdreader.h 29190 2015-05-13 21:40:30Z bishop $
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  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef GDAL_MDREADER_H_INCLUDED
32 #define GDAL_MDREADER_H_INCLUDED
33 
34 
35 #include "cpl_port.h"
36 #include "gdal_priv.h"
37 
38 #define MD_DOMAIN_IMD "IMD"              /**< image metadata section */
39 #define MD_DOMAIN_RPC "RPC"              /**< rpc metadata section */
40 #define MD_DOMAIN_IMAGERY "IMAGERY"      /**< imagery metadata section */
41 #define MD_DOMAIN_DEFAULT ""             /**< default metadata section */
42 
43 #define MD_NAME_ACQDATETIME "ACQUISITIONDATETIME"  /**< Acquisition Date Time property name. The time should be in UTC */
44 #define MD_NAME_SATELLITE   "SATELLITEID"          /**< Satellite identificator property name */
45 #define MD_NAME_CLOUDCOVER  "CLOUDCOVER"           /**< Cloud coverage property name. The value between 0 - 100 or 999 if n/a */
46 #define MD_NAME_MDTYPE      "METADATATYPE"         /**< Metadata reader type property name. The reader processed this metadata */
47 
48 #define MD_DATETIMEFORMAT "%Y-%m-%d %H:%M:%S"      /**< Date time format */
49 #define MD_CLOUDCOVER_NA "999"           /**< The value if cloud cover is n/a */
50 
51 /**
52  * RPC/RPB specific defines
53  */
54 
55 #define RPC_LINE_OFF        "LINE_OFF"
56 #define RPC_SAMP_OFF        "SAMP_OFF"
57 #define RPC_LAT_OFF         "LAT_OFF"
58 #define RPC_LONG_OFF        "LONG_OFF"
59 #define RPC_HEIGHT_OFF      "HEIGHT_OFF"
60 #define RPC_LINE_SCALE      "LINE_SCALE"
61 #define RPC_SAMP_SCALE      "SAMP_SCALE"
62 #define RPC_LAT_SCALE       "LAT_SCALE"
63 #define RPC_LONG_SCALE      "LONG_SCALE"
64 #define RPC_HEIGHT_SCALE    "HEIGHT_SCALE"
65 #define RPC_LINE_NUM_COEFF  "LINE_NUM_COEFF"
66 #define RPC_LINE_DEN_COEFF  "LINE_DEN_COEFF"
67 #define RPC_SAMP_NUM_COEFF  "SAMP_NUM_COEFF"
68 #define RPC_SAMP_DEN_COEFF  "SAMP_DEN_COEFF"
69 
70 /**
71  * Enumerator of metadata readers
72  */
73 
74 typedef enum {
75     MDR_None     = 0x00000000,    /**< no reader */
76     MDR_DG       = 0x00000001,    /**< Digital Globe, METADATATYPE=DG */
77     MDR_GE       = 0x00000002,    /**< Geo Eye,       METADATATYPE=GE */
78     MDR_OV       = 0x00000004,    /**< Orb View,      METADATATYPE=OV */
79     MDR_PLEIADES = 0x00000008,    /**< Pleiades,      METADATATYPE=DIMAP */
80     MDR_SPOT     = 0x00000010,    /**< Spot,          METADATATYPE=DIMAP */
81     MDR_RDK1     = 0x00000020,    /**< Resurs DK1,    METADATATYPE=MSP */
82     MDR_LS       = 0x00000040,    /**< Landsat,       METADATATYPE=ODL */
83     MDR_RE       = 0x00000080,    /**< RapidEye,      METADATATYPE=RE */
84     MDR_KOMPSAT  = 0x00000100,    /**< Kompsat,       METADATATYPE=KARI */
85     MDR_EROS     = 0x00000200,    /**< EROS,          METADATATYPE=EROS */
86     MDR_ALOS     = 0x00000400,    /**< ALOS,          METADATATYPE=ALOS */
87     MDR_ANY  = MDR_DG | MDR_GE | MDR_OV | MDR_PLEIADES | MDR_SPOT | MDR_RDK1 |
88                MDR_LS | MDR_RE | MDR_KOMPSAT | MDR_EROS | MDR_ALOS /**< any reader */
89 } MDReaders;
90 
91 
92 /**
93  * The base class for all metadata readers
94  */
95 class GDALMDReaderBase{
96 public:
97     GDALMDReaderBase(const char *pszPath, char **papszSiblingFiles);
98     virtual ~GDALMDReaderBase();
99 
100     /**
101      * @brief Get specified metadata domain
102      * @param pszDomain The metadata domain to return
103      * @return List of metadata items
104      */
105     virtual char ** GetMetadataDomain(const char *pszDomain);
106     /**
107      * @brief Fill provided metatada store class
108      * @param poMDMD Metatada store class
109      * @return true on success or false
110      */
111     virtual bool FillMetadata(GDALMultiDomainMetadata* poMDMD);
112     /**
113       * @brief Determine whether the input parameter correspond to the particular
114       *        provider of remote sensing data completely
115       * @return True if all needed sources files found
116       */
117     virtual const bool HasRequiredFiles() const = 0;
118     /**
119      * @brief Get metadata file names. The caller become owner of returned list
120      *        and have to free it via CSLDestroy.
121      * @return A file name list
122      */
123     virtual char** GetMetadataFiles() const = 0;
124 protected:
125     /**
126      * @brief Load metadata to the correspondent IMD, RPB, IMAGERY and DEFAULT
127      *        domains
128      */
129     virtual void LoadMetadata();
130     /**
131      * @brief Convert string like 2012-02-25T00:25:59.9440000Z to time
132      * @param pszDateTime String to convert
133      * @return value in time_t
134      */
135     virtual const time_t GetAcquisitionTimeFromString(const char* pszDateTime);
136     /**
137      * @brief ReadXMLToList Transform xml to list of NULL terminated name=value
138      *        strings
139      * @param psNode A xml node to process
140      * @param papszList A list to fill with name=value strings
141      * @param pszName A name of parent node. For root xml node should be empty.
142      *        If name is not empty, the sibling nodes will not proceed
143      * @return An input list filled with values
144      */
145     virtual char** ReadXMLToList(CPLXMLNode* psNode, char** papszList,
146                          const char* pszName = "");
147     /**
148      * @brief AddXMLNameValueToList Execute from ReadXMLToList to add name and
149      *        value to list. One can override this function for special
150      *        processing input values before add to list.
151      * @param papszList A list to fill with name=value strings
152      * @param pszName A name to add
153      * @param pszValue A value to add
154      * @return An input list filled with values
155      */
156     virtual char** AddXMLNameValueToList(char** papszList, const char *pszName,
157                                          const char *pszValue);
158 protected:
159     char **m_papszIMDMD;
160     char **m_papszRPCMD;
161     char **m_papszIMAGERYMD;
162     char **m_papszDEFAULTMD;
163     bool m_bIsMetadataLoad;
164 };
165 
166 /**
167  * The metadata reader main class.
168  * The main purpose of this class is to provide an correspondent reader
169  * for provided path.
170  */
171 class CPL_DLL GDALMDReaderManager{
172 public:
173     GDALMDReaderManager();
174     virtual ~GDALMDReaderManager();
175 
176     /**
177      * @brief Try to detect metadata reader correspondent to the provided
178      *        datasource path
179      * @param pszPath a path to GDALDataset
180      * @param papszSiblingFiles file list for metadata search purposes
181      * @param nType a preferable reader type (may be the OR of MDReaders)
182      * @return an appropriate reader or NULL if no such reader or error.
183      * The pointer delete by the GDALMDReaderManager, so the user have not
184      * delete it.
185      */
186     virtual GDALMDReaderBase* GetReader(const char *pszPath,
187                                         char **papszSiblingFiles,
188                                         GUInt32 nType = MDR_ANY);
189 protected:
190     GDALMDReaderBase *m_pReader;
191 };
192 
193 // misc
194 CPLString CPLStrip(const CPLString& osString, const char cChar);
195 CPLString CPLStripQuotes(const CPLString& osString);
196 char** GDALLoadRPBFile( const CPLString& osFilePath );
197 char** GDALLoadRPCFile( const CPLString& osFilePath );
198 char** GDALLoadIMDFile( const CPLString& osFilePath );
199 const bool GDALCheckFileHeader(const CPLString& soFilePath,
200                                const char * pszTestString,
201                                int nBufferSize = 256);
202 
203 CPLErr GDALWriteRPBFile( const char *pszFilename, char **papszMD );
204 CPLErr GDALWriteRPCTXTFile( const char *pszFilename, char **papszMD );
205 CPLErr GDALWriteIMDFile( const char *pszFilename, char **papszMD );
206 
207 #endif //GDAL_MDREADER_H_INCLUDED
208