Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_raster_sieve.cpp
Line
Count
Source
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
0
#define _(x) (x)
27
#endif
28
29
/************************************************************************/
30
/*         GDALRasterSieveAlgorithm::GDALRasterSieveAlgorithm()         */
31
/************************************************************************/
32
33
GDALRasterSieveAlgorithm::GDALRasterSieveAlgorithm(bool standaloneStep)
34
0
    : GDALRasterPipelineNonNativelyStreamingAlgorithm(NAME, DESCRIPTION,
35
0
                                                      HELP_URL, standaloneStep)
36
0
{
37
0
    auto &mask{
38
0
        AddArg("mask", 0,
39
0
               _("Use the first band of the specified file as a "
40
0
                 "validity mask (all pixels with a value other than zero "
41
0
                 "will be considered suitable for inclusion in polygons)"),
42
0
               &m_maskDataset, GDAL_OF_RASTER)};
43
44
0
    SetAutoCompleteFunctionForFilename(mask, GDAL_OF_RASTER);
45
46
0
    AddBandArg(&m_band);
47
0
    AddArg("size-threshold", 's', _("Minimum size of polygons to keep"),
48
0
           &m_sizeThreshold)
49
0
        .SetDefault(m_sizeThreshold);
50
51
0
    AddArg("connect-diagonal-pixels", 'c',
52
0
           _("Consider diagonal pixels as connected"), &m_connectDiagonalPixels)
53
0
        .SetDefault(m_connectDiagonalPixels);
54
0
}
55
56
/************************************************************************/
57
/*                 GDALRasterSieveAlgorithm::RunStep()                  */
58
/************************************************************************/
59
60
bool GDALRasterSieveAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt)
61
0
{
62
0
    auto pfnProgress = ctxt.m_pfnProgress;
63
0
    auto pProgressData = ctxt.m_pProgressData;
64
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
65
0
    std::unique_ptr<void, decltype(&GDALDestroyScaledProgress)> pScaledData(
66
0
        GDALCreateScaledProgress(0.0, 0.5, pfnProgress, pProgressData),
67
0
        GDALDestroyScaledProgress);
68
0
    auto poTmpDS = CreateTemporaryCopy(
69
0
        this, poSrcDS, m_band, true, pScaledData ? GDALScaledProgress : nullptr,
70
0
        pScaledData.get());
71
0
    if (!poTmpDS)
72
0
        return false;
73
74
0
    GDALRasterBand *maskBand{nullptr};
75
0
    if (m_maskDataset.GetDatasetRef())
76
0
    {
77
0
        maskBand = m_maskDataset.GetDatasetRef()->GetRasterBand(1);
78
0
        if (!maskBand)
79
0
        {
80
0
            ReportError(CE_Failure, CPLE_AppDefined, "Cannot get mask band.");
81
0
            return false;
82
0
        }
83
0
    }
84
85
    // Get the output band
86
0
    GDALRasterBand *dstBand = poTmpDS->GetRasterBand(1);
87
0
    CPLAssert(dstBand);
88
89
0
    pScaledData.reset(
90
0
        GDALCreateScaledProgress(0.5, 1.0, pfnProgress, pProgressData));
91
0
    const CPLErr err = GDALSieveFilter(
92
0
        dstBand, maskBand, dstBand, m_sizeThreshold,
93
0
        m_connectDiagonalPixels ? 8 : 4, nullptr,
94
0
        pScaledData ? GDALScaledProgress : nullptr, pScaledData.get());
95
0
    if (err == CE_None)
96
0
    {
97
0
        if (pfnProgress)
98
0
            pfnProgress(1.0, "", pProgressData);
99
0
        m_outputDataset.Set(std::move(poTmpDS));
100
0
    }
101
102
0
    return err == CE_None;
103
0
}
104
105
0
GDALRasterSieveAlgorithmStandalone::~GDALRasterSieveAlgorithmStandalone() =
106
    default;
107
108
//! @endcond