LCOV - code coverage report
Current view: top level - gcore/mdreader - reader_geo_eye.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 133 152 87.5 %
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 GeoEye 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_geo_eye.h"
      16             : 
      17             : #include <cstddef>
      18             : #include <cstdio>
      19             : #include <cstring>
      20             : 
      21             : #include <string>
      22             : 
      23             : #include "cpl_conv.h"
      24             : #include "cpl_error.h"
      25             : #include "cpl_string.h"
      26             : #include "cpl_time.h"
      27             : 
      28             : /**
      29             :  * GDALMDReaderGeoEye()
      30             :  */
      31        5112 : GDALMDReaderGeoEye::GDALMDReaderGeoEye(const char *pszPath,
      32        5112 :                                        char **papszSiblingFiles)
      33        5112 :     : GDALMDReaderBase(pszPath, papszSiblingFiles)
      34             : {
      35             : 
      36       10224 :     const CPLString osBaseName = CPLGetBasename(pszPath);
      37       10224 :     const CPLString osDirName = CPLGetDirname(pszPath);
      38             : 
      39             :     // get _metadata.txt file
      40             : 
      41             :     // split file name by _rgb_ or _pan_
      42       10224 :     CPLString osRadixMetadataName(osBaseName);
      43        5112 :     size_t i = osRadixMetadataName.ifind("_rgb_");
      44        5112 :     if (i == std::string::npos)
      45        5106 :         i = osRadixMetadataName.ifind("_pan_");
      46        5112 :     if (i != std::string::npos)
      47           6 :         osRadixMetadataName.resize(i);
      48             : 
      49             :     // form metadata file name
      50             :     std::string osIMDSourceFilename = CPLFormFilename(
      51       15336 :         osDirName, (osRadixMetadataName + "_metadata.txt").c_str(), nullptr);
      52        5112 :     if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
      53             :     {
      54           5 :         m_osIMDSourceFilename = std::move(osIMDSourceFilename);
      55             :     }
      56             :     else
      57             :     {
      58             :         osIMDSourceFilename = CPLFormFilename(
      59       10214 :             osDirName, (osRadixMetadataName + "_METADATA.txt").c_str(),
      60        5107 :             nullptr);
      61        5107 :         if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
      62             :         {
      63           0 :             m_osIMDSourceFilename = std::move(osIMDSourceFilename);
      64             :         }
      65             :     }
      66             : 
      67             :     // get _rpc.txt file
      68             : 
      69             :     std::string osRPBSourceFilename =
      70       15336 :         CPLFormFilename(osDirName, (osBaseName + "_rpc").c_str(), "txt");
      71        5112 :     if (CPLCheckForFile(&osRPBSourceFilename[0], papszSiblingFiles))
      72             :     {
      73          12 :         m_osRPBSourceFilename = std::move(osRPBSourceFilename);
      74             :     }
      75             :     else
      76             :     {
      77             :         osRPBSourceFilename =
      78        5100 :             CPLFormFilename(osDirName, (osBaseName + "_RPC").c_str(), "TXT");
      79        5100 :         if (CPLCheckForFile(&osRPBSourceFilename[0], papszSiblingFiles))
      80             :         {
      81           0 :             m_osRPBSourceFilename = std::move(osRPBSourceFilename);
      82             :         }
      83             :     }
      84             : 
      85        5112 :     if (!m_osIMDSourceFilename.empty())
      86           5 :         CPLDebug("MDReaderGeoEye", "IMD Filename: %s",
      87             :                  m_osIMDSourceFilename.c_str());
      88        5112 :     if (!m_osRPBSourceFilename.empty())
      89          12 :         CPLDebug("MDReaderGeoEye", "RPB Filename: %s",
      90             :                  m_osRPBSourceFilename.c_str());
      91        5112 : }
      92             : 
      93             : /**
      94             :  * ~GDALMDReaderGeoEye()
      95             :  */
      96       10224 : GDALMDReaderGeoEye::~GDALMDReaderGeoEye()
      97             : {
      98       10224 : }
      99             : 
     100             : /**
     101             :  * HasRequiredFiles()
     102             :  */
     103        5112 : bool GDALMDReaderGeoEye::HasRequiredFiles() const
     104             : {
     105        5112 :     if (!m_osIMDSourceFilename.empty())
     106           5 :         return true;
     107             : 
     108        5107 :     if (!m_osRPBSourceFilename.empty())
     109           7 :         return true;
     110             : 
     111        5100 :     return false;
     112             : }
     113             : 
     114             : /**
     115             :  * GetMetadataFiles()
     116             :  */
     117          12 : char **GDALMDReaderGeoEye::GetMetadataFiles() const
     118             : {
     119          12 :     char **papszFileList = nullptr;
     120          12 :     if (!m_osIMDSourceFilename.empty())
     121           5 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
     122          12 :     if (!m_osRPBSourceFilename.empty())
     123          12 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
     124             : 
     125          12 :     return papszFileList;
     126             : }
     127             : 
     128             : /**
     129             :  * LoadMetadata()
     130             :  */
     131          24 : void GDALMDReaderGeoEye::LoadMetadata()
     132             : {
     133          24 :     if (m_bIsMetadataLoad)
     134          12 :         return;
     135             : 
     136          12 :     if (!m_osIMDSourceFilename.empty())
     137             :     {
     138           5 :         m_papszIMDMD = LoadIMDWktFile();
     139             :     }
     140             : 
     141          12 :     if (!m_osRPBSourceFilename.empty())
     142             :     {
     143          12 :         m_papszRPCMD = GDALLoadRPCFile(m_osRPBSourceFilename);
     144             :     }
     145             : 
     146          12 :     m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "GE");
     147             : 
     148          12 :     m_bIsMetadataLoad = true;
     149             : 
     150          12 :     if (nullptr == m_papszIMDMD)
     151             :     {
     152           7 :         return;
     153             :     }
     154             : 
     155             :     // extract imagery metadata
     156             :     const char *pszSatId =
     157           5 :         CSLFetchNameValue(m_papszIMDMD, "Source Image Metadata.Sensor");
     158           5 :     if (nullptr != pszSatId)
     159             :     {
     160           5 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     161          10 :                                            CPLStripQuotes(pszSatId));
     162             :     }
     163             : 
     164          10 :     const char *pszCloudCover = CSLFetchNameValue(
     165           5 :         m_papszIMDMD, "Source Image Metadata.Percent Cloud Cover");
     166           5 :     if (nullptr != pszCloudCover)
     167             :     {
     168           5 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     169             :                                            pszCloudCover);
     170             :     }
     171             : 
     172          10 :     const char *pszDateTime = CSLFetchNameValue(
     173           5 :         m_papszIMDMD, "Source Image Metadata.Acquisition Date/Time");
     174             : 
     175           5 :     if (nullptr != pszDateTime)
     176             :     {
     177             :         char buffer[80];
     178           5 :         GIntBig timeMid = GetAcquisitionTimeFromString(pszDateTime);
     179             : 
     180             :         struct tm tmBuf;
     181           5 :         strftime(buffer, 80, MD_DATETIMEFORMAT,
     182           5 :                  CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
     183           5 :         m_papszIMAGERYMD =
     184           5 :             CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
     185             :     }
     186             : }
     187             : 
     188             : /**
     189             :  * GetAcqisitionTimeFromString()
     190             :  */
     191             : GIntBig
     192           5 : GDALMDReaderGeoEye::GetAcquisitionTimeFromString(const char *pszDateTime)
     193             : {
     194           5 :     if (nullptr == pszDateTime)
     195           0 :         return 0;
     196             : 
     197             :     int iYear;
     198             :     int iMonth;
     199             :     int iDay;
     200             :     int iHours;
     201             :     int iMin;
     202           5 :     int iSec = 0;
     203             : 
     204             :     // string example: Acquisition Date/Time: 2006-03-01 11:08 GMT
     205             : 
     206           5 :     int r = sscanf(pszDateTime, "%d-%d-%d %d:%d GMT", &iYear, &iMonth, &iDay,
     207             :                    &iHours, &iMin);
     208             : 
     209           5 :     if (r != 5)
     210           0 :         return 0;
     211             : 
     212             :     struct tm tmDateTime;
     213           5 :     tmDateTime.tm_sec = iSec;
     214           5 :     tmDateTime.tm_min = iMin;
     215           5 :     tmDateTime.tm_hour = iHours;
     216           5 :     tmDateTime.tm_mday = iDay;
     217           5 :     tmDateTime.tm_mon = iMonth - 1;
     218           5 :     tmDateTime.tm_year = iYear - 1900;
     219           5 :     tmDateTime.tm_isdst = -1;
     220             : 
     221           5 :     return CPLYMDHMSToUnixTime(&tmDateTime);
     222             : }
     223             : 
     224             : /**
     225             :  * LoadWKTIMDFile()
     226             :  */
     227           5 : char **GDALMDReaderGeoEye::LoadIMDWktFile() const
     228             : {
     229           5 :     char **papszResultList = nullptr;
     230           5 :     char **papszLines = CSLLoad(m_osIMDSourceFilename);
     231           5 :     bool bBeginSection = false;
     232          10 :     CPLString osSection;
     233          10 :     CPLString osKeyLevel1;
     234          10 :     CPLString osKeyLevel2;
     235          10 :     CPLString osKeyLevel3;
     236           5 :     int nLevel = 0;
     237             :     int nSpaceCount;
     238             : 
     239           5 :     if (papszLines == nullptr)
     240           0 :         return nullptr;
     241             : 
     242         475 :     for (int i = 0; papszLines[i] != nullptr; i++)
     243             :     {
     244             :         // skip section (=== or ---) lines
     245             : 
     246         470 :         if (STARTS_WITH_CI(papszLines[i], "==="))
     247             :         {
     248          30 :             bBeginSection = true;
     249         120 :             continue;
     250             :         }
     251             : 
     252         870 :         if (STARTS_WITH_CI(papszLines[i], "---") ||
     253         430 :             CPLStrnlen(papszLines[i], 512) == 0)
     254          90 :             continue;
     255             : 
     256             :         // check the metadata level
     257         350 :         nSpaceCount = 0;
     258         590 :         for (int j = 0; j < 11; j++)
     259             :         {
     260         590 :             if (papszLines[i][j] != ' ')
     261         350 :                 break;
     262         240 :             nSpaceCount++;
     263             :         }
     264             : 
     265         350 :         if (nSpaceCount % 3 != 0)
     266           0 :             continue;  // not a metadata item
     267         350 :         nLevel = nSpaceCount / 3;
     268             : 
     269             :         const char *pszValue;
     270         350 :         char *pszKey = nullptr;
     271         350 :         pszValue = CPLParseNameValue(papszLines[i], &pszKey);
     272             : 
     273         350 :         if (nullptr != pszValue && CPLStrnlen(pszValue, 512) > 0)
     274             :         {
     275             : 
     276         310 :             CPLString osCurrentKey;
     277         310 :             if (nLevel == 0)
     278             :             {
     279         230 :                 osCurrentKey = CPLOPrintf("%s", pszKey);
     280             :             }
     281          80 :             else if (nLevel == 1)
     282             :             {
     283             :                 osCurrentKey =
     284          80 :                     osKeyLevel1 + "." + CPLOPrintf("%s", pszKey + nSpaceCount);
     285             :             }
     286           0 :             else if (nLevel == 2)
     287             :             {
     288           0 :                 osCurrentKey = osKeyLevel1 + "." + osKeyLevel2 + "." +
     289           0 :                                CPLOPrintf("%s", pszKey + nSpaceCount);
     290             :             }
     291           0 :             else if (nLevel == 3)
     292             :             {
     293           0 :                 osCurrentKey = osKeyLevel1 + "." + osKeyLevel2 + "." +
     294           0 :                                osKeyLevel3 + "." +
     295           0 :                                CPLOPrintf("%s", pszKey + nSpaceCount);
     296             :             }
     297             : 
     298         310 :             if (!osSection.empty())
     299             :             {
     300         305 :                 osCurrentKey = osSection + "." + osCurrentKey;
     301             :             }
     302             : 
     303             :             papszResultList =
     304         310 :                 CSLAddNameValue(papszResultList, osCurrentKey, pszValue);
     305             :         }
     306             : 
     307         350 :         if (nullptr != pszKey && CPLStrnlen(pszKey, 512) > 0)
     308             :         {
     309         310 :             if (bBeginSection)
     310             :             {
     311           5 :                 osSection = CPLOPrintf("%s", pszKey);
     312           5 :                 bBeginSection = false;
     313             :             }
     314         305 :             else if (nLevel == 0)
     315             :             {
     316         225 :                 osKeyLevel1 = CPLOPrintf("%s", pszKey);
     317             :             }
     318          80 :             else if (nLevel == 1)
     319             :             {
     320          80 :                 osKeyLevel2 = CPLOPrintf("%s", pszKey + nSpaceCount);
     321             :             }
     322           0 :             else if (nLevel == 2)
     323             :             {
     324           0 :                 osKeyLevel3 = CPLOPrintf("%s", pszKey + nSpaceCount);
     325             :             }
     326             :         }
     327             :         else
     328             :         {
     329          40 :             if (bBeginSection)
     330             :             {
     331          20 :                 osSection = CPLOPrintf("%s", papszLines[i]);
     332          20 :                 bBeginSection = false;
     333             :             }
     334          20 :             else if (nLevel == 0)
     335             :             {
     336          20 :                 osKeyLevel1 = CPLOPrintf("%s", papszLines[i]);
     337             :             }
     338           0 :             else if (nLevel == 1)
     339             :             {
     340           0 :                 osKeyLevel2 = CPLOPrintf("%s", papszLines[i] + nSpaceCount);
     341             :             }
     342           0 :             else if (nLevel == 2)
     343             :             {
     344           0 :                 osKeyLevel3 = CPLOPrintf("%s", papszLines[i] + nSpaceCount);
     345             :             }
     346             :         }
     347             : 
     348         350 :         CPLFree(pszKey);
     349             :     }
     350             : 
     351           5 :     CSLDestroy(papszLines);
     352             : 
     353           5 :     return papszResultList;
     354             : }

Generated by: LCOV version 1.14