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