LCOV - code coverage report
Current view: top level - gcore/mdreader - reader_eros.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 99 117 84.6 %
Date: 2026-02-27 03:43:11 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Core
       4             :  * Purpose:  Read metadata from EROS 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_eros.h"
      16             : 
      17             : #include <cstddef>
      18             : #include <cstdio>
      19             : #include <cstdlib>
      20             : 
      21             : #include "cpl_conv.h"
      22             : #include "cpl_error.h"
      23             : #include "cpl_string.h"
      24             : #include "cpl_time.h"
      25             : 
      26             : /**
      27             :  * GDALMDReaderEROS()
      28             :  */
      29        5837 : GDALMDReaderEROS::GDALMDReaderEROS(const char *pszPath,
      30        5837 :                                    CSLConstList papszSiblingFiles)
      31        5837 :     : GDALMDReaderBase(pszPath, papszSiblingFiles)
      32             : {
      33        5837 :     const CPLString osBaseName = CPLGetBasenameSafe(pszPath);
      34        5837 :     const CPLString osDirName = CPLGetDirnameSafe(pszPath);
      35        5837 :     char szMetadataName[512] = {0};
      36             :     size_t i;
      37        5837 :     if (osBaseName.size() > 511)
      38           0 :         return;
      39             : 
      40             :     // To shutdown HTTP 403 errors when trying to open .pass side-car file on
      41             :     // gdalinfo /vsicurl/https://s3.opengeohub.org/global/dtm/v1.2/gedtm_rf_m_30m_s_20060101_20151231_go_epsg.4326.3855_v1.2.tif --debug on
      42       11674 :     CPLErrorStateBackuper oBackuper(CPLQuietErrorHandler);
      43             : 
      44       64396 :     for (i = 0; i < osBaseName.size(); i++)
      45             :     {
      46       58559 :         if (STARTS_WITH_CI(osBaseName + i, "."))
      47             :         {
      48             :             std::string osPassFileName =
      49          97 :                 CPLFormFilenameSafe(osDirName, szMetadataName, "pass");
      50          97 :             if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
      51             :             {
      52           0 :                 m_osIMDSourceFilename = std::move(osPassFileName);
      53           0 :                 break;
      54             :             }
      55             :             else
      56             :             {
      57             :                 osPassFileName =
      58          97 :                     CPLFormFilenameSafe(osDirName, szMetadataName, "PASS");
      59          97 :                 if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
      60             :                 {
      61           0 :                     m_osIMDSourceFilename = std::move(osPassFileName);
      62           0 :                     break;
      63             :                 }
      64             :             }
      65             :         }
      66       58559 :         szMetadataName[i] = osBaseName[i];
      67             :     }
      68             : 
      69        5837 :     if (m_osIMDSourceFilename.empty())
      70             :     {
      71             :         std::string osPassFileName =
      72       11674 :             CPLFormFilenameSafe(osDirName, szMetadataName, "pass");
      73        5837 :         if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
      74             :         {
      75           1 :             m_osIMDSourceFilename = std::move(osPassFileName);
      76             :         }
      77             :         else
      78             :         {
      79             :             osPassFileName =
      80        5836 :                 CPLFormFilenameSafe(osDirName, szMetadataName, "PASS");
      81        5836 :             if (CPLCheckForFile(&osPassFileName[0], papszSiblingFiles))
      82             :             {
      83           0 :                 m_osIMDSourceFilename = std::move(osPassFileName);
      84             :             }
      85             :         }
      86             :     }
      87             : 
      88             :     std::string osRPCFileName =
      89       11674 :         CPLFormFilenameSafe(osDirName, szMetadataName, "rpc");
      90        5837 :     if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
      91             :     {
      92           1 :         m_osRPBSourceFilename = std::move(osRPCFileName);
      93             :     }
      94             :     else
      95             :     {
      96        5836 :         osRPCFileName = CPLFormFilenameSafe(osDirName, szMetadataName, "RPC");
      97        5836 :         if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
      98             :         {
      99           0 :             m_osRPBSourceFilename = std::move(osRPCFileName);
     100             :         }
     101             :     }
     102             : 
     103        5837 :     if (!m_osIMDSourceFilename.empty())
     104           1 :         CPLDebug("MDReaderEROS", "IMD Filename: %s",
     105             :                  m_osIMDSourceFilename.c_str());
     106        5837 :     if (!m_osRPBSourceFilename.empty())
     107           1 :         CPLDebug("MDReaderEROS", "RPB Filename: %s",
     108             :                  m_osRPBSourceFilename.c_str());
     109             : }
     110             : 
     111             : /**
     112             :  * ~GDALMDReaderEROS()
     113             :  */
     114       11674 : GDALMDReaderEROS::~GDALMDReaderEROS()
     115             : {
     116       11674 : }
     117             : 
     118             : /**
     119             :  * HasRequiredFiles()
     120             :  */
     121        5837 : bool GDALMDReaderEROS::HasRequiredFiles() const
     122             : {
     123        5837 :     if (!m_osIMDSourceFilename.empty())
     124           1 :         return true;
     125        5836 :     if (!m_osRPBSourceFilename.empty())
     126           0 :         return true;
     127             : 
     128        5836 :     return false;
     129             : }
     130             : 
     131             : /**
     132             :  * GetMetadataFiles()
     133             :  */
     134           1 : char **GDALMDReaderEROS::GetMetadataFiles() const
     135             : {
     136           1 :     char **papszFileList = nullptr;
     137           1 :     if (!m_osIMDSourceFilename.empty())
     138           1 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
     139           1 :     if (!m_osRPBSourceFilename.empty())
     140           1 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
     141           1 :     return papszFileList;
     142             : }
     143             : 
     144             : /**
     145             :  * LoadMetadata()
     146             :  */
     147           2 : void GDALMDReaderEROS::LoadMetadata()
     148             : {
     149           2 :     if (m_bIsMetadataLoad)
     150           1 :         return;
     151             : 
     152           1 :     if (!m_osIMDSourceFilename.empty())
     153             :     {
     154           1 :         m_papszIMDMD = LoadImdTxtFile();
     155             :     }
     156             : 
     157           1 :     if (!m_osRPBSourceFilename.empty())
     158             :     {
     159           1 :         m_papszRPCMD = GDALLoadRPCFile(m_osRPBSourceFilename);
     160             :     }
     161             : 
     162           1 :     m_papszDEFAULTMD =
     163           1 :         CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "EROS");
     164             : 
     165           1 :     m_bIsMetadataLoad = true;
     166             : 
     167           1 :     const char *pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "satellite");
     168           1 :     const char *pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "camera");
     169           1 :     if (nullptr != pszSatId1 && nullptr != pszSatId2)
     170             :     {
     171           2 :         m_papszIMAGERYMD = CSLAddNameValue(
     172             :             m_papszIMAGERYMD, MD_NAME_SATELLITE,
     173           2 :             CPLSPrintf("%s %s", CPLStripQuotes(pszSatId1).c_str(),
     174           2 :                        CPLStripQuotes(pszSatId2).c_str()));
     175             :     }
     176           0 :     else if (nullptr != pszSatId1 && nullptr == pszSatId2)
     177             :     {
     178           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     179           0 :                                            CPLStripQuotes(pszSatId1));
     180             :     }
     181           0 :     else if (nullptr == pszSatId1 && nullptr != pszSatId2)
     182             :     {
     183           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     184           0 :                                            CPLStripQuotes(pszSatId2));
     185             :     }
     186             : 
     187           1 :     const char *pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "overall_cc");
     188           1 :     if (nullptr != pszCloudCover)
     189             :     {
     190           1 :         int nCC = atoi(pszCloudCover);
     191           1 :         if (nCC > 100 || nCC < 0)
     192             :         {
     193           0 :             m_papszIMAGERYMD = CSLAddNameValue(
     194             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     195             :         }
     196             :         else
     197             :         {
     198           1 :             m_papszIMAGERYMD = CSLAddNameValue(
     199             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", nCC));
     200             :         }
     201             :     }
     202             : 
     203           1 :     const char *pszDate = CSLFetchNameValue(m_papszIMDMD, "sweep_start_utc");
     204           1 :     if (nullptr != pszDate)
     205             :     {
     206             :         char buffer[80];
     207           1 :         GIntBig timeMid = GetAcquisitionTimeFromString(CPLStripQuotes(pszDate));
     208             :         struct tm tmBuf;
     209           1 :         strftime(buffer, 80, MD_DATETIMEFORMAT,
     210           1 :                  CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
     211           1 :         m_papszIMAGERYMD =
     212           1 :             CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
     213             :     }
     214             : }
     215             : 
     216             : /**
     217             :  * LoadImdTxtFile
     218             :  */
     219           1 : char **GDALMDReaderEROS::LoadImdTxtFile()
     220             : {
     221           1 :     char **papszLines = CSLLoad(m_osIMDSourceFilename);
     222           1 :     if (nullptr == papszLines)
     223           0 :         return nullptr;
     224             : 
     225           1 :     char **papszIMD = nullptr;
     226             : 
     227          10 :     for (int i = 0; papszLines[i] != nullptr; i++)
     228             :     {
     229           9 :         const char *pszLine = papszLines[i];
     230           9 :         if (CPLStrnlen(pszLine, 21) >= 21)
     231             :         {
     232             :             char szName[22];
     233           9 :             memcpy(szName, pszLine, 21);
     234           9 :             szName[21] = 0;
     235           9 :             char *pszSpace = strchr(szName, ' ');
     236           9 :             if (pszSpace)
     237             :             {
     238           9 :                 *pszSpace = 0;
     239           9 :                 papszIMD = CSLAddNameValue(papszIMD, szName, pszLine + 20);
     240             :             }
     241             :         }
     242             :     }
     243             : 
     244           1 :     CSLDestroy(papszLines);
     245             : 
     246           1 :     return papszIMD;
     247             : }
     248             : 
     249             : /**
     250             :  * GetAcqisitionTimeFromString()
     251             :  */
     252           1 : GIntBig GDALMDReaderEROS::GetAcquisitionTimeFromString(const char *pszDateTime)
     253             : {
     254           1 :     if (nullptr == pszDateTime)
     255           0 :         return 0;
     256             : 
     257             :     int iYear;
     258             :     int iMonth;
     259             :     int iDay;
     260             :     int iHours;
     261             :     int iMin;
     262             :     int iSec;
     263             : 
     264             :     // example: sweep_start_utc     2013-04-22,11:35:02.50724
     265             : 
     266           1 :     int r = sscanf(pszDateTime, "%d-%d-%d,%d:%d:%d.%*d", &iYear, &iMonth, &iDay,
     267             :                    &iHours, &iMin, &iSec);
     268             : 
     269           1 :     if (r != 6)
     270           0 :         return 0;
     271             : 
     272             :     struct tm tmDateTime;
     273           1 :     tmDateTime.tm_sec = iSec;
     274           1 :     tmDateTime.tm_min = iMin;
     275           1 :     tmDateTime.tm_hour = iHours;
     276           1 :     tmDateTime.tm_mday = iDay;
     277           1 :     tmDateTime.tm_mon = iMonth - 1;
     278           1 :     tmDateTime.tm_year = iYear - 1900;
     279           1 :     tmDateTime.tm_isdst = -1;
     280             : 
     281           1 :     return CPLYMDHMSToUnixTime(&tmDateTime);
     282             : }

Generated by: LCOV version 1.14