LCOV - code coverage report
Current view: top level - apps - gdalalg_raster_sieve.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 32 34 94.1 %
Date: 2025-05-15 18:21:54 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "raster sieve" subcommand
       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_sieve.h"
      14             : 
      15             : #include "cpl_conv.h"
      16             : #include "cpl_vsi_virtual.h"
      17             : 
      18             : #include "gdal_alg.h"
      19             : #include "gdal_priv.h"
      20             : #include "gdal_utils.h"
      21             : #include "commonutils.h"
      22             : 
      23             : //! @cond Doxygen_Suppress
      24             : 
      25             : #ifndef _
      26             : #define _(x) (x)
      27             : #endif
      28             : 
      29             : /************************************************************************/
      30             : /*      GDALRasterSieveAlgorithm::GDALRasterSieveAlgorithm()            */
      31             : /************************************************************************/
      32             : 
      33          18 : GDALRasterSieveAlgorithm::GDALRasterSieveAlgorithm(bool standaloneStep)
      34             :     : GDALRasterPipelineNonNativelyStreamingAlgorithm(NAME, DESCRIPTION,
      35          18 :                                                       HELP_URL, standaloneStep)
      36             : {
      37             :     auto &mask{
      38             :         AddArg("mask", 0,
      39             :                _("Use the first band of the specified file as a "
      40             :                  "validity mask (all pixels with a value other than zero "
      41             :                  "will be considered suitable for inclusion in polygons)"),
      42          18 :                &m_maskDataset, GDAL_OF_RASTER)};
      43             : 
      44          18 :     SetAutoCompleteFunctionForFilename(mask, GDAL_OF_RASTER);
      45             : 
      46          18 :     AddBandArg(&m_band);
      47             :     AddArg("size-threshold", 's', _("Minimum size of polygons to keep"),
      48          36 :            &m_sizeThreshold)
      49          18 :         .SetDefault(m_sizeThreshold);
      50             : 
      51             :     AddArg("connect-diagonal-pixels", 'c',
      52          36 :            _("Consider diagonal pixels as connected"), &m_connectDiagonalPixels)
      53          18 :         .SetDefault(m_connectDiagonalPixels);
      54          18 : }
      55             : 
      56             : /************************************************************************/
      57             : /*                 GDALRasterSieveAlgorithm::RunStep()                  */
      58             : /************************************************************************/
      59             : 
      60          10 : bool GDALRasterSieveAlgorithm::RunStep(GDALProgressFunc pfnProgress,
      61             :                                        void *pProgressData)
      62             : {
      63          10 :     auto poSrcDS = m_inputDataset.GetDatasetRef();
      64             :     std::unique_ptr<void, decltype(&GDALDestroyScaledProgress)> pScaledData(
      65             :         GDALCreateScaledProgress(0.0, 0.5, pfnProgress, pProgressData),
      66          20 :         GDALDestroyScaledProgress);
      67             :     auto poTmpDS = CreateTemporaryCopy(
      68          10 :         poSrcDS, m_band, true, pScaledData ? GDALScaledProgress : nullptr,
      69          30 :         pScaledData.get());
      70          10 :     if (!poTmpDS)
      71           1 :         return false;
      72             : 
      73           9 :     GDALRasterBand *maskBand{nullptr};
      74           9 :     if (m_maskDataset.GetDatasetRef())
      75             :     {
      76           1 :         maskBand = m_maskDataset.GetDatasetRef()->GetRasterBand(1);
      77           1 :         if (!maskBand)
      78             :         {
      79           0 :             ReportError(CE_Failure, CPLE_AppDefined, "Cannot get mask band.");
      80           0 :             return false;
      81             :         }
      82             :     }
      83             : 
      84             :     // Get the output band
      85           9 :     GDALRasterBand *dstBand = poTmpDS->GetRasterBand(1);
      86           9 :     CPLAssert(dstBand);
      87             : 
      88           9 :     pScaledData.reset(
      89             :         GDALCreateScaledProgress(0.5, 1.0, pfnProgress, pProgressData));
      90          27 :     const CPLErr err = GDALSieveFilter(
      91             :         dstBand, maskBand, dstBand, m_sizeThreshold,
      92           9 :         m_connectDiagonalPixels ? 8 : 4, nullptr,
      93           9 :         pScaledData ? GDALScaledProgress : nullptr, pScaledData.get());
      94           9 :     if (err == CE_None)
      95             :     {
      96           9 :         if (pfnProgress)
      97           1 :             pfnProgress(1.0, "", pProgressData);
      98           9 :         m_outputDataset.Set(std::move(poTmpDS));
      99             :     }
     100             : 
     101           9 :     return err == CE_None;
     102             : }
     103             : 
     104             : //! @endcond

Generated by: LCOV version 1.14