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

Generated by: LCOV version 1.14