/****************************************************************************** * * Project: GDAL Core * Purpose: Read metadata from Resurs-DK1 imagery. * Author: Alexander Lisovenko * Author: Dmitry Baryshnikov, polimax@mail.ru * ****************************************************************************** * Copyright (c) 2014-2015 NextGIS * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/ #include "cpl_port.h" #include "reader_rdk1.h" #include #include "cpl_error.h" #include "cpl_minixml.h" #include "cpl_string.h" #include "cpl_time.h" #include "gdal_priv.h" /** * GDALMDReaderResursDK1() */ GDALMDReaderResursDK1::GDALMDReaderResursDK1(const char *pszPath, char **papszSiblingFiles) : GDALMDReaderBase(pszPath, papszSiblingFiles), m_osXMLSourceFilename( GDALFindAssociatedFile(pszPath, "XML", papszSiblingFiles, 0)) { if (!m_osXMLSourceFilename.empty()) CPLDebug("MDReaderResursDK1", "XML Filename: %s", m_osXMLSourceFilename.c_str()); } /** * ~GDALMDReaderResursDK1() */ GDALMDReaderResursDK1::~GDALMDReaderResursDK1() { } /** * HasRequiredFiles() */ bool GDALMDReaderResursDK1::HasRequiredFiles() const { // check if (!m_osXMLSourceFilename.empty() && GDALCheckFileHeader(m_osXMLSourceFilename, "")) return true; return false; } /** * GetMetadataFiles() */ char **GDALMDReaderResursDK1::GetMetadataFiles() const { char **papszFileList = nullptr; if (!m_osXMLSourceFilename.empty()) papszFileList = CSLAddString(papszFileList, m_osXMLSourceFilename); return papszFileList; } /** * LoadMetadata() */ void GDALMDReaderResursDK1::LoadMetadata() { if (m_bIsMetadataLoad) return; if (!m_osXMLSourceFilename.empty()) { CPLXMLNode *psNode = CPLParseXMLFile(m_osXMLSourceFilename); if (psNode != nullptr) { CPLXMLNode *pMSPRootNode = CPLSearchXMLNode(psNode, "=MSP_ROOT"); if (pMSPRootNode != nullptr) { m_papszIMDMD = ReadXMLToList(pMSPRootNode, m_papszIMDMD, "MSP_ROOT"); } CPLDestroyXMLNode(psNode); } } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "MSP"); m_bIsMetadataLoad = true; if (nullptr == m_papszIMDMD) { return; } // extract imagery metadata const char *pszSatId = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.cCodeKA"); if (nullptr != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } const char *pszDate = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.dSceneDate"); if (nullptr != pszDate) { const char *pszTime = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.tSceneTime"); if (nullptr == pszTime) pszTime = "00:00:00.000000"; char buffer[80]; GIntBig timeMid = GetAcquisitionTimeFromString(CPLSPrintf("%s %s", pszDate, pszTime)); struct tm tmBuf; strftime(buffer, 80, MD_DATETIMEFORMAT, CPLUnixTimeToYMDHMS(timeMid, &tmBuf)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } /** * GetAcqisitionTimeFromString() */ GIntBig GDALMDReaderResursDK1::GetAcquisitionTimeFromString(const char *pszDateTime) { if (nullptr == pszDateTime) return 0; int iYear; int iMonth; int iDay; int iHours; int iMin; int iSec; // string example // tSceneTime = 10:21:36.000000 // dSceneDate = 16/9/2008 // int r = sscanf(pszDateTime, "%d/%d/%d %d:%d:%d.%*s", &iDay, &iMonth, &iYear, &iHours, &iMin, &iSec); if (r != 6) return 0; struct tm tmDateTime; tmDateTime.tm_sec = iSec; tmDateTime.tm_min = iMin; tmDateTime.tm_hour = iHours; tmDateTime.tm_mday = iDay; tmDateTime.tm_mon = iMonth - 1; tmDateTime.tm_year = iYear - 1900; tmDateTime.tm_isdst = -1; return CPLYMDHMSToUnixTime(&tmDateTime) - 10800; // int UTC+3 MSK } char **GDALMDReaderResursDK1::AddXMLNameValueToList(char **papszList, const char *pszName, const char *pszValue) { char **papszTokens = CSLTokenizeString2( pszValue, "\n", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); for (int i = 0; papszTokens[i] != nullptr; i++) { char **papszSubTokens = CSLTokenizeString2( papszTokens[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if (CSLCount(papszSubTokens) < 2) { CSLDestroy(papszSubTokens); continue; } papszList = CSLAddNameValue( papszList, CPLSPrintf("%s.%s", pszName, papszSubTokens[0]), papszSubTokens[1]); CSLDestroy(papszSubTokens); } CSLDestroy(papszTokens); return papszList; }