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

Generated by: LCOV version 1.14