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