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 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "cpl_port.h"
15 : #include "reader_rdk1.h"
16 :
17 : #include <cstdio>
18 :
19 : #include "cpl_error.h"
20 : #include "cpl_minixml.h"
21 : #include "cpl_string.h"
22 : #include "cpl_time.h"
23 :
24 : #include "gdal_priv.h"
25 :
26 : /**
27 : * GDALMDReaderResursDK1()
28 : */
29 5084 : GDALMDReaderResursDK1::GDALMDReaderResursDK1(const char *pszPath,
30 5084 : char **papszSiblingFiles)
31 : : GDALMDReaderBase(pszPath, papszSiblingFiles),
32 : m_osXMLSourceFilename(
33 5084 : GDALFindAssociatedFile(pszPath, "XML", papszSiblingFiles, 0))
34 : {
35 5084 : if (!m_osXMLSourceFilename.empty())
36 7 : CPLDebug("MDReaderResursDK1", "XML Filename: %s",
37 : m_osXMLSourceFilename.c_str());
38 5084 : }
39 :
40 : /**
41 : * ~GDALMDReaderResursDK1()
42 : */
43 10168 : GDALMDReaderResursDK1::~GDALMDReaderResursDK1()
44 : {
45 10168 : }
46 :
47 : /**
48 : * HasRequiredFiles()
49 : */
50 5084 : bool GDALMDReaderResursDK1::HasRequiredFiles() const
51 : {
52 : // check <MSP_ROOT>
53 5091 : if (!m_osXMLSourceFilename.empty() &&
54 7 : GDALCheckFileHeader(m_osXMLSourceFilename, "<MSP_ROOT>"))
55 1 : return true;
56 :
57 5083 : return false;
58 : }
59 :
60 : /**
61 : * GetMetadataFiles()
62 : */
63 1 : char **GDALMDReaderResursDK1::GetMetadataFiles() const
64 : {
65 1 : char **papszFileList = nullptr;
66 1 : if (!m_osXMLSourceFilename.empty())
67 1 : papszFileList = CSLAddString(papszFileList, m_osXMLSourceFilename);
68 :
69 1 : return papszFileList;
70 : }
71 :
72 : /**
73 : * LoadMetadata()
74 : */
75 2 : void GDALMDReaderResursDK1::LoadMetadata()
76 : {
77 2 : if (m_bIsMetadataLoad)
78 1 : return;
79 :
80 1 : if (!m_osXMLSourceFilename.empty())
81 : {
82 1 : CPLXMLNode *psNode = CPLParseXMLFile(m_osXMLSourceFilename);
83 :
84 1 : if (psNode != nullptr)
85 : {
86 1 : CPLXMLNode *pMSPRootNode = CPLSearchXMLNode(psNode, "=MSP_ROOT");
87 :
88 1 : if (pMSPRootNode != nullptr)
89 : {
90 1 : m_papszIMDMD =
91 1 : ReadXMLToList(pMSPRootNode, m_papszIMDMD, "MSP_ROOT");
92 : }
93 1 : CPLDestroyXMLNode(psNode);
94 : }
95 : }
96 :
97 1 : m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "MSP");
98 :
99 1 : m_bIsMetadataLoad = true;
100 :
101 1 : if (nullptr == m_papszIMDMD)
102 : {
103 0 : return;
104 : }
105 :
106 : // extract imagery metadata
107 1 : const char *pszSatId = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.cCodeKA");
108 1 : if (nullptr != pszSatId)
109 : {
110 1 : m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
111 2 : CPLStripQuotes(pszSatId));
112 : }
113 :
114 : const char *pszDate =
115 1 : CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.dSceneDate");
116 :
117 1 : if (nullptr != pszDate)
118 : {
119 : const char *pszTime =
120 1 : CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.tSceneTime");
121 1 : if (nullptr == pszTime)
122 0 : pszTime = "00:00:00.000000";
123 :
124 : char buffer[80];
125 : GIntBig timeMid =
126 1 : GetAcquisitionTimeFromString(CPLSPrintf("%s %s", pszDate, pszTime));
127 : struct tm tmBuf;
128 1 : strftime(buffer, 80, MD_DATETIMEFORMAT,
129 1 : CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
130 1 : m_papszIMAGERYMD =
131 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
132 : }
133 :
134 1 : m_papszIMAGERYMD =
135 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
136 : }
137 :
138 : /**
139 : * GetAcqisitionTimeFromString()
140 : */
141 : GIntBig
142 1 : GDALMDReaderResursDK1::GetAcquisitionTimeFromString(const char *pszDateTime)
143 : {
144 1 : if (nullptr == pszDateTime)
145 0 : return 0;
146 :
147 : int iYear;
148 : int iMonth;
149 : int iDay;
150 : int iHours;
151 : int iMin;
152 : int iSec;
153 :
154 : // string example <Normal>
155 : // tSceneTime = 10:21:36.000000
156 : // dSceneDate = 16/9/2008
157 : // </Normal>
158 :
159 1 : int r = sscanf(pszDateTime, "%d/%d/%d %d:%d:%d.%*s", &iDay, &iMonth, &iYear,
160 : &iHours, &iMin, &iSec);
161 :
162 1 : if (r != 6)
163 0 : return 0;
164 :
165 : struct tm tmDateTime;
166 1 : tmDateTime.tm_sec = iSec;
167 1 : tmDateTime.tm_min = iMin;
168 1 : tmDateTime.tm_hour = iHours;
169 1 : tmDateTime.tm_mday = iDay;
170 1 : tmDateTime.tm_mon = iMonth - 1;
171 1 : tmDateTime.tm_year = iYear - 1900;
172 1 : tmDateTime.tm_isdst = -1;
173 :
174 1 : return CPLYMDHMSToUnixTime(&tmDateTime) - 10800; // int UTC+3 MSK
175 : }
176 :
177 4 : char **GDALMDReaderResursDK1::AddXMLNameValueToList(char **papszList,
178 : const char *pszName,
179 : const char *pszValue)
180 : {
181 4 : char **papszTokens = CSLTokenizeString2(
182 : pszValue, "\n", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
183 :
184 34 : for (int i = 0; papszTokens[i] != nullptr; i++)
185 : {
186 :
187 60 : char **papszSubTokens = CSLTokenizeString2(
188 30 : papszTokens[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES);
189 30 : if (CSLCount(papszSubTokens) < 2)
190 : {
191 0 : CSLDestroy(papszSubTokens);
192 0 : continue;
193 : }
194 :
195 30 : papszList = CSLAddNameValue(
196 : papszList, CPLSPrintf("%s.%s", pszName, papszSubTokens[0]),
197 30 : papszSubTokens[1]);
198 30 : CSLDestroy(papszSubTokens);
199 : }
200 :
201 4 : CSLDestroy(papszTokens);
202 :
203 4 : return papszList;
204 : }
|