LCOV - code coverage report
Current view: top level - gcore/mdreader - reader_kompsat.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 86 110 78.2 %
Date: 2024-05-15 13:15:52 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL Core
       4             :  * Purpose:  Read metadata from Kompsat 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_kompsat.h"
      32             : 
      33             : #include <cstddef>
      34             : #include <cstdio>
      35             : #include <cstdlib>
      36             : 
      37             : #include "cpl_error.h"
      38             : #include "cpl_string.h"
      39             : #include "cpl_time.h"
      40             : 
      41             : #include "gdal_mdreader.h"
      42             : #include "gdal_priv.h"
      43             : 
      44             : /**
      45             :  * GDALMDReaderKompsat()
      46             :  */
      47        5028 : GDALMDReaderKompsat::GDALMDReaderKompsat(const char *pszPath,
      48        5028 :                                          char **papszSiblingFiles)
      49             :     : GDALMDReaderBase(pszPath, papszSiblingFiles),
      50             :       m_osIMDSourceFilename(
      51             :           GDALFindAssociatedFile(pszPath, "TXT", papszSiblingFiles, 0)),
      52             :       m_osRPBSourceFilename(
      53        5028 :           GDALFindAssociatedFile(pszPath, "RPC", papszSiblingFiles, 0))
      54             : {
      55        5028 :     if (!m_osIMDSourceFilename.empty())
      56           2 :         CPLDebug("MDReaderDigitalGlobe", "IMD Filename: %s",
      57             :                  m_osIMDSourceFilename.c_str());
      58        5028 :     if (!m_osRPBSourceFilename.empty())
      59           3 :         CPLDebug("MDReaderDigitalGlobe", "RPB Filename: %s",
      60             :                  m_osRPBSourceFilename.c_str());
      61        5028 : }
      62             : 
      63             : /**
      64             :  * ~GDALMDReaderKompsat()
      65             :  */
      66       10056 : GDALMDReaderKompsat::~GDALMDReaderKompsat()
      67             : {
      68       10056 : }
      69             : 
      70             : /**
      71             :  * HasRequiredFiles()
      72             :  */
      73        5028 : bool GDALMDReaderKompsat::HasRequiredFiles() const
      74             : {
      75        5028 :     if (!m_osIMDSourceFilename.empty() && !m_osRPBSourceFilename.empty())
      76           2 :         return true;
      77             : 
      78        5026 :     return false;
      79             : }
      80             : 
      81             : /**
      82             :  * GetMetadataFiles()
      83             :  */
      84           2 : char **GDALMDReaderKompsat::GetMetadataFiles() const
      85             : {
      86           2 :     char **papszFileList = nullptr;
      87           2 :     if (!m_osIMDSourceFilename.empty())
      88           2 :         papszFileList = CSLAddString(papszFileList, m_osIMDSourceFilename);
      89           2 :     if (!m_osRPBSourceFilename.empty())
      90           2 :         papszFileList = CSLAddString(papszFileList, m_osRPBSourceFilename);
      91             : 
      92           2 :     return papszFileList;
      93             : }
      94             : 
      95             : /**
      96             :  * LoadMetadata()
      97             :  */
      98           4 : void GDALMDReaderKompsat::LoadMetadata()
      99             : {
     100           4 :     if (m_bIsMetadataLoad)
     101           2 :         return;
     102             : 
     103           2 :     if (!m_osIMDSourceFilename.empty())
     104             :     {
     105           2 :         m_papszIMDMD = ReadTxtToList();
     106             :     }
     107             : 
     108           2 :     if (!m_osRPBSourceFilename.empty())
     109             :     {
     110           2 :         m_papszRPCMD = GDALLoadRPCFile(m_osRPBSourceFilename);
     111             :     }
     112             : 
     113           2 :     m_papszDEFAULTMD =
     114           2 :         CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "KARI");
     115             : 
     116           2 :     m_bIsMetadataLoad = true;
     117             : 
     118             :     const char *pszSatId1 =
     119           2 :         CSLFetchNameValue(m_papszIMDMD, "AUX_SATELLITE_NAME");
     120             :     const char *pszSatId2 =
     121           2 :         CSLFetchNameValue(m_papszIMDMD, "AUX_SATELLITE_SENSOR");
     122           2 :     if (nullptr != pszSatId1 && nullptr != pszSatId2)
     123             :     {
     124           4 :         m_papszIMAGERYMD = CSLAddNameValue(
     125             :             m_papszIMAGERYMD, MD_NAME_SATELLITE,
     126           4 :             CPLSPrintf("%s %s", CPLStripQuotes(pszSatId1).c_str(),
     127           4 :                        CPLStripQuotes(pszSatId2).c_str()));
     128             :     }
     129           0 :     else if (nullptr != pszSatId1 && nullptr == pszSatId2)
     130             :     {
     131           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     132           0 :                                            CPLStripQuotes(pszSatId1));
     133             :     }
     134           0 :     else if (nullptr == pszSatId1 && nullptr != pszSatId2)
     135             :     {
     136           0 :         m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE,
     137           0 :                                            CPLStripQuotes(pszSatId2));
     138             :     }
     139             : 
     140             :     const char *pszCloudCover =
     141           2 :         CSLFetchNameValue(m_papszIMDMD, "AUX_CLOUD_STATUS");
     142           2 :     if (nullptr != pszCloudCover)
     143             :     {
     144           2 :         int nCC = atoi(pszCloudCover);
     145           2 :         if (nCC > 100 || nCC < 0)
     146             :         {
     147           0 :             m_papszIMAGERYMD = CSLAddNameValue(
     148             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA);
     149             :         }
     150             :         else
     151             :         {
     152           2 :             m_papszIMAGERYMD = CSLAddNameValue(
     153             :                 m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", nCC));
     154             :         }
     155             :     }
     156             : 
     157             :     const char *pszDate =
     158           2 :         CSLFetchNameValue(m_papszIMDMD, "AUX_STRIP_ACQ_DATE_UT");
     159           2 :     if (nullptr != pszDate)
     160             :     {
     161             :         const char *pszTime =
     162           2 :             CSLFetchNameValue(m_papszIMDMD, "AUX_STRIP_ACQ_START_UT");
     163             : 
     164           2 :         if (nullptr == pszTime)
     165           0 :             pszTime = "000000.000000";
     166             : 
     167             :         char buffer[80];
     168             :         GIntBig timeMid =
     169           2 :             GetAcquisitionTimeFromString(CPLSPrintf("%sT%s", pszDate, pszTime));
     170             :         struct tm tmBuf;
     171           2 :         strftime(buffer, 80, MD_DATETIMEFORMAT,
     172           2 :                  CPLUnixTimeToYMDHMS(timeMid, &tmBuf));
     173           2 :         m_papszIMAGERYMD =
     174           2 :             CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer);
     175             :     }
     176             : }
     177             : 
     178             : /**
     179             :  * ReadTxtToList
     180             :  */
     181           2 : char **GDALMDReaderKompsat::ReadTxtToList()
     182             : {
     183           2 :     char **papszLines = CSLLoad(m_osIMDSourceFilename);
     184           2 :     if (nullptr == papszLines)
     185           0 :         return nullptr;
     186             : 
     187           2 :     char **papszIMD = nullptr;
     188             :     char szName[512];
     189             :     int i;
     190             :     size_t j;
     191           2 :     CPLString soGroupName;
     192             : 
     193          18 :     for (i = 0; papszLines[i] != nullptr; i++)
     194             :     {
     195          16 :         const char *pszLine = papszLines[i];
     196          16 :         const size_t nLineLenLimited = CPLStrnlen(pszLine, 512);
     197             : 
     198             :         // check if this is begin block
     199          16 :         if (STARTS_WITH_CI(pszLine, "BEGIN_"))
     200             :         {
     201           0 :             for (j = 6; j + 1 < nLineLenLimited; j++)
     202             :             {
     203           0 :                 if (STARTS_WITH_CI(pszLine + j, "_BLOCK"))
     204             :                 {
     205           0 :                     szName[j - 6] = 0;
     206           0 :                     break;
     207             :                 }
     208           0 :                 szName[j - 6] = pszLine[j];
     209             :             }
     210           0 :             szName[j - 6] = '\0';
     211             : 
     212           0 :             soGroupName = szName;
     213             : 
     214           0 :             continue;
     215             :         }
     216             : 
     217             :         // check if this is end block
     218          16 :         if (STARTS_WITH_CI(pszLine, "END_"))
     219             :         {
     220           0 :             soGroupName.clear();  // we don't expect subblocks
     221           0 :             continue;
     222             :         }
     223             : 
     224             :         // get name and value
     225         288 :         for (j = 0; j + 1 < nLineLenLimited; j++)
     226             :         {
     227         288 :             if (pszLine[j] == '\t')
     228             :             {
     229          16 :                 if (soGroupName.empty() || j > 0)
     230             :                 {
     231          16 :                     szName[j] = 0;
     232          16 :                     j++;
     233          16 :                     break;
     234             :                 }
     235             :                 else
     236             :                 {
     237           0 :                     continue;
     238             :                 }
     239             :             }
     240         272 :             szName[j] = pszLine[j];
     241             :         }
     242          16 :         szName[j] = '\0';
     243             : 
     244             :         // trim
     245          16 :         while (pszLine[j] == ' ')
     246           0 :             j++;
     247             : 
     248          16 :         if (soGroupName.empty())
     249             :         {
     250          16 :             papszIMD = CSLAddNameValue(papszIMD, szName, pszLine + j);
     251             :         }
     252             :         else
     253             :         {
     254           0 :             papszIMD = CSLAddNameValue(
     255             :                 papszIMD, CPLSPrintf("%s.%s", soGroupName.c_str(), szName),
     256             :                 pszLine + j);
     257             :         }
     258             :     }
     259             : 
     260           2 :     CSLDestroy(papszLines);
     261             : 
     262           2 :     return papszIMD;
     263             : }
     264             : 
     265             : /**
     266             :  * GetAcqisitionTimeFromString()
     267             :  */
     268             : GIntBig
     269           2 : GDALMDReaderKompsat::GetAcquisitionTimeFromString(const char *pszDateTime)
     270             : {
     271           2 :     if (nullptr == pszDateTime)
     272           0 :         return 0;
     273             : 
     274             :     int iYear;
     275             :     int iMonth;
     276             :     int iDay;
     277             :     int iHours;
     278             :     int iMin;
     279             :     int iSec;
     280             : 
     281           2 :     int r = sscanf(pszDateTime, "%4d%2d%2dT%2d%2d%2d.%*s", &iYear, &iMonth,
     282             :                    &iDay, &iHours, &iMin, &iSec);
     283             : 
     284           2 :     if (r != 6)
     285           0 :         return 0;
     286             : 
     287             :     struct tm tmDateTime;
     288           2 :     tmDateTime.tm_sec = iSec;
     289           2 :     tmDateTime.tm_min = iMin;
     290           2 :     tmDateTime.tm_hour = iHours;
     291           2 :     tmDateTime.tm_mday = iDay;
     292           2 :     tmDateTime.tm_mon = iMonth - 1;
     293           2 :     tmDateTime.tm_year = iYear - 1900;
     294           2 :     tmDateTime.tm_isdst = -1;
     295             : 
     296           2 :     return CPLYMDHMSToUnixTime(&tmDateTime);
     297             : }

Generated by: LCOV version 1.14