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_read.cpp
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  "read" step of "vector pipeline"
5
 * Author:   Even Rouault <even dot rouault at spatialys.com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
9
 *
10
 * SPDX-License-Identifier: MIT
11
 ****************************************************************************/
12
13
#include "gdalalg_vector_read.h"
14
15
#include "gdal_priv.h"
16
#include "ogrsf_frmts.h"
17
18
//! @cond Doxygen_Suppress
19
20
#ifndef _
21
#define _(x) (x)
22
#endif
23
24
/************************************************************************/
25
/*          GDALVectorReadAlgorithm::GDALVectorReadAlgorithm()          */
26
/************************************************************************/
27
28
GDALVectorReadAlgorithm::GDALVectorReadAlgorithm()
29
0
    : GDALVectorPipelineStepAlgorithm(
30
0
          NAME, DESCRIPTION, HELP_URL,
31
0
          ConstructorOptions().SetAddDefaultArguments(false))
32
0
{
33
0
    AddVectorInputArgs(/* hiddenForCLI = */ false);
34
0
}
35
36
/************************************************************************/
37
/*                 GDALVectorPipelineReadOutputDataset                  */
38
/************************************************************************/
39
40
/** Class used by vector pipeline steps to create an output on-the-fly
41
 * dataset where they can store on-the-fly layers.
42
 */
43
class GDALVectorPipelineReadOutputDataset final : public GDALDataset
44
{
45
    GDALDataset &m_srcDS;
46
    std::vector<OGRLayer *> m_layers{};
47
48
    CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineReadOutputDataset)
49
50
  public:
51
    explicit GDALVectorPipelineReadOutputDataset(GDALDataset &oSrcDS);
52
53
    void AddLayer(OGRLayer &oSrcLayer);
54
55
    int GetLayerCount() const override;
56
57
    OGRLayer *GetLayer(int idx) const override;
58
59
    int TestCapability(const char *pszCap) const override;
60
61
    void ResetReading() override;
62
63
    OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
64
                               double *pdfProgressPct,
65
                               GDALProgressFunc pfnProgress,
66
                               void *pProgressData) override;
67
};
68
69
/************************************************************************/
70
/*                GDALVectorPipelineReadOutputDataset()                 */
71
/************************************************************************/
72
73
GDALVectorPipelineReadOutputDataset::GDALVectorPipelineReadOutputDataset(
74
    GDALDataset &srcDS)
75
0
    : m_srcDS(srcDS)
76
0
{
77
0
    SetDescription(m_srcDS.GetDescription());
78
0
}
79
80
/************************************************************************/
81
/*           GDALVectorPipelineReadOutputDataset::AddLayer()            */
82
/************************************************************************/
83
84
void GDALVectorPipelineReadOutputDataset::AddLayer(OGRLayer &oSrcLayer)
85
0
{
86
0
    m_layers.push_back(&oSrcLayer);
87
0
}
88
89
/************************************************************************/
90
/*         GDALVectorPipelineReadOutputDataset::GetLayerCount()         */
91
/************************************************************************/
92
93
int GDALVectorPipelineReadOutputDataset::GetLayerCount() const
94
0
{
95
0
    return static_cast<int>(m_layers.size());
96
0
}
97
98
/************************************************************************/
99
/*           GDALVectorPipelineReadOutputDataset::GetLayer()            */
100
/************************************************************************/
101
102
OGRLayer *GDALVectorPipelineReadOutputDataset::GetLayer(int idx) const
103
0
{
104
0
    return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr;
105
0
}
106
107
/************************************************************************/
108
/*        GDALVectorPipelineReadOutputDataset::TestCapability()         */
109
/************************************************************************/
110
111
int GDALVectorPipelineReadOutputDataset::TestCapability(
112
    const char *pszCap) const
113
0
{
114
0
    if (EQUAL(pszCap, ODsCRandomLayerRead))
115
0
        return m_srcDS.TestCapability(pszCap);
116
0
    return false;
117
0
}
118
119
/************************************************************************/
120
/*         GDALVectorPipelineReadOutputDataset::ResetReading()          */
121
/************************************************************************/
122
123
void GDALVectorPipelineReadOutputDataset::ResetReading()
124
0
{
125
0
    m_srcDS.ResetReading();
126
0
}
127
128
/************************************************************************/
129
/*        GDALVectorPipelineReadOutputDataset::GetNextFeature()         */
130
/************************************************************************/
131
132
OGRFeature *GDALVectorPipelineReadOutputDataset::GetNextFeature(
133
    OGRLayer **ppoBelongingLayer, double *pdfProgressPct,
134
    GDALProgressFunc pfnProgress, void *pProgressData)
135
0
{
136
0
    while (true)
137
0
    {
138
0
        OGRLayer *poBelongingLayer = nullptr;
139
0
        auto poFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature(
140
0
            &poBelongingLayer, pdfProgressPct, pfnProgress, pProgressData));
141
0
        if (ppoBelongingLayer)
142
0
            *ppoBelongingLayer = poBelongingLayer;
143
0
        if (!poFeature)
144
0
            break;
145
0
        if (std::find(m_layers.begin(), m_layers.end(), poBelongingLayer) !=
146
0
            m_layers.end())
147
0
            return poFeature.release();
148
0
    }
149
0
    return nullptr;
150
0
}
151
152
/************************************************************************/
153
/*                  GDALVectorReadAlgorithm::RunStep()                  */
154
/************************************************************************/
155
156
bool GDALVectorReadAlgorithm::RunStep(GDALPipelineStepRunContext &)
157
0
{
158
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
159
0
    CPLAssert(poSrcDS);
160
161
0
    CPLAssert(m_outputDataset.GetName().empty());
162
0
    CPLAssert(!m_outputDataset.GetDatasetRef());
163
164
0
    if (m_inputLayerNames.empty())
165
0
    {
166
0
        m_outputDataset.Set(poSrcDS);
167
0
    }
168
0
    else
169
0
    {
170
0
        auto poOutDS =
171
0
            std::make_unique<GDALVectorPipelineReadOutputDataset>(*poSrcDS);
172
0
        for (const auto &srcLayerName : m_inputLayerNames)
173
0
        {
174
0
            auto poSrcLayer = poSrcDS->GetLayerByName(srcLayerName.c_str());
175
0
            if (!poSrcLayer)
176
0
            {
177
0
                ReportError(CE_Failure, CPLE_AppDefined,
178
0
                            "Cannot find source layer '%s'",
179
0
                            srcLayerName.c_str());
180
0
                return false;
181
0
            }
182
0
            poOutDS->AddLayer(*poSrcLayer);
183
0
        }
184
0
        m_outputDataset.Set(std::move(poOutDS));
185
0
    }
186
0
    return true;
187
0
}
188
189
//! @endcond