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