LCOV - code coverage report
Current view: top level - gcore - gdalgeorefpamdataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 120 122 98.4 %
Date: 2025-07-09 17:50:03 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        2422 : 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        2422 :       m_nPAMGeorefSrcIndex(0), m_bPAMLoaded(false), m_papszMainMD(nullptr)
      34             : {
      35        2422 : }
      36             : 
      37             : /************************************************************************/
      38             : /*                       ~GDALGeorefPamDataset()                        */
      39             : /************************************************************************/
      40             : 
      41        2422 : GDALGeorefPamDataset::~GDALGeorefPamDataset()
      42             : {
      43        2422 :     if (nGCPCount > 0)
      44             :     {
      45          14 :         GDALDeinitGCPs(nGCPCount, pasGCPList);
      46          14 :         CPLFree(pasGCPList);
      47             :     }
      48        2422 :     CSLDestroy(m_papszMainMD);
      49        2422 :     CSLDestroy(m_papszRPC);
      50        2422 : }
      51             : 
      52             : /************************************************************************/
      53             : /*                          GetMetadata()                               */
      54             : /************************************************************************/
      55             : 
      56         837 : char **GDALGeorefPamDataset::GetMetadata(const char *pszDomain)
      57             : {
      58         837 :     if (pszDomain != nullptr && EQUAL(pszDomain, "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 :             char **papszMD = GDALPamDataset::GetMetadata(pszDomain);
      66          25 :             if (papszMD)
      67           2 :                 return papszMD;
      68             :         }
      69          23 :         return m_papszRPC;
      70             :     }
      71             : 
      72         812 :     if (pszDomain == nullptr || EQUAL(pszDomain, ""))
      73             :     {
      74         495 :         if (m_papszMainMD)
      75          59 :             return m_papszMainMD;
      76         436 :         m_papszMainMD = CSLDuplicate(GDALPamDataset::GetMetadata(pszDomain));
      77         436 :         const int nPAMIndex = GetPAMGeorefSrcIndex();
      78         436 :         if (nPAMIndex >= 0 &&
      79         436 :             ((m_bPixelIsPoint && nPAMIndex < m_nPixelIsPointGeorefSrcIndex) ||
      80         432 :              m_nPixelIsPointGeorefSrcIndex < 0 || !m_bPixelIsPoint))
      81             :         {
      82         436 :             if (CSLFetchNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT) !=
      83             :                 nullptr)
      84           0 :                 return m_papszMainMD;
      85             :         }
      86         436 :         if (m_bPixelIsPoint)
      87             :         {
      88           4 :             m_papszMainMD = CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT,
      89             :                                             GDALMD_AOP_POINT);
      90             :         }
      91             :         else
      92             :         {
      93         432 :             m_papszMainMD =
      94         432 :                 CSLSetNameValue(m_papszMainMD, GDALMD_AREA_OR_POINT, nullptr);
      95             :         }
      96         436 :         return m_papszMainMD;
      97             :     }
      98             : 
      99         317 :     return GDALPamDataset::GetMetadata(pszDomain);
     100             : }
     101             : 
     102             : /************************************************************************/
     103             : /*                         GetMetadataItem()                            */
     104             : /************************************************************************/
     105             : 
     106         438 : const char *GDALGeorefPamDataset::GetMetadataItem(const char *pszName,
     107             :                                                   const char *pszDomain)
     108             : {
     109         438 :     if (pszDomain == nullptr || EQUAL(pszDomain, "") || EQUAL(pszDomain, "RPC"))
     110             :     {
     111         204 :         return CSLFetchNameValue(GetMetadata(pszDomain), pszName);
     112             :     }
     113         234 :     return GDALPamDataset::GetMetadataItem(pszName, pszDomain);
     114             : }
     115             : 
     116             : /************************************************************************/
     117             : /*                           TryLoadXML()                              */
     118             : /************************************************************************/
     119             : 
     120        1227 : CPLErr GDALGeorefPamDataset::TryLoadXML(CSLConstList papszSiblingFiles)
     121             : {
     122        1227 :     m_bPAMLoaded = true;
     123        1227 :     CPLErr eErr = GDALPamDataset::TryLoadXML(papszSiblingFiles);
     124        1227 :     CSLDestroy(m_papszMainMD);
     125        1227 :     m_papszMainMD = nullptr;
     126        1227 :     return eErr;
     127             : }
     128             : 
     129             : /************************************************************************/
     130             : /*                            SetMetadata()                             */
     131             : /************************************************************************/
     132             : 
     133          18 : CPLErr GDALGeorefPamDataset::SetMetadata(char **papszMetadata,
     134             :                                          const char *pszDomain)
     135             : {
     136          18 :     if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
     137             :     {
     138          18 :         CSLDestroy(m_papszMainMD);
     139          18 :         m_papszMainMD = CSLDuplicate(papszMetadata);
     140             :     }
     141          18 :     return GDALPamDataset::SetMetadata(papszMetadata, pszDomain);
     142             : }
     143             : 
     144             : /************************************************************************/
     145             : /*                            SetMetadata()                             */
     146             : /************************************************************************/
     147             : 
     148         646 : CPLErr GDALGeorefPamDataset::SetMetadataItem(const char *pszName,
     149             :                                              const char *pszValue,
     150             :                                              const char *pszDomain)
     151             : {
     152         646 :     if (m_bPAMLoaded && (pszDomain == nullptr || EQUAL(pszDomain, "")))
     153             :     {
     154          57 :         char **papszMD = GetMetadata();
     155          57 :         if (papszMD != m_papszMainMD)
     156             :         {
     157          45 :             CSLDestroy(m_papszMainMD);
     158          45 :             m_papszMainMD = CSLDuplicate(papszMD);
     159             :         }
     160          57 :         m_papszMainMD = CSLSetNameValue(m_papszMainMD, pszName, pszValue);
     161             :     }
     162         646 :     return GDALPamDataset::SetMetadataItem(pszName, pszValue, pszDomain);
     163             : }
     164             : 
     165             : /************************************************************************/
     166             : /*                            GetGCPCount()                             */
     167             : /*                                                                      */
     168             : /*      By default, we let PAM override the value stored                */
     169             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     170             : /************************************************************************/
     171             : 
     172         453 : int GDALGeorefPamDataset::GetGCPCount()
     173             : 
     174             : {
     175         453 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     176         453 :     if (nPAMIndex >= 0 &&
     177         436 :         ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
     178         420 :          m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
     179             :     {
     180         436 :         const int nPAMGCPCount = GDALPamDataset::GetGCPCount();
     181         436 :         if (nPAMGCPCount)
     182           2 :             return nPAMGCPCount;
     183             :     }
     184             : 
     185         451 :     return nGCPCount;
     186             : }
     187             : 
     188             : /************************************************************************/
     189             : /*                          GetGCPSpatialRef()                          */
     190             : /*                                                                      */
     191             : /*      By default, we let PAM override the value stored                */
     192             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     193             : /************************************************************************/
     194             : 
     195           6 : const OGRSpatialReference *GDALGeorefPamDataset::GetGCPSpatialRef() const
     196             : 
     197             : {
     198           6 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     199          12 :     if (nPAMIndex >= 0 &&
     200           6 :         ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
     201           1 :          m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
     202             :     {
     203             :         const OGRSpatialReference *pszPAMGCPSRS =
     204           6 :             GDALPamDataset::GetGCPSpatialRef();
     205           6 :         if (pszPAMGCPSRS != nullptr)
     206           1 :             return pszPAMGCPSRS;
     207             :     }
     208             : 
     209           5 :     if (!m_oSRS.IsEmpty())
     210           5 :         return &m_oSRS;
     211             : 
     212           0 :     return nullptr;
     213             : }
     214             : 
     215             : /************************************************************************/
     216             : /*                               GetGCP()                               */
     217             : /*                                                                      */
     218             : /*      By default, we let PAM override the value stored                */
     219             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     220             : /************************************************************************/
     221             : 
     222           9 : const GDAL_GCP *GDALGeorefPamDataset::GetGCPs()
     223             : 
     224             : {
     225           9 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     226           9 :     if (nPAMIndex >= 0 &&
     227           9 :         ((nGCPCount != 0 && nPAMIndex < m_nGCPGeorefSrcIndex) ||
     228           4 :          m_nGCPGeorefSrcIndex < 0 || nGCPCount == 0))
     229             :     {
     230           9 :         const GDAL_GCP *pasPAMGCPList = GDALPamDataset::GetGCPs();
     231           9 :         if (pasPAMGCPList)
     232           1 :             return pasPAMGCPList;
     233             :     }
     234             : 
     235           8 :     return pasGCPList;
     236             : }
     237             : 
     238             : /************************************************************************/
     239             : /*                          GetSpatialRef()                             */
     240             : /*                                                                      */
     241             : /*      By default, we let PAM override the value stored                */
     242             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     243             : /************************************************************************/
     244             : 
     245         363 : const OGRSpatialReference *GDALGeorefPamDataset::GetSpatialRef() const
     246             : 
     247             : {
     248         363 :     if (const_cast<GDALGeorefPamDataset *>(this)->GetGCPCount() > 0)
     249           2 :         return nullptr;
     250             : 
     251         361 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     252         705 :     if (nPAMIndex >= 0 &&
     253         344 :         ((!m_oSRS.IsEmpty() && nPAMIndex < m_nProjectionGeorefSrcIndex) ||
     254          82 :          m_nProjectionGeorefSrcIndex < 0 || m_oSRS.IsEmpty()))
     255             :     {
     256         340 :         const OGRSpatialReference *poPAMSRS = GDALPamDataset::GetSpatialRef();
     257         340 :         if (poPAMSRS != nullptr)
     258          20 :             return poPAMSRS;
     259             :     }
     260             : 
     261         341 :     if (!m_oSRS.IsEmpty())
     262         278 :         return &m_oSRS;
     263             : 
     264          63 :     return nullptr;
     265             : }
     266             : 
     267             : /************************************************************************/
     268             : /*                          GetGeoTransform()                           */
     269             : /*                                                                      */
     270             : /*      By default, we let PAM override the value stored                */
     271             : /*      inside our file, unless GDAL_GEOREF_SOURCES is defined.         */
     272             : /************************************************************************/
     273             : 
     274         500 : CPLErr GDALGeorefPamDataset::GetGeoTransform(GDALGeoTransform &gt) const
     275             : 
     276             : {
     277         500 :     const int nPAMIndex = GetPAMGeorefSrcIndex();
     278         500 :     if (nPAMIndex >= 0 &&
     279         483 :         ((bGeoTransformValid && nPAMIndex <= m_nGeoTransformGeorefSrcIndex) ||
     280         104 :          m_nGeoTransformGeorefSrcIndex < 0 || !bGeoTransformValid))
     281             :     {
     282         472 :         if (GDALPamDataset::GetGeoTransform(gt) == CE_None)
     283             :         {
     284          14 :             m_nGeoTransformGeorefSrcIndex = nPAMIndex;
     285          14 :             return CE_None;
     286             :         }
     287             :     }
     288             : 
     289         486 :     if (bGeoTransformValid)
     290             :     {
     291         414 :         gt = m_gt;
     292         414 :         return (CE_None);
     293             :     }
     294             : 
     295          72 :     return CE_Failure;
     296             : }
     297             : 
     298             : /************************************************************************/
     299             : /*                     GetPAMGeorefSrcIndex()                           */
     300             : /*                                                                      */
     301             : /*      Get priority index of PAM (the lower, the more prioritary)      */
     302             : /************************************************************************/
     303        1790 : int GDALGeorefPamDataset::GetPAMGeorefSrcIndex() const
     304             : {
     305        1790 :     if (!m_bGotPAMGeorefSrcIndex)
     306             :     {
     307          23 :         m_bGotPAMGeorefSrcIndex = true;
     308          23 :         const char *pszGeorefSources = CSLFetchNameValueDef(
     309          23 :             papszOpenOptions, "GEOREF_SOURCES",
     310             :             CPLGetConfigOption("GDAL_GEOREF_SOURCES", "PAM,OTHER"));
     311          23 :         char **papszTokens = CSLTokenizeString2(pszGeorefSources, ",", 0);
     312          23 :         m_nPAMGeorefSrcIndex = CSLFindString(papszTokens, "PAM");
     313          23 :         CSLDestroy(papszTokens);
     314             :     }
     315        1790 :     return m_nPAMGeorefSrcIndex;
     316             : }
     317             : 
     318             : //! @endcond

Generated by: LCOV version 1.14