Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Read metadata from Resurs-DK1 imagery.
5 : * Author: Alexander Lisovenko
6 : * Author: Dmitry Baryshnikov, polimax@mail.ru
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2014-2015 NextGIS <info@nextgis.ru>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "cpl_port.h"
31 : #include "reader_rdk1.h"
32 :
33 : #include <cstdio>
34 :
35 : #include "cpl_error.h"
36 : #include "cpl_minixml.h"
37 : #include "cpl_string.h"
38 : #include "cpl_time.h"
39 :
40 : #include "gdal_priv.h"
41 :
42 : /**
43 : * GDALMDReaderResursDK1()
44 : */
45 5030 : GDALMDReaderResursDK1::GDALMDReaderResursDK1(const char *pszPath,
46 5030 : char **papszSiblingFiles)
47 : : GDALMDReaderBase(pszPath, papszSiblingFiles),
48 : m_osXMLSourceFilename(
49 5030 : GDALFindAssociatedFile(pszPath, "XML", papszSiblingFiles, 0))
50 : {
51 5030 : if (!m_osXMLSourceFilename.empty())
52 7 : CPLDebug("MDReaderResursDK1", "XML Filename: %s",
53 : m_osXMLSourceFilename.c_str());
54 5030 : }
55 :
56 : /**
57 : * ~GDALMDReaderResursDK1()
58 : */
59 10060 : GDALMDReaderResursDK1::~GDALMDReaderResursDK1()
60 : {
61 10060 : }
62 :
63 : /**
64 : * HasRequiredFiles()
65 : */
66 5030 : bool GDALMDReaderResursDK1::HasRequiredFiles() const
67 : {
68 : // check <MSP_ROOT>
69 5037 : if (!m_osXMLSourceFilename.empty() &&
70 7 : GDALCheckFileHeader(m_osXMLSourceFilename, "<MSP_ROOT>"))
71 1 : return true;
72 :
73 5029 : return false;
74 : }
75 :
76 : /**
77 : * GetMetadataFiles()
78 : */
79 1 : char **GDALMDReaderResursDK1::GetMetadataFiles() const
80 : {
81 1 : char **papszFileList = nullptr;
82 1 : if (!m_osXMLSourceFilename.empty())
83 1 : papszFileList = CSLAddString(papszFileList, m_osXMLSourceFilename);
84 :
85 1 : return papszFileList;
86 : }
87 :
88 : /**
89 : * LoadMetadata()
90 : */
91 2 : void GDALMDReaderResursDK1::LoadMetadata()
92 : {
93 2 : if (m_bIsMetadataLoad)
94 1 : return;
95 :
96 1 : if (!m_osXMLSourceFilename.empty())
97 : {
98 1 : CPLXMLNode *psNode = CPLParseXMLFile(m_osXMLSourceFilename);
99 :
100 1 : if (psNode != nullptr)
101 : {
102 1 : CPLXMLNode *pMSPRootNode = CPLSearchXMLNode(psNode, "=MSP_ROOT");
103 :
104 1 : if (pMSPRootNode != nullptr)
105 : {
106 1 : m_papszIMDMD =
107 1 : ReadXMLToList(pMSPRootNode, m_papszIMDMD, "MSP_ROOT");
108 : }
109 1 : CPLDestroyXMLNode(psNode);
110 : }
111 : }
112 :
113 1 : m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "MSP");
114 :
115 1 : m_bIsMetadataLoad = true;
116 :
117 1 : if (nullptr == m_papszIMDMD)
118 : {
119 0 : return;
120 : }
121 :
122 : // extract imagery metadata
123 1 : const char *pszSatId = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.cCodeKA");
124 1 : if (nullptr != pszSatId)
125 : {
126 1 : m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
127 2 : CPLStripQuotes(pszSatId));
128 : }
129 :
130 : const char *pszDate =
131 1 : CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.dSceneDate");
132 :
133 1 : if (nullptr != pszDate)
134 : {
135 : const char *pszTime =
136 1 : CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.tSceneTime");
137 1 : if (nullptr == pszTime)
138 0 : pszTime = "00:00:00.000000";
139 :
140 : char buffer[80];
141 : GIntBig timeMid =
142 1 : GetAcquisitionTimeFromString(CPLSPrintf("%s %s", pszDate, pszTime));
143 : struct tm tmBuf;
144 1 : strftime(buffer, 80, MD_DATETIMEFORMAT,
145 1 : CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
146 1 : m_papszIMAGERYMD =
147 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
148 : }
149 :
150 1 : m_papszIMAGERYMD =
151 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
152 : }
153 :
154 : /**
155 : * GetAcqisitionTimeFromString()
156 : */
157 : GIntBig
158 1 : GDALMDReaderResursDK1::GetAcquisitionTimeFromString(const char *pszDateTime)
159 : {
160 1 : if (nullptr == pszDateTime)
161 0 : return 0;
162 :
163 : int iYear;
164 : int iMonth;
165 : int iDay;
166 : int iHours;
167 : int iMin;
168 : int iSec;
169 :
170 : // string example <Normal>
171 : // tSceneTime = 10:21:36.000000
172 : // dSceneDate = 16/9/2008
173 : // </Normal>
174 :
175 1 : int r = sscanf(pszDateTime, "%d/%d/%d %d:%d:%d.%*s", &iDay, &iMonth, &iYear,
176 : &iHours, &iMin, &iSec);
177 :
178 1 : if (r != 6)
179 0 : return 0;
180 :
181 : struct tm tmDateTime;
182 1 : tmDateTime.tm_sec = iSec;
183 1 : tmDateTime.tm_min = iMin;
184 1 : tmDateTime.tm_hour = iHours;
185 1 : tmDateTime.tm_mday = iDay;
186 1 : tmDateTime.tm_mon = iMonth - 1;
187 1 : tmDateTime.tm_year = iYear - 1900;
188 1 : tmDateTime.tm_isdst = -1;
189 :
190 1 : return CPLYMDHMSToUnixTime(&tmDateTime) - 10800; // int UTC+3 MSK
191 : }
192 :
193 4 : char **GDALMDReaderResursDK1::AddXMLNameValueToList(char **papszList,
194 : const char *pszName,
195 : const char *pszValue)
196 : {
197 4 : char **papszTokens = CSLTokenizeString2(
198 : pszValue, "\n", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
199 :
200 34 : for (int i = 0; papszTokens[i] != nullptr; i++)
201 : {
202 :
203 60 : char **papszSubTokens = CSLTokenizeString2(
204 30 : papszTokens[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
205 30 : if (CSLCount(papszSubTokens) < 2)
206 : {
207 0 : CSLDestroy(papszSubTokens);
208 0 : continue;
209 : }
210 :
211 30 : papszList = CSLAddNameValue(
212 : papszList, CPLSPrintf("%s.%s", pszName, papszSubTokens[0]),
213 30 : papszSubTokens[1]);
214 30 : CSLDestroy(papszSubTokens);
215 : }
216 :
217 4 : CSLDestroy(papszTokens);
218 :
219 4 : return papszList;
220 : }
|