Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL Core
4 : * Purpose: Read metadata from Landsat 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_landsat.h"
32 :
33 : #include <cstddef>
34 : #include <cstring>
35 : #include <ctime>
36 :
37 : #include "cpl_conv.h"
38 : #include "cpl_error.h"
39 : #include "cpl_string.h"
40 : #include "cpl_time.h"
41 :
42 : /**
43 : * GDALMDReaderLandsat()
44 : */
45 5046 : GDALMDReaderLandsat::GDALMDReaderLandsat(const char *pszPath,
46 5046 : char **papszSiblingFiles)
47 5046 : : GDALMDReaderBase(pszPath, papszSiblingFiles)
48 : {
49 5046 : const char *pszBaseName = CPLGetBasename(pszPath);
50 5046 : const char *pszDirName = CPLGetDirname(pszPath);
51 5046 : size_t nBaseNameLen = strlen(pszBaseName);
52 5046 : if (nBaseNameLen > 511)
53 0 : return;
54 :
55 : // split file name by _B or _b
56 5046 : char szMetadataName[512] = {0};
57 : size_t i;
58 55664 : for (i = 0; i < nBaseNameLen; i++)
59 : {
60 50830 : szMetadataName[i] = pszBaseName[i];
61 50830 : if (STARTS_WITH_CI(pszBaseName + i, "_B") ||
62 50618 : STARTS_WITH_CI(pszBaseName + i, "_b"))
63 : {
64 : break;
65 : }
66 : }
67 :
68 : // form metadata file name
69 5046 : CPLStrlcpy(szMetadataName + i, "_MTL.txt", 9);
70 :
71 : std::string osIMDSourceFilename =
72 10092 : CPLFormFilename(pszDirName, szMetadataName, nullptr);
73 5046 : if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
74 : {
75 1 : m_osIMDSourceFilename = std::move(osIMDSourceFilename);
76 : }
77 : else
78 : {
79 5045 : CPLStrlcpy(szMetadataName + i, "_MTL.TXT", 9);
80 : osIMDSourceFilename =
81 5045 : CPLFormFilename(pszDirName, szMetadataName, nullptr);
82 5045 : if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
83 : {
84 0 : m_osIMDSourceFilename = std::move(osIMDSourceFilename);
85 : }
86 : }
87 :
88 5046 : if (!m_osIMDSourceFilename.empty())
89 1 : CPLDebug("MDReaderLandsat", "IMD Filename: %s",
90 : m_osIMDSourceFilename.c_str());
91 : }
92 :
93 : /**
94 : * ~GDALMDReaderLandsat()
95 : */
96 10092 : GDALMDReaderLandsat::~GDALMDReaderLandsat()
97 : {
98 10092 : }
99 :
100 : /**
101 : * HasRequiredFiles()
102 : */
103 5046 : bool GDALMDReaderLandsat::HasRequiredFiles() const
104 : {
105 5046 : if (!m_osIMDSourceFilename.empty())
106 1 : return true;
107 :
108 5045 : return false;
109 : }
110 :
111 : /**
112 : * GetMetadataFiles()
113 : */
114 1 : char **GDALMDReaderLandsat::GetMetadataFiles() const
115 : {
116 1 : char **papszFileList = nullptr;
117 1 : if (!m_osIMDSourceFilename.empty())
118 1 : papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
119 :
120 1 : return papszFileList;
121 : }
122 :
123 : /**
124 : * LoadMetadata()
125 : */
126 2 : void GDALMDReaderLandsat::LoadMetadata()
127 : {
128 2 : if (m_bIsMetadataLoad)
129 1 : return;
130 :
131 1 : if (!m_osIMDSourceFilename.empty())
132 : {
133 1 : m_papszIMDMD = GDALLoadIMDFile(m_osIMDSourceFilename);
134 : }
135 :
136 1 : m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ODL");
137 :
138 1 : m_bIsMetadataLoad = true;
139 :
140 : // date/time
141 : // DATE_ACQUIRED = 2013-04-07
142 : // SCENE_CENTER_TIME = 15:47:03.0882620Z
143 :
144 : // L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID
145 2 : const char *pszSatId = CSLFetchNameValue(
146 1 : m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID");
147 1 : if (nullptr != pszSatId)
148 : {
149 1 : m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
150 2 : CPLStripQuotes(pszSatId));
151 : }
152 :
153 : // L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER
154 2 : const char *pszCloudCover = CSLFetchNameValue(
155 1 : m_papszIMDMD, "L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER");
156 1 : if (nullptr != pszCloudCover)
157 : {
158 1 : double fCC = CPLAtofM(pszCloudCover);
159 1 : if (fCC < 0)
160 : {
161 0 : m_papszIMAGERYMD = CSLAddNameValue(
162 : m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
163 : }
164 : else
165 : {
166 1 : m_papszIMAGERYMD =
167 1 : CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
168 : CPLSPrintf("%d", int(fCC)));
169 : }
170 : }
171 :
172 : // L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE
173 : // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME
174 :
175 : // L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED
176 : // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME
177 :
178 2 : const char *pszDate = CSLFetchNameValue(
179 1 : m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE");
180 1 : if (nullptr == pszDate)
181 : {
182 1 : pszDate = CSLFetchNameValue(
183 1 : m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED");
184 : }
185 :
186 1 : if (nullptr != pszDate)
187 : {
188 2 : const char *pszTime = CSLFetchNameValue(
189 1 : m_papszIMDMD,
190 : "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME");
191 1 : if (nullptr == pszTime)
192 : {
193 1 : pszTime = CSLFetchNameValue(
194 1 : m_papszIMDMD,
195 : "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME");
196 : }
197 1 : if (nullptr == pszTime)
198 0 : pszTime = "00:00:00.000000Z";
199 :
200 : char buffer[80];
201 : GIntBig timeMid =
202 1 : GetAcquisitionTimeFromString(CPLSPrintf("%sT%s", pszDate, pszTime));
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 : }
|