LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_fill_nodata.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 44 46 95.7 %
Date: 2025-06-19 12:30:01 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  "gdal raster fillnodata" standalone command
       5             :  * Author:   Alessandro Pasotti <elpaso at itopen dot it>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2025, Alessandro Pasotti <elpaso at itopen dot it>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "gdalalg_raster_fill_nodata.h"
      14             : 
      15             : #include "cpl_progress.h"
      16             : #include "gdal_priv.h"
      17             : #include "gdal_alg.h"
      18             : #include "commonutils.h"
      19             : 
      20             : #include <algorithm>
      21             : 
      22             : //! @cond Doxygen_Suppress
      23             : 
      24             : #ifndef _
      25             : #define _(x) (x)
      26             : #endif
      27             : 
      28             : /************************************************************************/
      29             : /*   GDALRasterFillNodataAlgorithm::GDALRasterFillNodataAlgorithm()     */
      30             : /************************************************************************/
      31             : 
      32          39 : GDALRasterFillNodataAlgorithm::GDALRasterFillNodataAlgorithm(
      33          39 :     bool standalone) noexcept
      34             :     : GDALRasterPipelineNonNativelyStreamingAlgorithm(NAME, DESCRIPTION,
      35          39 :                                                       HELP_URL, standalone)
      36             : {
      37          39 :     AddBandArg(&m_band).SetDefault(m_band);
      38             : 
      39             :     AddArg("max-distance", 'd',
      40             :            _("The maximum distance (in pixels) that the algorithm will search "
      41             :              "out for values to interpolate."),
      42          78 :            &m_maxDistance)
      43          39 :         .SetDefault(m_maxDistance)
      44          39 :         .SetMetaVar("MAX_DISTANCE");
      45             : 
      46             :     AddArg("smoothing-iterations", 's',
      47             :            _("The number of 3x3 average filter smoothing iterations to run "
      48             :              "after the interpolation to dampen artifacts. The default is zero "
      49             :              "smoothing iterations."),
      50          78 :            &m_smoothingIterations)
      51          39 :         .SetDefault(m_smoothingIterations)
      52          39 :         .SetMetaVar("SMOOTHING_ITERATIONS");
      53             : 
      54             :     auto &mask{AddArg("mask", 0,
      55             :                       _("Use the first band of the specified file as a "
      56             :                         "validity mask (zero is invalid, non-zero is valid)."),
      57          39 :                       &m_maskDataset)};
      58             : 
      59          39 :     SetAutoCompleteFunctionForFilename(mask, GDAL_OF_RASTER);
      60             : 
      61             :     AddArg("strategy", 0,
      62             :            _("By default, pixels are interpolated using an inverse distance "
      63             :              "weighting (invdist). It is also possible to choose a nearest "
      64             :              "neighbour (nearest) strategy."),
      65          78 :            &m_strategy)
      66          39 :         .SetDefault(m_strategy)
      67          39 :         .SetChoices("invdist", "nearest");
      68          39 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                 GDALRasterFillNodataAlgorithm::RunStep()             */
      72             : /************************************************************************/
      73             : 
      74          15 : bool GDALRasterFillNodataAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt)
      75             : {
      76          15 :     auto pfnProgress = ctxt.m_pfnProgress;
      77          15 :     auto pProgressData = ctxt.m_pProgressData;
      78             : 
      79          15 :     auto poSrcDS = m_inputDataset[0].GetDatasetRef();
      80             :     std::unique_ptr<void, decltype(&GDALDestroyScaledProgress)> pScaledData(
      81             :         GDALCreateScaledProgress(0.0, 0.5, pfnProgress, pProgressData),
      82          30 :         GDALDestroyScaledProgress);
      83             :     auto poTmpDS = CreateTemporaryCopy(
      84          15 :         this, poSrcDS, m_band, true, pScaledData ? GDALScaledProgress : nullptr,
      85          45 :         pScaledData.get());
      86          15 :     if (!poTmpDS)
      87           1 :         return false;
      88             : 
      89          14 :     GDALRasterBand *maskBand{nullptr};
      90          14 :     if (m_maskDataset.GetDatasetRef())
      91             :     {
      92           2 :         maskBand = m_maskDataset.GetDatasetRef()->GetRasterBand(1);
      93           2 :         if (!maskBand)
      94             :         {
      95           0 :             ReportError(CE_Failure, CPLE_AppDefined, "Cannot get mask band.");
      96           0 :             return false;
      97             :         }
      98             :     }
      99             : 
     100             :     // Get the output band
     101          14 :     GDALRasterBand *dstBand{poTmpDS->GetRasterBand(1)};
     102          14 :     CPLAssert(dstBand);
     103             : 
     104             :     // Prepare options to pass to GDALFillNodata
     105          14 :     CPLStringList aosFillOptions;
     106             : 
     107          14 :     if (EQUAL(m_strategy.c_str(), "nearest"))
     108           1 :         aosFillOptions.AddNameValue("INTERPOLATION", "NEAREST");
     109             :     else
     110             :         aosFillOptions.AddNameValue("INTERPOLATION",
     111          13 :                                     "INV_DIST");  // default strategy
     112             : 
     113          14 :     pScaledData.reset(
     114             :         GDALCreateScaledProgress(0.5, 1.0, pfnProgress, pProgressData));
     115          28 :     const auto retVal = GDALFillNodata(
     116          14 :         dstBand, maskBand, m_maxDistance, 0, m_smoothingIterations,
     117          14 :         aosFillOptions.List(), pScaledData ? GDALScaledProgress : nullptr,
     118             :         pScaledData.get());
     119             : 
     120          14 :     if (retVal == CE_None)
     121             :     {
     122          13 :         if (pfnProgress)
     123          11 :             pfnProgress(1.0, "", pProgressData);
     124          13 :         m_outputDataset.Set(std::move(poTmpDS));
     125             :     }
     126             : 
     127          14 :     return retVal == CE_None;
     128             : }
     129             : 
     130             : GDALRasterFillNodataAlgorithmStandalone::
     131             :     ~GDALRasterFillNodataAlgorithmStandalone() = default;
     132             : 
     133             : //! @endcond

Generated by: LCOV version 1.14