LCOV - code coverage report
Current view: top level - alg - gdaltransformgeolocs.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 40 43 93.0 %
Date: 2024-11-21 22:18:42 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           1 :     double *padfX = static_cast<double *>(CPLMalloc(sizeof(double) * nXSize));
      86           1 :     double *padfY = static_cast<double *>(CPLMalloc(sizeof(double) * nXSize));
      87           1 :     double *padfZ = static_cast<double *>(CPLMalloc(sizeof(double) * nXSize));
      88           1 :     int *panSuccess = static_cast<int *>(CPLMalloc(sizeof(int) * nXSize));
      89           1 :     CPLErr eErr = CE_None;
      90             : 
      91           1 :     pfnProgress(0.0, "", pProgressArg);
      92           3 :     for (int iLine = 0; eErr == CE_None && iLine < nYSize; iLine++)
      93             :     {
      94           2 :         eErr = poXBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfX, nXSize, 1,
      95             :                                  GDT_Float64, 0, 0, nullptr);
      96           2 :         if (eErr == CE_None)
      97           2 :             eErr = poYBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfY,
      98             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
      99           2 :         if (eErr == CE_None && poZBand != nullptr)
     100           2 :             eErr = poZBand->RasterIO(GF_Read, 0, iLine, nXSize, 1, padfZ,
     101             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     102             :         else
     103           0 :             memset(padfZ, 0, sizeof(double) * nXSize);
     104             : 
     105           2 :         if (eErr == CE_None)
     106             :         {
     107           2 :             pfnTransformer(pTransformArg, FALSE, nXSize, padfX, padfY, padfZ,
     108             :                            panSuccess);
     109             :         }
     110             : 
     111           2 :         if (eErr == CE_None)
     112           2 :             eErr = poXBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfX,
     113             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     114           2 :         if (eErr == CE_None)
     115           2 :             eErr = poYBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfY,
     116             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     117           2 :         if (eErr == CE_None && poZBand != nullptr)
     118           2 :             eErr = poZBand->RasterIO(GF_Write, 0, iLine, nXSize, 1, padfZ,
     119             :                                      nXSize, 1, GDT_Float64, 0, 0, nullptr);
     120             : 
     121           2 :         if (eErr == CE_None)
     122           2 :             pfnProgress((iLine + 1) / static_cast<double>(nYSize), "",
     123             :                         pProgressArg);
     124             :     }
     125             : 
     126             :     /* -------------------------------------------------------------------- */
     127             :     /*      Cleanup                                                         */
     128             :     /* -------------------------------------------------------------------- */
     129           1 :     CPLFree(padfX);
     130           1 :     CPLFree(padfY);
     131           1 :     CPLFree(padfZ);
     132           1 :     CPLFree(panSuccess);
     133             : 
     134           1 :     return eErr;
     135             : }

Generated by: LCOV version 1.14