Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Read metadata from EROS 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_eros.h"
16 :
17 : #include <cstddef>
18 : #include <cstdio>
19 : #include <cstdlib>
20 :
21 : #include "cpl_conv.h"
22 : #include "cpl_error.h"
23 : #include "cpl_string.h"
24 : #include "cpl_time.h"
25 :
26 : /**
27 : * GDALMDReaderEROS()
28 : */
29 5080 : GDALMDReaderEROS::GDALMDReaderEROS(const char *pszPath,
30 5080 : char **papszSiblingFiles)
31 5080 : : GDALMDReaderBase(pszPath, papszSiblingFiles)
32 : {
33 5080 : CPLString osBaseName = CPLGetBasename(pszPath);
34 5080 : CPLString osDirName = CPLGetDirname(pszPath);
35 5080 : char szMetadataName[512] = {0};
36 : size_t i;
37 5080 : if (osBaseName.size() > 511)
38 0 : return;
39 58220 : for (i = 0; i < osBaseName.size(); i++)
40 : {
41 53140 : if (STARTS_WITH_CI(osBaseName + i, "."))
42 : {
43 : std::string osPassFileName =
44 109 : CPLFormFilename(osDirName, szMetadataName, "pass");
45 109 : if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
46 : {
47 0 : m_osIMDSourceFilename = std::move(osPassFileName);
48 0 : break;
49 : }
50 : else
51 : {
52 : osPassFileName =
53 109 : CPLFormFilename(osDirName, szMetadataName, "PASS");
54 109 : if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
55 : {
56 0 : m_osIMDSourceFilename = std::move(osPassFileName);
57 0 : break;
58 : }
59 : }
60 : }
61 53140 : szMetadataName[i] = osBaseName[i];
62 : }
63 :
64 5080 : if (m_osIMDSourceFilename.empty())
65 : {
66 : std::string osPassFileName =
67 10160 : CPLFormFilename(osDirName, szMetadataName, "pass");
68 5080 : if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
69 : {
70 1 : m_osIMDSourceFilename = std::move(osPassFileName);
71 : }
72 : else
73 : {
74 5079 : osPassFileName = CPLFormFilename(osDirName, szMetadataName, "PASS");
75 5079 : if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
76 : {
77 0 : m_osIMDSourceFilename = std::move(osPassFileName);
78 : }
79 : }
80 : }
81 :
82 : std::string osRPCFileName =
83 10160 : CPLFormFilename(osDirName, szMetadataName, "rpc");
84 5080 : if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
85 : {
86 1 : m_osRPBSourceFilename = std::move(osRPCFileName);
87 : }
88 : else
89 : {
90 5079 : osRPCFileName = CPLFormFilename(osDirName, szMetadataName, "RPC");
91 5079 : if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
92 : {
93 0 : m_osRPBSourceFilename = std::move(osRPCFileName);
94 : }
95 : }
96 :
97 5080 : if (!m_osIMDSourceFilename.empty())
98 1 : CPLDebug("MDReaderEROS", "IMD Filename: %s",
99 : m_osIMDSourceFilename.c_str());
100 5080 : if (!m_osRPBSourceFilename.empty())
101 1 : CPLDebug("MDReaderEROS", "RPB Filename: %s",
102 : m_osRPBSourceFilename.c_str());
103 : }
104 :
105 : /**
106 : * ~GDALMDReaderEROS()
107 : */
108 10160 : GDALMDReaderEROS::~GDALMDReaderEROS()
109 : {
110 10160 : }
111 :
112 : /**
113 : * HasRequiredFiles()
114 : */
115 5080 : bool GDALMDReaderEROS::HasRequiredFiles() const
116 : {
117 5080 : if (!m_osIMDSourceFilename.empty())
118 1 : return true;
119 5079 : if (!m_osRPBSourceFilename.empty())
120 0 : return true;
121 :
122 5079 : return false;
123 : }
124 :
125 : /**
126 : * GetMetadataFiles()
127 : */
128 1 : char **GDALMDReaderEROS::GetMetadataFiles() const
129 : {
130 1 : char **papszFileList = nullptr;
131 1 : if (!m_osIMDSourceFilename.empty())
132 1 : papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
133 1 : if (!m_osRPBSourceFilename.empty())
134 1 : papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
135 1 : return papszFileList;
136 : }
137 :
138 : /**
139 : * LoadMetadata()
140 : */
141 2 : void GDALMDReaderEROS::LoadMetadata()
142 : {
143 2 : if (m_bIsMetadataLoad)
144 1 : return;
145 :
146 1 : if (!m_osIMDSourceFilename.empty())
147 : {
148 1 : m_papszIMDMD = LoadImdTxtFile();
149 : }
150 :
151 1 : if (!m_osRPBSourceFilename.empty())
152 : {
153 1 : m_papszRPCMD = GDALLoadRPCFile(m_osRPBSourceFilename);
154 : }
155 :
156 1 : m_papszDEFAULTMD =
157 1 : CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "EROS");
158 :
159 1 : m_bIsMetadataLoad = true;
160 :
161 1 : const char *pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "satellite");
162 1 : const char *pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "camera");
163 1 : if (nullptr != pszSatId1 && nullptr != pszSatId2)
164 : {
165 2 : m_papszIMAGERYMD = CSLAddNameValue(
166 : m_papszIMAGERYMD, MD_NAME_SATELLITE,
167 2 : CPLSPrintf("%s %s", CPLStripQuotes(pszSatId1).c_str(),
168 2 : CPLStripQuotes(pszSatId2).c_str()));
169 : }
170 0 : else if (nullptr != pszSatId1 && nullptr == pszSatId2)
171 : {
172 0 : m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
173 0 : CPLStripQuotes(pszSatId1));
174 : }
175 0 : else if (nullptr == pszSatId1 && nullptr != pszSatId2)
176 : {
177 0 : m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
178 0 : CPLStripQuotes(pszSatId2));
179 : }
180 :
181 1 : const char *pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "overall_cc");
182 1 : if (nullptr != pszCloudCover)
183 : {
184 1 : int nCC = atoi(pszCloudCover);
185 1 : if (nCC > 100 || nCC < 0)
186 : {
187 0 : m_papszIMAGERYMD = CSLAddNameValue(
188 : m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
189 : }
190 : else
191 : {
192 1 : m_papszIMAGERYMD = CSLAddNameValue(
193 : m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", nCC));
194 : }
195 : }
196 :
197 1 : const char *pszDate = CSLFetchNameValue(m_papszIMDMD, "sweep_start_utc");
198 1 : if (nullptr != pszDate)
199 : {
200 : char buffer[80];
201 1 : GIntBig timeMid = GetAcquisitionTimeFromString(CPLStripQuotes(pszDate));
202 : struct tm tmBuf;
203 1 : strftime(buffer, 80, MD_DATETIMEFORMAT,
204 1 : CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
205 1 : m_papszIMAGERYMD =
206 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
207 : }
208 : }
209 :
210 : /**
211 : * LoadImdTxtFile
212 : */
213 1 : char **GDALMDReaderEROS::LoadImdTxtFile()
214 : {
215 1 : char **papszLines = CSLLoad(m_osIMDSourceFilename);
216 1 : if (nullptr == papszLines)
217 0 : return nullptr;
218 :
219 1 : char **papszIMD = nullptr;
220 :
221 10 : for (int i = 0; papszLines[i] != nullptr; i++)
222 : {
223 9 : const char *pszLine = papszLines[i];
224 9 : if (CPLStrnlen(pszLine, 21) >= 21)
225 : {
226 : char szName[22];
227 9 : memcpy(szName, pszLine, 21);
228 9 : szName[21] = 0;
229 9 : char *pszSpace = strchr(szName, ' ');
230 9 : if (pszSpace)
231 : {
232 9 : *pszSpace = 0;
233 9 : papszIMD = CSLAddNameValue(papszIMD, szName, pszLine + 20);
234 : }
235 : }
236 : }
237 :
238 1 : CSLDestroy(papszLines);
239 :
240 1 : return papszIMD;
241 : }
242 :
243 : /**
244 : * GetAcqisitionTimeFromString()
245 : */
246 1 : GIntBig GDALMDReaderEROS::GetAcquisitionTimeFromString(const char *pszDateTime)
247 : {
248 1 : if (nullptr == pszDateTime)
249 0 : return 0;
250 :
251 : int iYear;
252 : int iMonth;
253 : int iDay;
254 : int iHours;
255 : int iMin;
256 : int iSec;
257 :
258 : // example: sweep_start_utc 2013-04-22,11:35:02.50724
259 :
260 1 : int r = sscanf(pszDateTime, "%d-%d-%d,%d:%d:%d.%*d", &iYear, &iMonth, &iDay,
261 : &iHours, &iMin, &iSec);
262 :
263 1 : if (r != 6)
264 0 : return 0;
265 :
266 : struct tm tmDateTime;
267 1 : tmDateTime.tm_sec = iSec;
268 1 : tmDateTime.tm_min = iMin;
269 1 : tmDateTime.tm_hour = iHours;
270 1 : tmDateTime.tm_mday = iDay;
271 1 : tmDateTime.tm_mon = iMonth - 1;
272 1 : tmDateTime.tm_year = iYear - 1900;
273 1 : tmDateTime.tm_isdst = -1;
274 :
275 1 : return CPLYMDHMSToUnixTime(&tmDateTime);
276 : }
|