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

Generated by: LCOV version 1.14