LCOV - code coverage report
Current view: top level - gcore - gdalgeorefpamdataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 121 123 98.4 %
Date: 2026-06-23 23:27:26 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  GDALPamDataset with internal storage for georeferencing, with
       5             :  *           priority for PAM over internal georeferencing
       6             :  * Author:   Even Rouault <even dot rouault at spatialys.com>
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "gdalgeorefpamdataset.h"
      15             : 
      16             : #include <cstring>
      17             : 
      18             : #include "cpl_conv.h"
      19             : #include "cpl_error.h"
      20             : #include "gdal.h"
      21             : 
      22             : //! @cond Doxygen_Suppress
      23             : /************************************************************************/
      24             : /*                        GDALGeorefPamDataset()                        */
      25             : /************************************************************************/
      26             : 
      27        2429 : GDALGeorefPamDataset::GDALGeorefPamDataset()
      28             :     : bGeoTransformValid(false), nGCPCount(0), pasGCPList(nullptr),
      29             :       m_papszRPC(nullptr), m_bPixelIsPoint(false),
      30             :       m_nGeoTransformGeorefSrcIndex(-1), m_nGCPGeorefSrcIndex(-1),
      31             :       m_nProjectionGeorefSrcIndex(-1), m_nRPCGeorefSrcIndex(-1),
      32             :       m_nPixelIsPointGeorefSrcIndex(-1), m_bGotPAMGeorefSrcIndex(false),
      33        2429 :       m_nPAMGeorefSrcIndex(0), m_bPAMLoaded(false), m_papszMainMD(nullptr)
      34             : {
      35        2429 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                       ~GDALGeorefPamDataset()                        */
      39             : /************************************************************************/
      40             : 
      41        2429 : GDALGeorefPamDataset::~GDALGeorefPamDataset()
      42             : {
      43        2429 :     if (nGCPCount > 0)
      44             :     {
      45          14 :         GDALDeinitGCPs(nGCPCount, pasGCPList);
      46          14 :         CPLFree(pasGCPList);
      47             :     }
      48        2429 :     CSLDestroy(m_papszMainMD);
      49        2429 :     CSLDestroy(m_papszRPC);
      50        2429 : }
      51             : 
      52             : /************************************************************************/
      53             : /*                            GetMetadata()                             */
      54             : /************************************************************************/
      55             : 
      56        1073 : CSLConstList GDALGeorefPamDataset::GetMetadata(const char *pszDomain)
      57             : {
      58        1073 :     if (pszDomain != nullptr && EQUAL(pszDomain, GDAL_MDD_RPC))
      59             :     {
      60          25 :         const int nPAMIndex = GetPAMGeorefSrcIndex();
      61          25 :         if (nPAMIndex >= 0 &&
      62          25 :             ((m_papszRPC != nullptr && nPAMIndex < m_nRPCGeorefSrcIndex) ||
      63          24 :              m_nRPCGeorefSrcIndex < 0 || m_papszRPC == nullptr))
      64             :         {
      65          25 :             CSLConstList papszMD = GDALPamDataset::GetMetadata(pszDomain);
      66          25 :             if (papszMD)
      67           2 :                 return papszMD;
      68             :         }
      69          23 :         return m_papszRPC;
      70             :     }
      71             : 
      72        1048 :     if (pszDomain == nullptr || EQUAL(pszDomain, ""))
      73             :     {
      74         500 :         if (m_papszMainMD)
      75          59 :             return m_papszMainMD;
      76         441 :         m_papszMainMD = CSLDuplicate(GDALPamDataset::GetMetadata(pszDomain));
      77         441 :         const int nPAMIndex = GetPAMGeorefSrcIndex();
      78         441 :         if (nPAMIndex >= 0 &&
      79         441 :             ((m_bPixelIsPoint && nPAMIndex < m_nPixelIsPointGeorefSrcIndex) ||
      80         437 :              m_nPixelIsPointGeorefSrcIndex < 0 || !m_bPixelIsPoint))
      81             :         {
      82         441 :             if (CSLFetchNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT) !=
      83             :                 nullptr)
      84           0 :                 return m_papszMainMD;
      85             :         }
      86         441 :         if (m_bPixelIsPoint)
      87             :         {
      88           4 :             m_papszMainMD = CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT,
      89             :                                             GDALMD_AOP_POINT);
      90             :         }
      91             :         else
      92             :         {
      93         437 :             m_papszMainMD =
      94         437 :                 CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT, nullptr);
      95             :         }
      96         441 :         return m_papszMainMD;
      97             :     }
      98             : 
      99         548 :     return GDALPamDataset::GetMetadata(pszDomain);
     100             : }
     101             : 
     102             : /************************************************************************/
     103             : /*                          GetMetadataItem()                           */
     104             : /************************************************************************/
     105             : 
     106         442 : const char *GDALGeorefPamDataset::GetMetadataItem(const char *pszName,
     107             :                                                   const char *pszDomain)
     108             : {
     109         442 :     if (pszDomain == nullptr || EQUAL(pszDomain, "") ||
     110         234 :         EQUAL(pszDomain, GDAL_MDD_RPC))
     111             :     {
     112         208 :         return CSLFetchNameValue(GetMetadata(pszDomain), pszName);
     113             :     }
     114         234 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
     115             : }
     116             : 
     117             : /************************************************************************/
     118             : /*                             TryLoadXML()                             */
     119             : /************************************************************************/
     120             : 
     121        1232 : CPLErr GDALGeorefPamDataset::TryLoadXML(CSLConstList papszSiblingFiles)
     122             : {
     123        1232 :     m_bPAMLoaded = true;
     124        1232 :     CPLErr eErr = GDALPamDataset::TryLoadXML(papszSiblingFiles);
     125        1232 :     CSLDestroy(m_papszMainMD);
     126        1232 :     m_papszMainMD = nullptr;
     127        1232 :     return eErr;
     128             : }
     129             : 
     130             : /************************************************************************/
     131             : /*                            SetMetadata()                             */
     132             : /************************************************************************/
     133             : 
     134          18 : CPLErr GDALGeorefPamDataset::SetMetadata(CSLConstList papszMetadata,
     135             :                                          const char *pszDomain)
     136             : {
     137          18 :     if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
     138             :     {
     139          18 :         CSLDestroy(m_papszMainMD);
     140          18 :         m_papszMainMD = CSLDuplicate(papszMetadata);
     141             :     }
     142          18 :     return GDALPamDataset::SetMetadata(papszMetadata, pszDomain);
     143             : }
     144             : 
     145             : /************************************************************************/
     146             : /*                            SetMetadata()                             */
     147             : /************************************************************************/
     148             : 
     149         652 : CPLErr GDALGeorefPamDataset::SetMetadataItem(const char *pszName,
     150             :                                              const char *pszValue,
     151             :                                              const char *pszDomain)
     152             : {
     153         652 :     if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
     154             :     {
     155          58 :         CSLConstList papszMD = GetMetadata();
     156          58 :         if (papszMD != m_papszMainMD)
     157             :         {
     158          45 :             CSLDestroy(m_papszMainMD);
     159          45 :             m_papszMainMD = CSLDuplicate(papszMD);
     160             :         }
     161          58 :         m_papszMainMD = CSLSetNameValue(m_papszMainMD, pszName, pszValue);
     162             :     }
     163         652 :     return GDALPamDataset::SetMetadataItem(pszName, pszValue, pszDomain);
     164             : }
     165             : 
     166             : /************************************************************************/
     167             : /*                            GetGCPCount()                             */
     168             : /*                                                                      */
     169             : /*      By default, we let PAM override the value stored                */
     170             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     171             : /************************************************************************/
     172             : 
     173         456 : int GDALGeorefPamDataset::GetGCPCount()
     174             : 
     175             : {
     176         456 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     177         456 :     if (nPAMIndex >= 0 &&
     178         439 :         ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
     179         423 :          m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
     180             :     {
     181         439 :         const int nPAMGCPCount = GDALPamDataset::GetGCPCount();
     182         439 :         if (nPAMGCPCount)
     183           2 :             return nPAMGCPCount;
     184             :     }
     185             : 
     186         454 :     return nGCPCount;
     187             : }
     188             : 
     189             : /************************************************************************/
     190             : /*                          GetGCPSpatialRef()                          */
     191             : /*                                                                      */
     192             : /*      By default, we let PAM override the value stored                */
     193             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     194             : /************************************************************************/
     195             : 
     196           6 : const OGRSpatialReference *GDALGeorefPamDataset::GetGCPSpatialRef() const
     197             : 
     198             : {
     199           6 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     200          12 :     if (nPAMIndex >= 0 &&
     201           6 :         ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
     202           1 :          m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
     203             :     {
     204             :         const OGRSpatialReference *pszPAMGCPSRS =
     205           6 :             GDALPamDataset::GetGCPSpatialRef();
     206           6 :         if (pszPAMGCPSRS != nullptr)
     207           1 :             return pszPAMGCPSRS;
     208             :     }
     209             : 
     210           5 :     if (!m_oSRS.IsEmpty())
     211           5 :         return &m_oSRS;
     212             : 
     213           0 :     return nullptr;
     214             : }
     215             : 
     216             : /************************************************************************/
     217             : /*                               GetGCP()                               */
     218             : /*                                                                      */
     219             : /*      By default, we let PAM override the value stored                */
     220             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     221             : /************************************************************************/
     222             : 
     223           9 : const GDAL_GCP *GDALGeorefPamDataset::GetGCPs()
     224             : 
     225             : {
     226           9 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     227           9 :     if (nPAMIndex >= 0 &&
     228           9 :         ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
     229           4 :          m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
     230             :     {
     231           9 :         const GDAL_GCP *pasPAMGCPList = GDALPamDataset::GetGCPs();
     232           9 :         if (pasPAMGCPList)
     233           1 :             return pasPAMGCPList;
     234             :     }
     235             : 
     236           8 :     return pasGCPList;
     237             : }
     238             : 
     239             : /************************************************************************/
     240             : /*                          GetSpatialRef()                             */
     241             : /*                                                                      */
     242             : /*      By default, we let PAM override the value stored                */
     243             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     244             : /************************************************************************/
     245             : 
     246         365 : const OGRSpatialReference *GDALGeorefPamDataset::GetSpatialRef() const
     247             : 
     248             : {
     249         365 :     if (const_cast<GDALGeorefPamDataset *>(this)->GetGCPCount() > 0)
     250           2 :         return nullptr;
     251             : 
     252         363 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     253         709 :     if (nPAMIndex >= 0 &&
     254         346 :         ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
     255          83 :          m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
     256             :     {
     257         342 :         const OGRSpatialReference *poPAMSRS = GDALPamDataset::GetSpatialRef();
     258         342 :         if (poPAMSRS != nullptr)
     259          20 :             return poPAMSRS;
     260             :     }
     261             : 
     262         343 :     if (!m_oSRS.IsEmpty())
     263         279 :         return &m_oSRS;
     264             : 
     265          64 :     return nullptr;
     266             : }
     267             : 
     268             : /************************************************************************/
     269             : /*                          GetGeoTransform()                           */
     270             : /*                                                                      */
     271             : /*      By default, we let PAM override the value stored                */
     272             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     273             : /************************************************************************/
     274             : 
     275         502 : CPLErr GDALGeorefPamDataset::GetGeoTransform(GDALGeoTransform &gt) const
     276             : 
     277             : {
     278         502 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     279         502 :     if (nPAMIndex >= 0 &&
     280         485 :         ((bGeoTransformValid && nPAMIndex <= m_nGeoTransformGeorefSrcIndex) ||
     281         105 :          m_nGeoTransformGeorefSrcIndex < 0 || !bGeoTransformValid))
     282             :     {
     283         474 :         if (GDALPamDataset::GetGeoTransform(gt) == CE_None)
     284             :         {
     285          14 :             m_nGeoTransformGeorefSrcIndex = nPAMIndex;
     286          14 :             return CE_None;
     287             :         }
     288             :     }
     289             : 
     290         488 :     if (bGeoTransformValid)
     291             :     {
     292         415 :         gt = m_gt;
     293         415 :         return (CE_None);
     294             :     }
     295             : 
     296          73 :     return CE_Failure;
     297             : }
     298             : 
     299             : /************************************************************************/
     300             : /*                     GetPAMGeorefSrcIndex()                           */
     301             : /*                                                                      */
     302             : /*      Get priority index of PAM (the lower, the more priority)      */
     303             : /************************************************************************/
     304        1802 : int GDALGeorefPamDataset::GetPAMGeorefSrcIndex() const
     305             : {
     306        1802 :     if (!m_bGotPAMGeorefSrcIndex)
     307             :     {
     308          23 :         m_bGotPAMGeorefSrcIndex = true;
     309          23 :         const char *pszGeorefSources = CSLFetchNameValueDef(
     310          23 :             papszOpenOptions, "GEOREF_SOURCES",
     311             :             CPLGetConfigOption("GDAL_GEOREF_SOURCES", "PAM,OTHER"));
     312          23 :         char **papszTokens = CSLTokenizeString2(pszGeorefSources, ",", 0);
     313          23 :         m_nPAMGeorefSrcIndex = CSLFindString(papszTokens, "PAM");
     314          23 :         CSLDestroy(papszTokens);
     315             :     }
     316        1802 :     return m_nPAMGeorefSrcIndex;
     317             : }
     318             : 
     319             : //! @endcond

Generated by: LCOV version 1.14