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

Generated by: LCOV version 1.14