LCOV - code coverage report
Current view: top level - gcore/mdreader - reader_alos.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 128 167 76.6 %
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 Alos 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 "reader_alos.h"
      15             : 
      16             : #include <cstdio>
      17             : #include <cstdlib>
      18             : 
      19             : #include <string>
      20             : 
      21             : #include "cpl_conv.h"
      22             : #include "cpl_error.h"
      23             : #include "cpl_string.h"
      24             : #include "cpl_time.h"
      25             : #include "gdal_mdreader.h"
      26             : 
      27             : /**
      28             :  * GDALMDReaderALOS()
      29             :  */
      30        5079 : GDALMDReaderALOS::GDALMDReaderALOS(const char *pszPath,
      31        5079 :                                    char **papszSiblingFiles)
      32        5079 :     : GDALMDReaderBase(pszPath, papszSiblingFiles)
      33             : {
      34       10158 :     CPLString osDirName = CPLGetDirname(pszPath);
      35       10158 :     CPLString osBaseName = CPLGetBasename(pszPath);
      36             : 
      37             :     CPLString osIMDSourceFilename =
      38       10158 :         CPLFormFilename(osDirName, "summary", ".txt");
      39        5079 :     if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
      40             :     {
      41           1 :         m_osIMDSourceFilename = std::move(osIMDSourceFilename);
      42             :     }
      43             :     else
      44             :     {
      45        5078 :         osIMDSourceFilename = CPLFormFilename(osDirName, "SUMMARY", ".TXT");
      46        5078 :         if (CPLCheckForFile(&osIMDSourceFilename[0], papszSiblingFiles))
      47             :         {
      48           0 :             m_osIMDSourceFilename = std::move(osIMDSourceFilename);
      49             :         }
      50             :     }
      51             : 
      52        5079 :     if (osBaseName.size() >= 6)
      53             :     {
      54             :         // check if this is separate band or whole image
      55             :         // test without 6 symbols
      56             :         CPLString osHDRFileName = CPLFormFilename(
      57        6268 :             osDirName, CPLSPrintf("HDR%s", osBaseName + 6), "txt");
      58        3134 :         if (CPLCheckForFile(&osHDRFileName[0], papszSiblingFiles))
      59             :         {
      60           0 :             m_osHDRSourceFilename = std::move(osHDRFileName);
      61             :         }
      62             :         else
      63             :         {
      64             :             osHDRFileName = CPLFormFilename(
      65        3134 :                 osDirName, CPLSPrintf("HDR%s", osBaseName + 6), "TXT");
      66        3134 :             if (CPLCheckForFile(&osHDRFileName[0], papszSiblingFiles))
      67             :             {
      68           0 :                 m_osHDRSourceFilename = std::move(osHDRFileName);
      69             :             }
      70             :         }
      71             :     }
      72             : 
      73             :     // test without 3 symbols
      74        5079 :     if (osBaseName.size() >= 3 && m_osHDRSourceFilename.empty())
      75             :     {
      76             :         CPLString osHDRFileName = CPLFormFilename(
      77       10122 :             osDirName, CPLSPrintf("HDR%s", osBaseName + 3), "txt");
      78        5061 :         if (CPLCheckForFile(&osHDRFileName[0], papszSiblingFiles))
      79             :         {
      80           0 :             m_osHDRSourceFilename = std::move(osHDRFileName);
      81             :         }
      82             :         else
      83             :         {
      84             :             osHDRFileName = CPLFormFilename(
      85        5061 :                 osDirName, CPLSPrintf("HDR%s", osBaseName + 3), "TXT");
      86        5061 :             if (CPLCheckForFile(&osHDRFileName[0], papszSiblingFiles))
      87             :             {
      88           0 :                 m_osHDRSourceFilename = std::move(osHDRFileName);
      89             :             }
      90             :         }
      91             :     }
      92             : 
      93             :     // test without 6 symbols
      94        5079 :     if (osBaseName.size() >= 6)
      95             :     {
      96             :         CPLString osRPCFileName = CPLFormFilename(
      97        6268 :             osDirName, CPLSPrintf("RPC%s", osBaseName + 6), "txt");
      98        3134 :         if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
      99             :         {
     100           0 :             m_osRPBSourceFilename = std::move(osRPCFileName);
     101             :         }
     102             :         else
     103             :         {
     104             :             osRPCFileName = CPLFormFilename(
     105        3134 :                 osDirName, CPLSPrintf("RPC%s", osBaseName + 6), "TXT");
     106        3134 :             if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
     107             :             {
     108           0 :                 m_osRPBSourceFilename = std::move(osRPCFileName);
     109             :             }
     110             :         }
     111             :     }
     112             : 
     113             :     // test without 3 symbols
     114        5079 :     if (osBaseName.size() >= 3 && m_osRPBSourceFilename.empty())
     115             :     {
     116             :         CPLString osRPCFileName = CPLFormFilename(
     117       10122 :             osDirName, CPLSPrintf("RPC%s", osBaseName + 3), "txt");
     118        5061 :         if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
     119             :         {
     120           1 :             m_osRPBSourceFilename = std::move(osRPCFileName);
     121             :         }
     122             :         else
     123             :         {
     124             :             osRPCFileName = CPLFormFilename(
     125        5060 :                 osDirName, CPLSPrintf("RPC%s", osBaseName + 3), "TXT");
     126        5060 :             if (CPLCheckForFile(&osRPCFileName[0], papszSiblingFiles))
     127             :             {
     128           0 :                 m_osRPBSourceFilename = std::move(osRPCFileName);
     129             :             }
     130             :         }
     131             :     }
     132             : 
     133        5079 :     if (!m_osIMDSourceFilename.empty())
     134           1 :         CPLDebug("MDReaderALOS", "IMD Filename: %s",
     135             :                  m_osIMDSourceFilename.c_str());
     136        5079 :     if (!m_osHDRSourceFilename.empty())
     137           0 :         CPLDebug("MDReaderALOS", "HDR Filename: %s",
     138             :                  m_osHDRSourceFilename.c_str());
     139        5079 :     if (!m_osRPBSourceFilename.empty())
     140           1 :         CPLDebug("MDReaderALOS", "RPB Filename: %s",
     141             :                  m_osRPBSourceFilename.c_str());
     142        5079 : }
     143             : 
     144             : /**
     145             :  * ~GDALMDReaderALOS()
     146             :  */
     147       10158 : GDALMDReaderALOS::~GDALMDReaderALOS()
     148             : {
     149       10158 : }
     150             : 
     151             : /**
     152             :  * HasRequiredFiles()
     153             :  */
     154        5079 : bool GDALMDReaderALOS::HasRequiredFiles() const
     155             : {
     156        5079 :     if (!m_osIMDSourceFilename.empty())
     157           1 :         return true;
     158             : 
     159        5078 :     if (!m_osHDRSourceFilename.empty() && !m_osRPBSourceFilename.empty())
     160           0 :         return true;
     161             : 
     162        5078 :     return false;
     163             : }
     164             : 
     165             : /**
     166             :  * GetMetadataFiles()
     167             :  */
     168           1 : char **GDALMDReaderALOS::GetMetadataFiles() const
     169             : {
     170           1 :     char **papszFileList = nullptr;
     171           1 :     if (!m_osIMDSourceFilename.empty())
     172           1 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
     173           1 :     if (!m_osHDRSourceFilename.empty())
     174           0 :         papszFileList = CSLAddString(papszFileList, m_osHDRSourceFilename);
     175           1 :     if (!m_osRPBSourceFilename.empty())
     176           1 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
     177             : 
     178           1 :     return papszFileList;
     179             : }
     180             : 
     181             : /**
     182             :  * LoadMetadata()
     183             :  */
     184           2 : void GDALMDReaderALOS::LoadMetadata()
     185             : {
     186           2 :     if (m_bIsMetadataLoad)
     187           1 :         return;
     188             : 
     189           1 :     if (!m_osIMDSourceFilename.empty())
     190             :     {
     191           1 :         m_papszIMDMD = CSLLoad(m_osIMDSourceFilename);
     192             :     }
     193             : 
     194           1 :     if (!m_osHDRSourceFilename.empty())
     195             :     {
     196           0 :         if (nullptr == m_papszIMDMD)
     197             :         {
     198           0 :             m_papszIMDMD = CSLLoad(m_osHDRSourceFilename);
     199             :         }
     200             :         else
     201             :         {
     202           0 :             char **papszHDR = CSLLoad(m_osHDRSourceFilename);
     203           0 :             m_papszIMDMD = CSLMerge(m_papszIMDMD, papszHDR);
     204           0 :             CSLDestroy(papszHDR);
     205             :         }
     206             :     }
     207             : 
     208           1 :     m_papszRPCMD = LoadRPCTxtFile();
     209             : 
     210           1 :     m_papszDEFAULTMD =
     211           1 :         CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ALOS");
     212             : 
     213           1 :     m_bIsMetadataLoad = true;
     214             : 
     215           1 :     const char *pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "Lbi_Satellite");
     216           1 :     const char *pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "Lbi_Sensor");
     217           1 :     if (nullptr != pszSatId1 && nullptr != pszSatId2)
     218             :     {
     219           2 :         m_papszIMAGERYMD = CSLAddNameValue(
     220             :             m_papszIMAGERYMD, MD_NAME_SATELLITE,
     221           2 :             CPLSPrintf("%s %s", CPLStripQuotes(pszSatId1).c_str(),
     222           2 :                        CPLStripQuotes(pszSatId2).c_str()));
     223             :     }
     224           0 :     else if (nullptr != pszSatId1 && nullptr == pszSatId2)
     225             :     {
     226           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     227           0 :                                            CPLStripQuotes(pszSatId1));
     228             :     }
     229           0 :     else if (nullptr == pszSatId1 && nullptr != pszSatId2)
     230             :     {
     231           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     232           0 :                                            CPLStripQuotes(pszSatId2));
     233             :     }
     234             : 
     235             :     const char *pszCloudCover =
     236           1 :         CSLFetchNameValue(m_papszIMDMD, "Img_CloudQuantityOfAllImage");
     237           1 :     if (nullptr != pszCloudCover)
     238             :     {
     239           0 :         int nCC = atoi(pszCloudCover);
     240           0 :         if (nCC >= 99)
     241             :         {
     242           0 :             m_papszIMAGERYMD = CSLAddNameValue(
     243             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     244             :         }
     245             :         else
     246             :         {
     247           0 :             m_papszIMAGERYMD =
     248           0 :                 CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER,
     249             :                                 CPLSPrintf("%d", nCC * 10));
     250             :         }
     251             :     }
     252             : 
     253             :     const char *pszDate =
     254           1 :         CSLFetchNameValue(m_papszIMDMD, "Img_SceneCenterDateTime");
     255             : 
     256           1 :     if (nullptr != pszDate)
     257             :     {
     258             :         char buffer[80];
     259           0 :         GIntBig timeMid = GetAcquisitionTimeFromString(CPLStripQuotes(pszDate));
     260             :         struct tm tmBuf;
     261           0 :         strftime(buffer, 80, MD_DATETIMEFORMAT,
     262           0 :                  CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
     263           0 :         m_papszIMAGERYMD =
     264           0 :             CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
     265             :     }
     266             :     else
     267             :     {
     268           1 :         pszDate = CSLFetchNameValue(m_papszIMDMD, "Lbi_ObservationDate");
     269           1 :         if (nullptr != pszDate)
     270             :         {
     271           1 :             const char *pszTime = "00:00:00.000";
     272             : 
     273             :             char buffer[80];
     274           2 :             GIntBig timeMid = GetAcquisitionTimeFromString(
     275           2 :                 CPLSPrintf("%s %s", CPLStripQuotes(pszDate).c_str(),
     276           2 :                            CPLStripQuotes(pszTime).c_str()));
     277             :             struct tm tmBuf;
     278           1 :             strftime(buffer, 80, MD_DATETIMEFORMAT,
     279           1 :                      CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
     280           1 :             m_papszIMAGERYMD =
     281           1 :                 CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
     282             :         }
     283             :     }
     284             : }
     285             : 
     286             : /**
     287             :  * LoadRPCTxtFile
     288             :  */
     289           1 : char **GDALMDReaderALOS::LoadRPCTxtFile()
     290             : {
     291           1 :     if (m_osRPBSourceFilename.empty())
     292           0 :         return nullptr;
     293             : 
     294           2 :     const CPLStringList aosLines(CSLLoad(m_osRPBSourceFilename));
     295           1 :     if (aosLines.empty())
     296           0 :         return nullptr;
     297             : 
     298           1 :     const char *pszFirstRow = aosLines[0];
     299           2 :     CPLStringList aosRPB;
     300           1 :     if (nullptr != pszFirstRow)
     301             :     {
     302             :         static const struct
     303             :         {
     304             :             const char *pszName;
     305             :             int nSize;
     306             :         } apsFieldDescriptors[] = {
     307             :             {RPC_LINE_OFF, 6},     {RPC_SAMP_OFF, 5},   {RPC_LAT_OFF, 8},
     308             :             {RPC_LONG_OFF, 9},     {RPC_HEIGHT_OFF, 5}, {RPC_LINE_SCALE, 6},
     309             :             {RPC_SAMP_SCALE, 5},   {RPC_LAT_SCALE, 8},  {RPC_LONG_SCALE, 9},
     310             :             {RPC_HEIGHT_SCALE, 5},
     311             :         };
     312             : 
     313           1 :         int nRequiredSize = 0;
     314          11 :         for (const auto &sFieldDescriptor : apsFieldDescriptors)
     315             :         {
     316          10 :             nRequiredSize += sFieldDescriptor.nSize;
     317             :         }
     318             : 
     319             :         static const char *const apszRPCTXT20ValItems[] = {
     320             :             RPC_LINE_NUM_COEFF, RPC_LINE_DEN_COEFF, RPC_SAMP_NUM_COEFF,
     321             :             RPC_SAMP_DEN_COEFF};
     322             : 
     323           1 :         constexpr int RPC_COEFF_COUNT1 = CPL_ARRAYSIZE(apszRPCTXT20ValItems);
     324           1 :         constexpr int RPC_COEFF_COUNT2 = 20;
     325           1 :         constexpr int RPC_COEFF_SIZE = 12;
     326           1 :         nRequiredSize += RPC_COEFF_COUNT1 * RPC_COEFF_COUNT2 * RPC_COEFF_SIZE;
     327           1 :         if (strlen(pszFirstRow) < static_cast<size_t>(nRequiredSize))
     328             :         {
     329           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     330             :                      "%s has only %d bytes wherea %d are required",
     331           0 :                      m_osRPBSourceFilename.c_str(), int(strlen(pszFirstRow)),
     332             :                      nRequiredSize);
     333           0 :             return nullptr;
     334             :         }
     335             : 
     336           1 :         int nOffset = 0;
     337           1 :         char buff[16] = {0};
     338          11 :         for (const auto &sFieldDescriptor : apsFieldDescriptors)
     339             :         {
     340          10 :             CPLAssert(sFieldDescriptor.nSize < int(sizeof(buff)));
     341          10 :             memcpy(buff, pszFirstRow + nOffset, sFieldDescriptor.nSize);
     342          10 :             buff[sFieldDescriptor.nSize] = 0;
     343          10 :             aosRPB.SetNameValue(sFieldDescriptor.pszName, buff);
     344          10 :             nOffset += sFieldDescriptor.nSize;
     345             :         }
     346             : 
     347           5 :         for (const char *pszItem : apszRPCTXT20ValItems)
     348             :         {
     349           8 :             std::string osValue;
     350          84 :             for (int j = 0; j < RPC_COEFF_COUNT2; j++)
     351             :             {
     352          80 :                 memcpy(buff, pszFirstRow + nOffset, RPC_COEFF_SIZE);
     353          80 :                 buff[RPC_COEFF_SIZE] = 0;
     354          80 :                 nOffset += RPC_COEFF_SIZE;
     355             : 
     356          80 :                 if (!osValue.empty())
     357          76 :                     osValue += " ";
     358          80 :                 osValue += buff;
     359             :             }
     360           4 :             aosRPB.SetNameValue(pszItem, osValue.c_str());
     361             :         }
     362             :     }
     363             : 
     364           1 :     return aosRPB.StealList();
     365             : }
     366             : 
     367             : /**
     368             :  * GetAcqisitionTimeFromString()
     369             :  */
     370           1 : GIntBig GDALMDReaderALOS::GetAcquisitionTimeFromString(const char *pszDateTime)
     371             : {
     372           1 :     if (nullptr == pszDateTime)
     373           0 :         return 0;
     374             : 
     375             :     int iYear;
     376             :     int iMonth;
     377             :     int iDay;
     378             :     int iHours;
     379             :     int iMin;
     380             :     int iSec;
     381             : 
     382           1 :     int r = sscanf(pszDateTime, "%4d%2d%2d %d:%d:%d.%*d", &iYear, &iMonth,
     383             :                    &iDay, &iHours, &iMin, &iSec);
     384             : 
     385           1 :     if (r != 6)
     386           0 :         return 0;
     387             : 
     388             :     struct tm tmDateTime;
     389           1 :     tmDateTime.tm_sec = iSec;
     390           1 :     tmDateTime.tm_min = iMin;
     391           1 :     tmDateTime.tm_hour = iHours;
     392           1 :     tmDateTime.tm_mday = iDay;
     393           1 :     tmDateTime.tm_mon = iMonth - 1;
     394           1 :     tmDateTime.tm_year = iYear - 1900;
     395           1 :     tmDateTime.tm_isdst = -1;
     396             : 
     397           1 :     return CPLYMDHMSToUnixTime(&tmDateTime);
     398             : }

Generated by: LCOV version 1.14