LCOV - code coverage report
Current view: top level - gcore/mdreader - reader_digital_globe.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 103 108 95.4 %
Date: 2024-11-25 13:07:18 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Core
       4             :  * Purpose:  Read metadata from DigitalGlobe 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_digital_globe.h"
      16             : 
      17             : #include <ctime>
      18             : 
      19             : #include "cpl_conv.h"
      20             : #include "cpl_error.h"
      21             : #include "cpl_minixml.h"
      22             : #include "cpl_string.h"
      23             : #include "cpl_time.h"
      24             : 
      25             : #include "gdal_priv.h"
      26             : 
      27             : /**
      28             :  * GDALMDReaderDigitalGlobe()
      29             :  */
      30        5151 : GDALMDReaderDigitalGlobe::GDALMDReaderDigitalGlobe(const char *pszPath,
      31        5151 :                                                    char **papszSiblingFiles)
      32             :     : GDALMDReaderBase(pszPath, papszSiblingFiles),
      33             :       m_osXMLSourceFilename(
      34             :           GDALFindAssociatedFile(pszPath, "XML", papszSiblingFiles, 0)),
      35             :       m_osIMDSourceFilename(
      36             :           GDALFindAssociatedFile(pszPath, "IMD", papszSiblingFiles, 0)),
      37             :       m_osRPBSourceFilename(
      38        5151 :           GDALFindAssociatedFile(pszPath, "RPB", papszSiblingFiles, 0))
      39             : {
      40        5151 :     if (!m_osIMDSourceFilename.empty())
      41          36 :         CPLDebug("MDReaderDigitalGlobe", "IMD Filename: %s",
      42             :                  m_osIMDSourceFilename.c_str());
      43        5151 :     if (!m_osRPBSourceFilename.empty())
      44          10 :         CPLDebug("MDReaderDigitalGlobe", "RPB Filename: %s",
      45             :                  m_osRPBSourceFilename.c_str());
      46        5151 :     if (!m_osXMLSourceFilename.empty())
      47           9 :         CPLDebug("MDReaderDigitalGlobe", "XML Filename: %s",
      48             :                  m_osXMLSourceFilename.c_str());
      49        5151 : }
      50             : 
      51             : /**
      52             :  * ~GDALMDReaderDigitalGlobe()
      53             :  */
      54       10302 : GDALMDReaderDigitalGlobe::~GDALMDReaderDigitalGlobe()
      55             : {
      56       10302 : }
      57             : 
      58             : /**
      59             :  * HasRequiredFiles()
      60             :  */
      61        5151 : bool GDALMDReaderDigitalGlobe::HasRequiredFiles() const
      62             : {
      63        5151 :     if (!m_osIMDSourceFilename.empty())
      64          36 :         return true;
      65        5115 :     if (!m_osRPBSourceFilename.empty())
      66           0 :         return true;
      67             : 
      68             :     // check <isd>
      69        5124 :     if (!m_osXMLSourceFilename.empty() &&
      70           9 :         GDALCheckFileHeader(m_osXMLSourceFilename, "<isd>"))
      71           2 :         return true;
      72             : 
      73        5113 :     return false;
      74             : }
      75             : 
      76             : /**
      77             :  * LoadMetadata()
      78             :  */
      79          76 : void GDALMDReaderDigitalGlobe::LoadMetadata()
      80             : {
      81          76 :     if (m_bIsMetadataLoad)
      82          38 :         return;
      83             : 
      84          38 :     if (!m_osIMDSourceFilename.empty())
      85             :     {
      86          36 :         m_papszIMDMD = GDALLoadIMDFile(m_osIMDSourceFilename);
      87             :     }
      88             : 
      89          38 :     if (!m_osRPBSourceFilename.empty())
      90             :     {
      91          10 :         m_papszRPCMD = GDALLoadRPBFile(m_osRPBSourceFilename);
      92             :     }
      93             : 
      94          66 :     if ((nullptr == m_papszIMDMD || nullptr == m_papszRPCMD) &&
      95          28 :         !m_osXMLSourceFilename.empty())
      96             :     {
      97           2 :         CPLXMLNode *psNode = CPLParseXMLFile(m_osXMLSourceFilename);
      98             : 
      99           2 :         if (psNode != nullptr)
     100             :         {
     101           2 :             CPLXMLNode *psisdNode = psNode->psNext;
     102           2 :             if (psisdNode != nullptr)
     103             :             {
     104           2 :                 if (m_papszIMDMD == nullptr)
     105           2 :                     m_papszIMDMD =
     106           2 :                         LoadIMDXmlNode(CPLSearchXMLNode(psisdNode, "IMD"));
     107           2 :                 if (m_papszRPCMD == nullptr)
     108           2 :                     m_papszRPCMD =
     109           2 :                         LoadRPBXmlNode(CPLSearchXMLNode(psisdNode, "RPB"));
     110             :             }
     111           2 :             CPLDestroyXMLNode(psNode);
     112             :         }
     113             :     }
     114             : 
     115          38 :     m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "DG");
     116             : 
     117          38 :     m_bIsMetadataLoad = true;
     118             : 
     119          38 :     if (nullptr == m_papszIMDMD)
     120             :     {
     121           4 :         return;
     122             :     }
     123             :     // extract imagery metadata
     124          34 :     const char *pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE.SATID");
     125          34 :     if (nullptr != pszSatId)
     126             :     {
     127           2 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     128           4 :                                            CPLStripQuotes(pszSatId));
     129             :     }
     130             :     else
     131             :     {
     132          32 :         pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.SATID");
     133          32 :         if (nullptr != pszSatId)
     134             :         {
     135          30 :             m_papszIMAGERYMD = CSLAddNameValue(
     136          60 :                 m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId));
     137             :         }
     138             :     }
     139             : 
     140             :     const char *pszCloudCover =
     141          34 :         CSLFetchNameValue(m_papszIMDMD, "IMAGE.CLOUDCOVER");
     142          34 :     if (nullptr != pszCloudCover)
     143             :     {
     144           2 :         double fCC = CPLAtofM(pszCloudCover);
     145           2 :         if (fCC < 0)
     146             :         {
     147           0 :             m_papszIMAGERYMD = CSLAddNameValue(
     148             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     149             :         }
     150             :         else
     151             :         {
     152           2 :             m_papszIMAGERYMD =
     153           2 :                 CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     154           2 :                                 CPLSPrintf("%d", int(fCC * 100)));
     155             :         }
     156             :     }
     157             :     else
     158             :     {
     159          32 :         pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.cloudCover");
     160          32 :         if (nullptr != pszCloudCover)
     161             :         {
     162          30 :             double fCC = CPLAtofM(pszCloudCover);
     163          30 :             if (fCC < 0)
     164             :             {
     165           0 :                 m_papszIMAGERYMD = CSLAddNameValue(
     166             :                     m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     167             :             }
     168             :             else
     169             :             {
     170          30 :                 m_papszIMAGERYMD =
     171          30 :                     CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     172          30 :                                     CPLSPrintf("%d", int(fCC * 100)));
     173             :             }
     174             :         }
     175             :     }
     176             : 
     177             :     const char *pszDateTime =
     178          34 :         CSLFetchNameValue(m_papszIMDMD, "IMAGE.FIRSTLINETIME");
     179          34 :     if (nullptr != pszDateTime)
     180             :     {
     181           2 :         GIntBig timeStart = GetAcquisitionTimeFromString(pszDateTime);
     182             :         char szMidDateTime[80];
     183             :         struct tm tmBuf;
     184           2 :         strftime(szMidDateTime, 80, MD_DATETIMEFORMAT,
     185           2 :                  CPLUnixTimeToYMDHMS(timeStart, &tmBuf));
     186             : 
     187           2 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD,
     188             :                                            MD_NAME_ACQDATETIME, szMidDateTime);
     189             :     }
     190             :     else
     191             :     {
     192          32 :         pszDateTime = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.firstLineTime");
     193          32 :         if (nullptr != pszDateTime)
     194             :         {
     195          30 :             GIntBig timeStart = GetAcquisitionTimeFromString(pszDateTime);
     196             :             char szMidDateTime[80];
     197             :             struct tm tmBuf;
     198          30 :             strftime(szMidDateTime, 80, MD_DATETIMEFORMAT,
     199          30 :                      CPLUnixTimeToYMDHMS(timeStart, &tmBuf));
     200             : 
     201          30 :             m_papszIMAGERYMD = CSLAddNameValue(
     202             :                 m_papszIMAGERYMD, MD_NAME_ACQDATETIME, szMidDateTime);
     203             :         }
     204             :     }
     205             : }
     206             : 
     207             : /**
     208             :  * GetMetadataFiles()
     209             :  */
     210          38 : char **GDALMDReaderDigitalGlobe::GetMetadataFiles() const
     211             : {
     212          38 :     char **papszFileList = nullptr;
     213          38 :     if (!m_osIMDSourceFilename.empty())
     214          36 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
     215          38 :     if (!m_osRPBSourceFilename.empty())
     216          10 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
     217          38 :     if (!m_osXMLSourceFilename.empty())
     218           2 :         papszFileList = CSLAddString(papszFileList, m_osXMLSourceFilename);
     219             : 
     220          38 :     return papszFileList;
     221             : }
     222             : 
     223             : /**
     224             :  * GDALLoadIMDXmlNode()
     225             :  */
     226           2 : char **GDALMDReaderDigitalGlobe::LoadIMDXmlNode(CPLXMLNode *psNode)
     227             : {
     228           2 :     if (nullptr == psNode)
     229           0 :         return nullptr;
     230           2 :     char **papszList = nullptr;
     231           2 :     return ReadXMLToList(psNode->psChild, papszList);
     232             : }
     233             : 
     234             : /**
     235             :  * GDALLoadRPBXmlNode()
     236             :  */
     237             : static const char *const apszRPBMap[] = {RPC_ERR_BIAS,
     238             :                                          "image.errBias",
     239             :                                          RPC_ERR_RAND,
     240             :                                          "image.errRand",
     241             :                                          RPC_LINE_OFF,
     242             :                                          "image.lineOffset",
     243             :                                          RPC_SAMP_OFF,
     244             :                                          "image.sampOffset",
     245             :                                          RPC_LAT_OFF,
     246             :                                          "image.latOffset",
     247             :                                          RPC_LONG_OFF,
     248             :                                          "image.longOffset",
     249             :                                          RPC_HEIGHT_OFF,
     250             :                                          "image.heightOffset",
     251             :                                          RPC_LINE_SCALE,
     252             :                                          "image.lineScale",
     253             :                                          RPC_SAMP_SCALE,
     254             :                                          "image.sampScale",
     255             :                                          RPC_LAT_SCALE,
     256             :                                          "image.latScale",
     257             :                                          RPC_LONG_SCALE,
     258             :                                          "image.longScale",
     259             :                                          RPC_HEIGHT_SCALE,
     260             :                                          "image.heightScale",
     261             :                                          RPC_LINE_NUM_COEFF,
     262             :                                          "image.lineNumCoefList.lineNumCoef",
     263             :                                          RPC_LINE_DEN_COEFF,
     264             :                                          "image.lineDenCoefList.lineDenCoef",
     265             :                                          RPC_SAMP_NUM_COEFF,
     266             :                                          "image.sampNumCoefList.sampNumCoef",
     267             :                                          RPC_SAMP_DEN_COEFF,
     268             :                                          "image.sampDenCoefList.sampDenCoef",
     269             :                                          nullptr,
     270             :                                          nullptr};
     271             : 
     272           2 : char **GDALMDReaderDigitalGlobe::LoadRPBXmlNode(CPLXMLNode *psNode)
     273             : {
     274           2 :     if (nullptr == psNode)
     275           1 :         return nullptr;
     276           1 :     char **papszList = nullptr;
     277           1 :     papszList = ReadXMLToList(psNode->psChild, papszList);
     278             : 
     279           1 :     if (nullptr == papszList)
     280           0 :         return nullptr;
     281             : 
     282           1 :     char **papszRPB = nullptr;
     283          17 :     for (int i = 0; apszRPBMap[i] != nullptr; i += 2)
     284             :     {
     285             :         papszRPB =
     286          16 :             CSLAddNameValue(papszRPB, apszRPBMap[i],
     287          16 :                             CSLFetchNameValue(papszList, apszRPBMap[i + 1]));
     288             :     }
     289             : 
     290           1 :     CSLDestroy(papszList);
     291             : 
     292           1 :     return papszRPB;
     293             : }

Generated by: LCOV version 1.14