Coverage Report

Created: 2026-02-14 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_vector_limit.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  "limit" step of "vector pipeline"
5
 * Author:   Dan Baston
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2025, ISciences LLC
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "gdalalg_vector_limit.h"
14
#include "gdalalg_vector_pipeline.h"
15
16
#include "gdal_priv.h"
17
#include "ogrsf_frmts.h"
18
#include "ogr_p.h"
19
20
#include <algorithm>
21
#include <set>
22
23
//! @cond Doxygen_Suppress
24
25
#ifndef _
26
0
#define _(x) (x)
27
#endif
28
29
/************************************************************************/
30
/*         GDALVectorLimitAlgorithm::GDALVectorLimitAlgorithm()         */
31
/************************************************************************/
32
33
GDALVectorLimitAlgorithm::GDALVectorLimitAlgorithm(bool standaloneStep)
34
0
    : GDALVectorPipelineStepAlgorithm(NAME, DESCRIPTION, HELP_URL,
35
0
                                      standaloneStep)
36
0
{
37
0
    AddArg("limit", 0, _("Limit the number of features to read per layer"),
38
0
           &m_featureLimit)
39
0
        .SetPositional()
40
0
        .SetRequired();
41
0
    AddActiveLayerArg(&m_activeLayer);
42
0
}
43
44
namespace
45
{
46
47
/************************************************************************/
48
/*                      GDALVectorReadLimitedLayer                      */
49
/************************************************************************/
50
51
class GDALVectorReadLimitedLayer : public OGRLayer
52
{
53
  public:
54
    GDALVectorReadLimitedLayer(OGRLayer &layer, int featureLimit)
55
0
        : m_srcLayer(layer), m_featureLimit(featureLimit), m_featuresRead(0)
56
0
    {
57
0
    }
58
59
    ~GDALVectorReadLimitedLayer() override;
60
61
    OGRFeature *GetNextFeature() override
62
0
    {
63
0
        if (m_featuresRead < m_featureLimit)
64
0
        {
65
0
            m_featuresRead++;
66
0
            return m_srcLayer.GetNextFeature();
67
0
        }
68
0
        return nullptr;
69
0
    }
70
71
    const OGRFeatureDefn *GetLayerDefn() const override
72
0
    {
73
0
        return m_srcLayer.GetLayerDefn();
74
0
    }
75
76
    GIntBig GetFeatureCount(int bForce) override
77
0
    {
78
0
        return std::min(m_featureLimit, m_srcLayer.GetFeatureCount(bForce));
79
0
    }
80
81
    void ResetReading() override
82
0
    {
83
0
        m_featuresRead = 0;
84
0
        m_srcLayer.ResetReading();
85
0
    }
86
87
    int TestCapability(const char *pszCap) const override
88
0
    {
89
0
        return m_srcLayer.TestCapability(pszCap);
90
0
    }
91
92
  private:
93
    OGRLayer &m_srcLayer;
94
    GIntBig m_featureLimit;
95
    GIntBig m_featuresRead;
96
};
97
98
GDALVectorReadLimitedLayer::~GDALVectorReadLimitedLayer() = default;
99
100
}  // namespace
101
102
/************************************************************************/
103
/*                 GDALVectorLimitAlgorithm::RunStep()                  */
104
/************************************************************************/
105
106
bool GDALVectorLimitAlgorithm::RunStep(GDALPipelineStepRunContext &)
107
0
{
108
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
109
0
    CPLAssert(poSrcDS);
110
111
0
    CPLAssert(m_outputDataset.GetName().empty());
112
0
    CPLAssert(!m_outputDataset.GetDatasetRef());
113
114
0
    auto outDS = std::make_unique<GDALVectorOutputDataset>();
115
116
0
    for (auto &&poSrcLayer : poSrcDS->GetLayers())
117
0
    {
118
0
        if (m_activeLayer.empty() ||
119
0
            m_activeLayer == poSrcLayer->GetDescription())
120
0
        {
121
0
            outDS->AddLayer(std::make_unique<GDALVectorReadLimitedLayer>(
122
0
                *poSrcLayer, m_featureLimit));
123
0
        }
124
0
        else
125
0
        {
126
0
            outDS->AddLayer(
127
0
                std::make_unique<GDALVectorPipelinePassthroughLayer>(
128
0
                    *poSrcLayer));
129
0
        }
130
0
    }
131
132
0
    m_outputDataset.Set(std::move(outDS));
133
134
0
    return true;
135
0
}
136
137
//! @endcond