EVOLUTION-MANAGER
Edit File: reader_spot.cpp
/****************************************************************************** * * Project: GDAL Core * Purpose: Read metadata from Spot 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_spot.h" #include <ctime> #include "cpl_conv.h" #include "cpl_error.h" #include "cpl_minixml.h" #include "cpl_string.h" #include "gdal_mdreader.h" CPL_CVSID("$Id: reader_spot.cpp 36682 2016-12-04 20:34:45Z rouault $"); /** * GDALMDReaderSpot() */ GDALMDReaderSpot::GDALMDReaderSpot(const char *pszPath, char **papszSiblingFiles) : GDALMDReaderPleiades(pszPath, papszSiblingFiles) { const char* pszIMDSourceFilename; const char* pszDirName = CPLGetDirname(pszPath); if(m_osIMDSourceFilename.empty()) { pszIMDSourceFilename = CPLFormFilename( pszDirName, "METADATA.DIM", NULL ); if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles)) { m_osIMDSourceFilename = pszIMDSourceFilename; } else { pszIMDSourceFilename = CPLFormFilename( pszDirName, "metadata.dim", NULL ); if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles)) { m_osIMDSourceFilename = pszIMDSourceFilename; } } } // if the file name ended on METADATA.DIM // Linux specific // example: R2_CAT_091028105025131_1\METADATA.DIM if(m_osIMDSourceFilename.empty()) { if(EQUAL(CPLGetFilename(pszPath), "IMAGERY.TIF")) { pszIMDSourceFilename = CPLSPrintf( "%s\\METADATA.DIM", CPLGetPath(pszPath)); if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles)) { m_osIMDSourceFilename = pszIMDSourceFilename; } else { pszIMDSourceFilename = CPLSPrintf( "%s\\metadata.dim", CPLGetPath(pszPath)); if (CPLCheckForFile((char*)pszIMDSourceFilename, papszSiblingFiles)) { m_osIMDSourceFilename = pszIMDSourceFilename; } } } } if(!m_osIMDSourceFilename.empty() ) CPLDebug( "MDReaderSpot", "IMD Filename: %s", m_osIMDSourceFilename.c_str() ); } /** * ~GDALMDReaderSpot() */ GDALMDReaderSpot::~GDALMDReaderSpot() { } /** * LoadMetadata() */ void GDALMDReaderSpot::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osIMDSourceFilename.empty()) { CPLXMLNode* psNode = CPLParseXMLFile(m_osIMDSourceFilename); if(psNode != NULL) { CPLXMLNode* psisdNode = CPLSearchXMLNode(psNode, "=Dimap_Document"); if(psisdNode != NULL) { m_papszIMDMD = ReadXMLToList(psisdNode->psChild, m_papszIMDMD); } CPLDestroyXMLNode(psNode); } } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "DIMAP"); m_bIsMetadataLoad = true; if(NULL == m_papszIMDMD) { return; } //extract imagery metadata int nCounter = -1; const char* pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.MISSION"); if(NULL == pszSatId1) { nCounter = 1; for(int i = 0; i < 5; i++) { pszSatId1 = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf("Dataset_Sources.Source_Information_%d.Scene_Source.MISSION", nCounter)); if(NULL != pszSatId1) break; nCounter++; } } const char* pszSatId2; if(nCounter == -1) pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.MISSION_INDEX"); else pszSatId2 = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.MISSION_INDEX", nCounter)); if(NULL != pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLSPrintf( "%s %s", CPLStripQuotes(pszSatId1).c_str(), CPLStripQuotes(pszSatId2).c_str())); } else if(NULL != pszSatId1 && NULL == pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId1)); } else if(NULL == pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId2)); } const char* pszDate; if(nCounter == -1) pszDate = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.IMAGING_DATE"); else pszDate = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.IMAGING_DATE", nCounter)); if(NULL != pszDate) { const char* pszTime; if(nCounter == -1) pszTime = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.IMAGING_TIME"); else pszTime = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.IMAGING_TIME", nCounter)); if(NULL == pszTime) pszTime = "00:00:00.0Z"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } /** * ReadXMLToList() */ char** GDALMDReaderSpot::ReadXMLToList(CPLXMLNode* psNode, char** papszList, const char* pszName) { if(NULL == psNode) return papszList; if (psNode->eType == CXT_Text) { if(!EQUAL(pszName, "")) return AddXMLNameValueToList(papszList, pszName, psNode->pszValue); } if (psNode->eType == CXT_Element && !EQUAL(psNode->pszValue, "Data_Strip")) { int nAddIndex = 0; bool bReset = false; for(CPLXMLNode* psChildNode = psNode->psChild; NULL != psChildNode; psChildNode = psChildNode->psNext) { if (psChildNode->eType == CXT_Element) { // check name duplicates if(NULL != psChildNode->psNext) { if(bReset) { bReset = false; nAddIndex = 0; } if(EQUAL(psChildNode->pszValue, psChildNode->psNext->pszValue)) { nAddIndex++; } else { // the name changed if(nAddIndex > 0) { bReset = true; nAddIndex++; } } } else { if(nAddIndex > 0) { nAddIndex++; } } char szName[512]; if(nAddIndex > 0) { CPLsnprintf( szName, 511, "%s_%d", psChildNode->pszValue, nAddIndex); } else { CPLStrlcpy(szName, psChildNode->pszValue, 511); } char szNameNew[512]; if(CPLStrnlen( pszName, 511 ) > 0) //if no prefix just set name to node name { CPLsnprintf( szNameNew, 511, "%s.%s", pszName, szName ); } else { CPLsnprintf( szNameNew, 511, "%s.%s", psNode->pszValue, szName ); } papszList = ReadXMLToList(psChildNode, papszList, szNameNew); } else { // Text nodes should always have name if(EQUAL(pszName, "")) { papszList = ReadXMLToList(psChildNode, papszList, psNode->pszValue); } else { papszList = ReadXMLToList(psChildNode, papszList, pszName); } } } } // proceed next only on top level if(NULL != psNode->psNext && EQUAL(pszName, "")) { papszList = ReadXMLToList(psNode->psNext, papszList, pszName); } return papszList; }