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