LCOV - code coverage report
Current view: top level - alg - gdalgeoloc_carray_accessor.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 104 112 92.9 %
Date: 2024-11-21 22:18:42 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  C-Array storage of geolocation array and backmap
       5             :  * Author:   Even Rouault, <even.rouault at spatialys.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2022, Planet Labs
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : /*! @cond Doxygen_Suppress */
      14             : 
      15             : /************************************************************************/
      16             : /*                        GDALGeoLocCArrayAccessors                     */
      17             : /************************************************************************/
      18             : 
      19             : class GDALGeoLocCArrayAccessors
      20             : {
      21             :     typedef class GDALGeoLocCArrayAccessors AccessorType;
      22             : 
      23             :     GDALGeoLocTransformInfo *m_psTransform;
      24             :     double *m_padfGeoLocX = nullptr;
      25             :     double *m_padfGeoLocY = nullptr;
      26             :     float *m_pafBackMapX = nullptr;
      27             :     float *m_pafBackMapY = nullptr;
      28             :     float *m_wgtsBackMap = nullptr;
      29             : 
      30             :     bool LoadGeoloc(bool bIsRegularGrid);
      31             : 
      32             :   public:
      33             :     template <class Type> struct CArrayAccessor
      34             :     {
      35             :         Type *m_array;
      36             :         size_t m_nXSize;
      37             : 
      38         230 :         CArrayAccessor(Type *array, size_t nXSize)
      39         230 :             : m_array(array), m_nXSize(nXSize)
      40             :         {
      41         230 :         }
      42             : 
      43    23334350 :         inline Type Get(int nX, int nY, bool *pbSuccess = nullptr)
      44             :         {
      45    23334350 :             if (pbSuccess)
      46           0 :                 *pbSuccess = true;
      47    23334350 :             return m_array[nY * m_nXSize + nX];
      48             :         }
      49             : 
      50     1932970 :         inline bool Set(int nX, int nY, Type val)
      51             :         {
      52     1932970 :             m_array[nY * m_nXSize + nX] = val;
      53     1932970 :             return true;
      54             :         }
      55             :     };
      56             : 
      57             :     CArrayAccessor<double> geolocXAccessor;
      58             :     CArrayAccessor<double> geolocYAccessor;
      59             :     CArrayAccessor<float> backMapXAccessor;
      60             :     CArrayAccessor<float> backMapYAccessor;
      61             :     CArrayAccessor<float> backMapWeightAccessor;
      62             : 
      63          46 :     explicit GDALGeoLocCArrayAccessors(GDALGeoLocTransformInfo *psTransform)
      64          46 :         : m_psTransform(psTransform), geolocXAccessor(nullptr, 0),
      65             :           geolocYAccessor(nullptr, 0), backMapXAccessor(nullptr, 0),
      66          46 :           backMapYAccessor(nullptr, 0), backMapWeightAccessor(nullptr, 0)
      67             :     {
      68          46 :     }
      69             : 
      70          46 :     ~GDALGeoLocCArrayAccessors()
      71          46 :     {
      72          46 :         VSIFree(m_pafBackMapX);
      73          46 :         VSIFree(m_pafBackMapY);
      74          46 :         VSIFree(m_padfGeoLocX);
      75          46 :         VSIFree(m_padfGeoLocY);
      76          46 :         VSIFree(m_wgtsBackMap);
      77          46 :     }
      78             : 
      79             :     GDALGeoLocCArrayAccessors(const GDALGeoLocCArrayAccessors &) = delete;
      80             :     GDALGeoLocCArrayAccessors &
      81             :     operator=(const GDALGeoLocCArrayAccessors &) = delete;
      82             : 
      83             :     bool Load(bool bIsRegularGrid, bool bUseQuadtree);
      84             : 
      85             :     bool AllocateBackMap();
      86             : 
      87             :     GDALDataset *GetBackmapDataset();
      88             : 
      89          42 :     static void FlushBackmapCaches()
      90             :     {
      91          42 :     }
      92             : 
      93          42 :     static void ReleaseBackmapDataset(GDALDataset *poDS)
      94             :     {
      95          42 :         delete poDS;
      96          42 :     }
      97             : 
      98             :     void FreeWghtsBackMap();
      99             : };
     100             : 
     101             : /************************************************************************/
     102             : /*                         AllocateBackMap()                            */
     103             : /************************************************************************/
     104             : 
     105          42 : bool GDALGeoLocCArrayAccessors::AllocateBackMap()
     106             : {
     107          42 :     m_pafBackMapX = static_cast<float *>(
     108          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     109             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     110          42 :     m_pafBackMapY = static_cast<float *>(
     111          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     112             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     113             : 
     114          42 :     m_wgtsBackMap = static_cast<float *>(
     115          42 :         VSI_MALLOC3_VERBOSE(m_psTransform->nBackMapWidth,
     116             :                             m_psTransform->nBackMapHeight, sizeof(float)));
     117             : 
     118          42 :     if (m_pafBackMapX == nullptr || m_pafBackMapY == nullptr ||
     119          42 :         m_wgtsBackMap == nullptr)
     120             :     {
     121           0 :         return false;
     122             :     }
     123             : 
     124          42 :     const size_t nBMXYCount =
     125          42 :         static_cast<size_t>(m_psTransform->nBackMapWidth) *
     126          42 :         m_psTransform->nBackMapHeight;
     127      186014 :     for (size_t i = 0; i < nBMXYCount; i++)
     128             :     {
     129      185972 :         m_pafBackMapX[i] = 0;
     130      185972 :         m_pafBackMapY[i] = 0;
     131      185972 :         m_wgtsBackMap[i] = 0.0;
     132             :     }
     133             : 
     134          42 :     backMapXAccessor.m_array = m_pafBackMapX;
     135          42 :     backMapXAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     136             : 
     137          42 :     backMapYAccessor.m_array = m_pafBackMapY;
     138          42 :     backMapYAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     139             : 
     140          42 :     backMapWeightAccessor.m_array = m_wgtsBackMap;
     141          42 :     backMapWeightAccessor.m_nXSize = m_psTransform->nBackMapWidth;
     142             : 
     143          42 :     return true;
     144             : }
     145             : 
     146             : /************************************************************************/
     147             : /*                         FreeWghtsBackMap()                           */
     148             : /************************************************************************/
     149             : 
     150          42 : void GDALGeoLocCArrayAccessors::FreeWghtsBackMap()
     151             : {
     152          42 :     VSIFree(m_wgtsBackMap);
     153          42 :     m_wgtsBackMap = nullptr;
     154          42 :     backMapWeightAccessor.m_array = nullptr;
     155          42 :     backMapWeightAccessor.m_nXSize = 0;
     156          42 : }
     157             : 
     158             : /************************************************************************/
     159             : /*                        GetBackmapDataset()                           */
     160             : /************************************************************************/
     161             : 
     162          42 : GDALDataset *GDALGeoLocCArrayAccessors::GetBackmapDataset()
     163             : {
     164          84 :     auto poMEMDS = MEMDataset::Create("", m_psTransform->nBackMapWidth,
     165          42 :                                       m_psTransform->nBackMapHeight, 0,
     166             :                                       GDT_Float32, nullptr);
     167             : 
     168         126 :     for (int i = 1; i <= 2; i++)
     169             :     {
     170          84 :         void *ptr = (i == 1) ? m_pafBackMapX : m_pafBackMapY;
     171          84 :         GDALRasterBandH hMEMBand = MEMCreateRasterBandEx(
     172             :             poMEMDS, i, static_cast<GByte *>(ptr), GDT_Float32, 0, 0, false);
     173          84 :         poMEMDS->AddMEMBand(hMEMBand);
     174          84 :         poMEMDS->GetRasterBand(i)->SetNoDataValue(INVALID_BMXY);
     175             :     }
     176          42 :     return poMEMDS;
     177             : }
     178             : 
     179             : /************************************************************************/
     180             : /*                             Load()                                   */
     181             : /************************************************************************/
     182             : 
     183          46 : bool GDALGeoLocCArrayAccessors::Load(bool bIsRegularGrid, bool bUseQuadtree)
     184             : {
     185          92 :     return LoadGeoloc(bIsRegularGrid) &&
     186           4 :            ((bUseQuadtree && GDALGeoLocBuildQuadTree(m_psTransform)) ||
     187          42 :             (!bUseQuadtree &&
     188          88 :              GDALGeoLoc<AccessorType>::GenerateBackMap(m_psTransform)));
     189             : }
     190             : 
     191             : /************************************************************************/
     192             : /*                          LoadGeoloc()                                */
     193             : /************************************************************************/
     194             : 
     195          46 : bool GDALGeoLocCArrayAccessors::LoadGeoloc(bool bIsRegularGrid)
     196             : 
     197             : {
     198          46 :     const int nXSize = m_psTransform->nGeoLocXSize;
     199          46 :     const int nYSize = m_psTransform->nGeoLocYSize;
     200             : 
     201          46 :     m_padfGeoLocY = static_cast<double *>(
     202          46 :         VSI_MALLOC3_VERBOSE(sizeof(double), nXSize, nYSize));
     203          46 :     m_padfGeoLocX = static_cast<double *>(
     204          46 :         VSI_MALLOC3_VERBOSE(sizeof(double), nXSize, nYSize));
     205             : 
     206          46 :     if (m_padfGeoLocX == nullptr || m_padfGeoLocY == nullptr)
     207             :     {
     208           0 :         return false;
     209             :     }
     210             : 
     211          46 :     if (bIsRegularGrid)
     212             :     {
     213             :         // Case of regular grid.
     214             :         // The XBAND contains the x coordinates for all lines.
     215             :         // The YBAND contains the y coordinates for all columns.
     216             : 
     217             :         double *padfTempX =
     218          14 :             static_cast<double *>(VSI_MALLOC2_VERBOSE(nXSize, sizeof(double)));
     219             :         double *padfTempY =
     220          14 :             static_cast<double *>(VSI_MALLOC2_VERBOSE(nYSize, sizeof(double)));
     221          14 :         if (padfTempX == nullptr || padfTempY == nullptr)
     222             :         {
     223           0 :             CPLFree(padfTempX);
     224           0 :             CPLFree(padfTempY);
     225           0 :             return false;
     226             :         }
     227             : 
     228             :         CPLErr eErr =
     229          14 :             GDALRasterIO(m_psTransform->hBand_X, GF_Read, 0, 0, nXSize, 1,
     230             :                          padfTempX, nXSize, 1, GDT_Float64, 0, 0);
     231             : 
     232         262 :         for (size_t j = 0; j < static_cast<size_t>(nYSize); j++)
     233             :         {
     234         248 :             memcpy(m_padfGeoLocX + j * nXSize, padfTempX,
     235         248 :                    nXSize * sizeof(double));
     236             :         }
     237             : 
     238          14 :         if (eErr == CE_None)
     239             :         {
     240          14 :             eErr = GDALRasterIO(m_psTransform->hBand_Y, GF_Read, 0, 0, nYSize,
     241             :                                 1, padfTempY, nYSize, 1, GDT_Float64, 0, 0);
     242             : 
     243         262 :             for (size_t j = 0; j < static_cast<size_t>(nYSize); j++)
     244             :             {
     245       31480 :                 for (size_t i = 0; i < static_cast<size_t>(nXSize); i++)
     246             :                 {
     247       31232 :                     m_padfGeoLocY[j * nXSize + i] = padfTempY[j];
     248             :                 }
     249             :             }
     250             :         }
     251             : 
     252          14 :         CPLFree(padfTempX);
     253          14 :         CPLFree(padfTempY);
     254             : 
     255          14 :         if (eErr != CE_None)
     256           0 :             return false;
     257             :     }
     258             :     else
     259             :     {
     260          96 :         if (GDALRasterIO(m_psTransform->hBand_X, GF_Read, 0, 0, nXSize, nYSize,
     261          32 :                          m_padfGeoLocX, nXSize, nYSize, GDT_Float64, 0,
     262          64 :                          0) != CE_None ||
     263          32 :             GDALRasterIO(m_psTransform->hBand_Y, GF_Read, 0, 0, nXSize, nYSize,
     264          32 :                          m_padfGeoLocY, nXSize, nYSize, GDT_Float64, 0,
     265             :                          0) != CE_None)
     266           0 :             return false;
     267             :     }
     268             : 
     269          46 :     geolocXAccessor.m_array = m_padfGeoLocX;
     270          46 :     geolocXAccessor.m_nXSize = m_psTransform->nGeoLocXSize;
     271             : 
     272          46 :     geolocYAccessor.m_array = m_padfGeoLocY;
     273          46 :     geolocYAccessor.m_nXSize = m_psTransform->nGeoLocXSize;
     274             : 
     275          46 :     GDALGeoLoc<GDALGeoLocCArrayAccessors>::LoadGeolocFinish(m_psTransform);
     276          46 :     return true;
     277             : }
     278             : 
     279             : /*! @endcond */

Generated by: LCOV version 1.14