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-05-14 23:54:21 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "cpl_port.h"
      31             : #include "reader_digital_globe.h"
      32             : 
      33             : #include <ctime>
      34             : 
      35             : #include "cpl_conv.h"
      36             : #include "cpl_error.h"
      37             : #include "cpl_minixml.h"
      38             : #include "cpl_string.h"
      39             : #include "cpl_time.h"
      40             : 
      41             : #include "gdal_priv.h"
      42             : 
      43             : /**
      44             :  * GDALMDReaderDigitalGlobe()
      45             :  */
      46        5095 : GDALMDReaderDigitalGlobe::GDALMDReaderDigitalGlobe(const char *pszPath,
      47        5095 :                                                    char **papszSiblingFiles)
      48             :     : GDALMDReaderBase(pszPath, papszSiblingFiles),
      49             :       m_osXMLSourceFilename(
      50             :           GDALFindAssociatedFile(pszPath, "XML", papszSiblingFiles, 0)),
      51             :       m_osIMDSourceFilename(
      52             :           GDALFindAssociatedFile(pszPath, "IMD", papszSiblingFiles, 0)),
      53             :       m_osRPBSourceFilename(
      54        5095 :           GDALFindAssociatedFile(pszPath, "RPB", papszSiblingFiles, 0))
      55             : {
      56        5095 :     if (!m_osIMDSourceFilename.empty())
      57          36 :         CPLDebug("MDReaderDigitalGlobe", "IMD Filename: %s",
      58             :                  m_osIMDSourceFilename.c_str());
      59        5095 :     if (!m_osRPBSourceFilename.empty())
      60          10 :         CPLDebug("MDReaderDigitalGlobe", "RPB Filename: %s",
      61             :                  m_osRPBSourceFilename.c_str());
      62        5095 :     if (!m_osXMLSourceFilename.empty())
      63           9 :         CPLDebug("MDReaderDigitalGlobe", "XML Filename: %s",
      64             :                  m_osXMLSourceFilename.c_str());
      65        5095 : }
      66             : 
      67             : /**
      68             :  * ~GDALMDReaderDigitalGlobe()
      69             :  */
      70       10190 : GDALMDReaderDigitalGlobe::~GDALMDReaderDigitalGlobe()
      71             : {
      72       10190 : }
      73             : 
      74             : /**
      75             :  * HasRequiredFiles()
      76             :  */
      77        5095 : bool GDALMDReaderDigitalGlobe::HasRequiredFiles() const
      78             : {
      79        5095 :     if (!m_osIMDSourceFilename.empty())
      80          36 :         return true;
      81        5059 :     if (!m_osRPBSourceFilename.empty())
      82           0 :         return true;
      83             : 
      84             :     // check <isd>
      85        5068 :     if (!m_osXMLSourceFilename.empty() &&
      86           9 :         GDALCheckFileHeader(m_osXMLSourceFilename, "<isd>"))
      87           2 :         return true;
      88             : 
      89        5057 :     return false;
      90             : }
      91             : 
      92             : /**
      93             :  * LoadMetadata()
      94             :  */
      95          76 : void GDALMDReaderDigitalGlobe::LoadMetadata()
      96             : {
      97          76 :     if (m_bIsMetadataLoad)
      98          38 :         return;
      99             : 
     100          38 :     if (!m_osIMDSourceFilename.empty())
     101             :     {
     102          36 :         m_papszIMDMD = GDALLoadIMDFile(m_osIMDSourceFilename);
     103             :     }
     104             : 
     105          38 :     if (!m_osRPBSourceFilename.empty())
     106             :     {
     107          10 :         m_papszRPCMD = GDALLoadRPBFile(m_osRPBSourceFilename);
     108             :     }
     109             : 
     110          66 :     if ((nullptr == m_papszIMDMD || nullptr == m_papszRPCMD) &&
     111          28 :         !m_osXMLSourceFilename.empty())
     112             :     {
     113           2 :         CPLXMLNode *psNode = CPLParseXMLFile(m_osXMLSourceFilename);
     114             : 
     115           2 :         if (psNode != nullptr)
     116             :         {
     117           2 :             CPLXMLNode *psisdNode = psNode->psNext;
     118           2 :             if (psisdNode != nullptr)
     119             :             {
     120           2 :                 if (m_papszIMDMD == nullptr)
     121           2 :                     m_papszIMDMD =
     122           2 :                         LoadIMDXmlNode(CPLSearchXMLNode(psisdNode, "IMD"));
     123           2 :                 if (m_papszRPCMD == nullptr)
     124           2 :                     m_papszRPCMD =
     125           2 :                         LoadRPBXmlNode(CPLSearchXMLNode(psisdNode, "RPB"));
     126             :             }
     127           2 :             CPLDestroyXMLNode(psNode);
     128             :         }
     129             :     }
     130             : 
     131          38 :     m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "DG");
     132             : 
     133          38 :     m_bIsMetadataLoad = true;
     134             : 
     135          38 :     if (nullptr == m_papszIMDMD)
     136             :     {
     137           4 :         return;
     138             :     }
     139             :     // extract imagery metadata
     140          34 :     const char *pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE.SATID");
     141          34 :     if (nullptr != pszSatId)
     142             :     {
     143           2 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     144           4 :                                            CPLStripQuotes(pszSatId));
     145             :     }
     146             :     else
     147             :     {
     148          32 :         pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.SATID");
     149          32 :         if (nullptr != pszSatId)
     150             :         {
     151          30 :             m_papszIMAGERYMD = CSLAddNameValue(
     152          60 :                 m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId));
     153             :         }
     154             :     }
     155             : 
     156             :     const char *pszCloudCover =
     157          34 :         CSLFetchNameValue(m_papszIMDMD, "IMAGE.CLOUDCOVER");
     158          34 :     if (nullptr != pszCloudCover)
     159             :     {
     160           2 :         double fCC = CPLAtofM(pszCloudCover);
     161           2 :         if (fCC < 0)
     162             :         {
     163           0 :             m_papszIMAGERYMD = CSLAddNameValue(
     164             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     165             :         }
     166             :         else
     167             :         {
     168           2 :             m_papszIMAGERYMD =
     169           2 :                 CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     170           2 :                                 CPLSPrintf("%d", int(fCC * 100)));
     171             :         }
     172             :     }
     173             :     else
     174             :     {
     175          32 :         pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.cloudCover");
     176          32 :         if (nullptr != pszCloudCover)
     177             :         {
     178          30 :             double fCC = CPLAtofM(pszCloudCover);
     179          30 :             if (fCC < 0)
     180             :             {
     181           0 :                 m_papszIMAGERYMD = CSLAddNameValue(
     182             :                     m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     183             :             }
     184             :             else
     185             :             {
     186          30 :                 m_papszIMAGERYMD =
     187          30 :                     CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     188          30 :                                     CPLSPrintf("%d", int(fCC * 100)));
     189             :             }
     190             :         }
     191             :     }
     192             : 
     193             :     const char *pszDateTime =
     194          34 :         CSLFetchNameValue(m_papszIMDMD, "IMAGE.FIRSTLINETIME");
     195          34 :     if (nullptr != pszDateTime)
     196             :     {
     197           2 :         GIntBig timeStart = GetAcquisitionTimeFromString(pszDateTime);
     198             :         char szMidDateTime[80];
     199             :         struct tm tmBuf;
     200           2 :         strftime(szMidDateTime, 80, MD_DATETIMEFORMAT,
     201           2 :                  CPLUnixTimeToYMDHMS(timeStart, &tmBuf));
     202             : 
     203           2 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD,
     204             :                                            MD_NAME_ACQDATETIME, szMidDateTime);
     205             :     }
     206             :     else
     207             :     {
     208          32 :         pszDateTime = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.firstLineTime");
     209          32 :         if (nullptr != pszDateTime)
     210             :         {
     211          30 :             GIntBig timeStart = GetAcquisitionTimeFromString(pszDateTime);
     212             :             char szMidDateTime[80];
     213             :             struct tm tmBuf;
     214          30 :             strftime(szMidDateTime, 80, MD_DATETIMEFORMAT,
     215          30 :                      CPLUnixTimeToYMDHMS(timeStart, &tmBuf));
     216             : 
     217          30 :             m_papszIMAGERYMD = CSLAddNameValue(
     218             :                 m_papszIMAGERYMD, MD_NAME_ACQDATETIME, szMidDateTime);
     219             :         }
     220             :     }
     221             : }
     222             : 
     223             : /**
     224             :  * GetMetadataFiles()
     225             :  */
     226          38 : char **GDALMDReaderDigitalGlobe::GetMetadataFiles() const
     227             : {
     228          38 :     char **papszFileList = nullptr;
     229          38 :     if (!m_osIMDSourceFilename.empty())
     230          36 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
     231          38 :     if (!m_osRPBSourceFilename.empty())
     232          10 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
     233          38 :     if (!m_osXMLSourceFilename.empty())
     234           2 :         papszFileList = CSLAddString(papszFileList, m_osXMLSourceFilename);
     235             : 
     236          38 :     return papszFileList;
     237             : }
     238             : 
     239             : /**
     240             :  * GDALLoadIMDXmlNode()
     241             :  */
     242           2 : char **GDALMDReaderDigitalGlobe::LoadIMDXmlNode(CPLXMLNode *psNode)
     243             : {
     244           2 :     if (nullptr == psNode)
     245           0 :         return nullptr;
     246           2 :     char **papszList = nullptr;
     247           2 :     return ReadXMLToList(psNode->psChild, papszList);
     248             : }
     249             : 
     250             : /**
     251             :  * GDALLoadRPBXmlNode()
     252             :  */
     253             : static const char *const apszRPBMap[] = {RPC_ERR_BIAS,
     254             :                                          "image.errBias",
     255             :                                          RPC_ERR_RAND,
     256             :                                          "image.errRand",
     257             :                                          RPC_LINE_OFF,
     258             :                                          "image.lineOffset",
     259             :                                          RPC_SAMP_OFF,
     260             :                                          "image.sampOffset",
     261             :                                          RPC_LAT_OFF,
     262             :                                          "image.latOffset",
     263             :                                          RPC_LONG_OFF,
     264             :                                          "image.longOffset",
     265             :                                          RPC_HEIGHT_OFF,
     266             :                                          "image.heightOffset",
     267             :                                          RPC_LINE_SCALE,
     268             :                                          "image.lineScale",
     269             :                                          RPC_SAMP_SCALE,
     270             :                                          "image.sampScale",
     271             :                                          RPC_LAT_SCALE,
     272             :                                          "image.latScale",
     273             :                                          RPC_LONG_SCALE,
     274             :                                          "image.longScale",
     275             :                                          RPC_HEIGHT_SCALE,
     276             :                                          "image.heightScale",
     277             :                                          RPC_LINE_NUM_COEFF,
     278             :                                          "image.lineNumCoefList.lineNumCoef",
     279             :                                          RPC_LINE_DEN_COEFF,
     280             :                                          "image.lineDenCoefList.lineDenCoef",
     281             :                                          RPC_SAMP_NUM_COEFF,
     282             :                                          "image.sampNumCoefList.sampNumCoef",
     283             :                                          RPC_SAMP_DEN_COEFF,
     284             :                                          "image.sampDenCoefList.sampDenCoef",
     285             :                                          nullptr,
     286             :                                          nullptr};
     287             : 
     288           2 : char **GDALMDReaderDigitalGlobe::LoadRPBXmlNode(CPLXMLNode *psNode)
     289             : {
     290           2 :     if (nullptr == psNode)
     291           1 :         return nullptr;
     292           1 :     char **papszList = nullptr;
     293           1 :     papszList = ReadXMLToList(psNode->psChild, papszList);
     294             : 
     295           1 :     if (nullptr == papszList)
     296           0 :         return nullptr;
     297             : 
     298           1 :     char **papszRPB = nullptr;
     299          17 :     for (int i = 0; apszRPBMap[i] != nullptr; i += 2)
     300             :     {
     301             :         papszRPB =
     302          16 :             CSLAddNameValue(papszRPB, apszRPBMap[i],
     303          16 :                             CSLFetchNameValue(papszList, apszRPBMap[i + 1]));
     304             :     }
     305             : 
     306           1 :     CSLDestroy(papszList);
     307             : 
     308           1 :     return papszRPB;
     309             : }

Generated by: LCOV version 1.14