LCOV - code coverage report
Current view: top level - alg - gdaltransformgeolocs.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 36 39 92.3 %
Date: 2025-05-20 14:45:53 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  Algorithm to apply a transformer to geolocation style bands.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2012, Frank Warmerdam
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_port.h"
      14             : #include "gdal_alg.h"
      15             : 
      16             : #include <cstring>
      17             : 
      18             : #include "cpl_conv.h"
      19             : #include "cpl_error.h"
      20             : #include "cpl_progress.h"
      21             : #include "gdal.h"
      22             : #include "gdal_alg_priv.h"
      23             : #include "gdal_priv.h"
      24             : 
      25             : /************************************************************************/
      26             : /*                     GDALTransformGeolocations()                      */
      27             : /************************************************************************/
      28             : 
      29             : /**
      30             :  * Transform locations held in bands.
      31             :  *
      32             :  * The X/Y and possibly Z values in the identified bands are transformed
      33             :  * using a spatial transformer.  The changed values are written back to the
      34             :  * source bands so they need to be updateable.
      35             :  *
      36             :  * @param hXBand the band containing the X locations (usually long/easting).
      37             :  * @param hYBand the band containing the Y locations (usually lat/northing).
      38             :  * @param hZBand the band containing the Z locations (may be NULL).
      39             :  * @param pfnTransformer the transformer function.
      40             :  * @param pTransformArg the callback data for the transformer function.
      41             :  * @param pfnProgress callback for reporting algorithm progress matching the
      42             :  * GDALProgressFunc() semantics.  May be NULL.
      43             :  * @param pProgressArg callback argument passed to pfnProgress.
      44             :  * @param papszOptions list of name/value options - none currently supported.
      45             :  *
      46             :  * @return CE_None on success or CE_Failure if an error occurs.
      47             :  */
      48             : 
      49           1 : CPLErr GDALTransformGeolocations(GDALRasterBandH hXBand, GDALRasterBandH hYBand,
      50             :                                  GDALRasterBandH hZBand,
      51             :                                  GDALTransformerFunc pfnTransformer,
      52             :                                  void *pTransformArg,
      53             :                                  GDALProgressFunc pfnProgress,
      54             :                                  void *pProgressArg,
      55             :                                  CPL_UNUSED char **papszOptions)
      56             : 
      57             : {
      58           1 :     VALIDATE_POINTER1(hXBand, "GDALTransformGeolocations", CE_Failure);
      59           1 :     VALIDATE_POINTER1(hYBand, "GDALTransformGeolocations", CE_Failure);
      60             : 
      61           1 :     if (pfnProgress == nullptr)
      62           1 :         pfnProgress = GDALDummyProgress;
      63             : 
      64             :     /* -------------------------------------------------------------------- */
      65             :     /*      Ensure the bands are matching in size.                          */
      66             :     /* -------------------------------------------------------------------- */
      67           1 :     GDALRasterBand *poXBand = reinterpret_cast<GDALRasterBand *>(hXBand);
      68           1 :     GDALRasterBand *poYBand = reinterpret_cast<GDALRasterBand *>(hYBand);
      69           1 :     GDALRasterBand *poZBand = reinterpret_cast<GDALRasterBand *>(hZBand);
      70           1 :     const int nXSize = poXBand->GetXSize();
      71           1 :     const int nYSize = poXBand->GetYSize();
      72             : 
      73           2 :     if (nXSize != poYBand->GetXSize() || nYSize != poYBand->GetYSize() ||
      74           3 :         (poZBand != nullptr && nXSize != poZBand->GetXSize()) ||
      75           1 :         (poZBand != nullptr && nYSize != poZBand->GetYSize()))
      76             :     {
      77           0 :         CPLError(CE_Failure, CPLE_AppDefined,
      78             :                  "Size of X, Y and/or Z bands do not match.");
      79           0 :         return CE_Failure;
      80             :     }
      81             : 
      82             :     /* -------------------------------------------------------------------- */
      83             :     /*      Allocate a buffer large enough to hold one whole row.           */
      84             :     /* -------------------------------------------------------------------- */
      85             :     std::unique_ptr<double, VSIFreeReleaser> padfX(
      86           2 :         static_cast<double *>(VSI_MALLOC2_VERBOSE(sizeof(double), nXSize)));
      87             :     std::unique_ptr<double, VSIFreeReleaser> padfY(
      88           2 :         static_cast<double *>(VSI_MALLOC2_VERBOSE(sizeof(double), nXSize)));
      89             :     std::unique_ptr<double, VSIFreeReleaser> padfZ(
      90           2 :         static_cast<double *>(VSI_MALLOC2_VERBOSE(sizeof(double), nXSize)));
      91             :     std::unique_ptr<int, VSIFreeReleaser> panSuccess(
      92           1 :         static_cast<int *>(VSI_MALLOC2_VERBOSE(sizeof(int), nXSize)));
      93           1 :     CPLErr eErr = padfX && padfY && padfZ && panSuccess ? CE_None : CE_Failure;
      94             : 
      95           1 :     pfnProgress(0.0, "", pProgressArg);
      96           3 :     for (int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++)
      97             :     {
      98           2 :         eErr = poXBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfX.get(),
      99             :                                  nXSize, 1, GDT_Float64, 0, 0, nullptr);
     100           2 :         if (eErr == CE_None)
     101           2 :             eErr = poYBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfY.get(),
     102             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     103           2 :         if (eErr == CE_None && poZBand != nullptr)
     104           2 :             eErr = poZBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfZ.get(),
     105             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     106             :         else
     107           0 :             memset(padfZ.get(), 0, sizeof(double) * nXSize);
     108             : 
     109           2 :         if (eErr == CE_None)
     110             :         {
     111           2 :             pfnTransformer(pTransformArg, FALSE, nXSize, padfX.get(),
     112             :                            padfY.get(), padfZ.get(), panSuccess.get());
     113             :         }
     114             : 
     115           2 :         if (eErr == CE_None)
     116           2 :             eErr = poXBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfX.get(),
     117             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     118           2 :         if (eErr == CE_None)
     119           2 :             eErr = poYBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfY.get(),
     120             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     121           2 :         if (eErr == CE_None && poZBand != nullptr)
     122           2 :             eErr = poZBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfZ.get(),
     123             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     124             : 
     125           2 :         if (eErr == CE_None)
     126           2 :             pfnProgress((iLine + 1) / static_cast<double>(nYSize), "",
     127             :                         pProgressArg);
     128             :     }
     129             : 
     130           1 :     return eErr;
     131             : }

Generated by: LCOV version 1.14