gdal/gcore/mdreader/reader_rdk1.cpp

221 строка
6.3 KiB
C++

/******************************************************************************
*
* Project: GDAL Core
* Purpose: Read metadata from Resurs-DK1 imagery.
* Author: Alexander Lisovenko
* Author: Dmitry Baryshnikov, polimax@mail.ru
*
******************************************************************************
* Copyright (c) 2014-2015 NextGIS <info@nextgis.ru>
*
* 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 <cstdio>
#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 <MSP_ROOT>
if (!m_osXMLSourceFilename.empty() &&
GDALCheckFileHeader(m_osXMLSourceFilename, "<MSP_ROOT>"))
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 <Normal>
// tSceneTime = 10:21:36.000000
// dSceneDate = 16/9/2008
// </Normal>
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;
}