Coverage Report

Created: 2026-06-30 08:33

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
44
    : public GDALVectorDecoratedDataset
45
{
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
    OGRLayer *ExecuteSQL(const char *pszStatement, OGRGeometry *poSpatialFilter,
64
                         const char *pszDialect) override;
65
    void ReleaseResultSet(OGRLayer *poResultsSet) override;
66
67
    OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
68
                               double *pdfProgressPct,
69
                               GDALProgressFunc pfnProgress,
70
                               void *pProgressData) override;
71
};
72
73
/************************************************************************/
74
/*                GDALVectorPipelineReadOutputDataset()                 */
75
/************************************************************************/
76
77
GDALVectorPipelineReadOutputDataset::GDALVectorPipelineReadOutputDataset(
78
    GDALDataset &srcDS)
79
0
    : GDALVectorDecoratedDataset(&srcDS)
80
0
{
81
0
    poDriver = m_srcDS.GetDriver();
82
0
}
83
84
/************************************************************************/
85
/*           GDALVectorPipelineReadOutputDataset::AddLayer()            */
86
/************************************************************************/
87
88
void GDALVectorPipelineReadOutputDataset::AddLayer(OGRLayer &oSrcLayer)
89
0
{
90
0
    m_layers.push_back(&oSrcLayer);
91
0
}
92
93
/************************************************************************/
94
/*         GDALVectorPipelineReadOutputDataset::GetLayerCount()         */
95
/************************************************************************/
96
97
int GDALVectorPipelineReadOutputDataset::GetLayerCount() const
98
0
{
99
0
    return static_cast<int>(m_layers.size());
100
0
}
101
102
/************************************************************************/
103
/*           GDALVectorPipelineReadOutputDataset::GetLayer()            */
104
/************************************************************************/
105
106
OGRLayer *GDALVectorPipelineReadOutputDataset::GetLayer(int idx) const
107
0
{
108
0
    return idx >= 0 && idx < GetLayerCount() ? m_layers[idx] : nullptr;
109
0
}
110
111
/************************************************************************/
112
/*        GDALVectorPipelineReadOutputDataset::TestCapability()         */
113
/************************************************************************/
114
115
int GDALVectorPipelineReadOutputDataset::TestCapability(
116
    const char *pszCap) const
117
0
{
118
0
    if (EQUAL(pszCap, ODsCRandomLayerRead))
119
0
        return m_srcDS.TestCapability(pszCap);
120
0
    return false;
121
0
}
122
123
/************************************************************************/
124
/*         GDALVectorPipelineReadOutputDataset::ResetReading()          */
125
/************************************************************************/
126
127
void GDALVectorPipelineReadOutputDataset::ResetReading()
128
0
{
129
0
    m_srcDS.ResetReading();
130
0
}
131
132
/************************************************************************/
133
/*          GDALVectorPipelineReadOutputDataset::ExecuteSQL()           */
134
/************************************************************************/
135
136
OGRLayer *
137
GDALVectorPipelineReadOutputDataset::ExecuteSQL(const char *pszStatement,
138
                                                OGRGeometry *poSpatialFilter,
139
                                                const char *pszDialect)
140
0
{
141
0
    return m_srcDS.ExecuteSQL(pszStatement, poSpatialFilter, pszDialect);
142
0
}
143
144
/************************************************************************/
145
/*       GDALVectorPipelineReadOutputDataset::ReleaseResultSet()        */
146
/************************************************************************/
147
148
void GDALVectorPipelineReadOutputDataset::ReleaseResultSet(
149
    OGRLayer *poResultsSet)
150
0
{
151
0
    m_srcDS.ReleaseResultSet(poResultsSet);
152
0
}
153
154
/************************************************************************/
155
/*        GDALVectorPipelineReadOutputDataset::GetNextFeature()         */
156
/************************************************************************/
157
158
OGRFeature *GDALVectorPipelineReadOutputDataset::GetNextFeature(
159
    OGRLayer **ppoBelongingLayer, double *pdfProgressPct,
160
    GDALProgressFunc pfnProgress, void *pProgressData)
161
0
{
162
0
    while (true)
163
0
    {
164
0
        OGRLayer *poBelongingLayer = nullptr;
165
0
        auto poFeature = std::unique_ptr<OGRFeature>(m_srcDS.GetNextFeature(
166
0
            &poBelongingLayer, pdfProgressPct, pfnProgress, pProgressData));
167
0
        if (ppoBelongingLayer)
168
0
            *ppoBelongingLayer = poBelongingLayer;
169
0
        if (!poFeature)
170
0
            break;
171
0
        if (std::find(m_layers.begin(), m_layers.end(), poBelongingLayer) !=
172
0
            m_layers.end())
173
0
            return poFeature.release();
174
0
    }
175
0
    return nullptr;
176
0
}
177
178
/************************************************************************/
179
/*                  GDALVectorReadAlgorithm::RunStep()                  */
180
/************************************************************************/
181
182
bool GDALVectorReadAlgorithm::RunStep(GDALPipelineStepRunContext &)
183
0
{
184
0
    auto poSrcDS = m_inputDataset[0].GetDatasetRef();
185
0
    CPLAssert(poSrcDS);
186
187
0
    CPLAssert(m_outputDataset.GetName().empty());
188
0
    CPLAssert(!m_outputDataset.GetDatasetRef());
189
190
0
    if (m_inputLayerNames.empty())
191
0
    {
192
0
        m_outputDataset.Set(poSrcDS);
193
0
    }
194
0
    else
195
0
    {
196
0
        auto poOutDS =
197
0
            std::make_unique<GDALVectorPipelineReadOutputDataset>(*poSrcDS);
198
0
        for (const auto &srcLayerName : m_inputLayerNames)
199
0
        {
200
0
            auto poSrcLayer = poSrcDS->GetLayerByName(srcLayerName.c_str());
201
0
            if (!poSrcLayer)
202
0
            {
203
0
                ReportError(CE_Failure, CPLE_AppDefined,
204
0
                            "Cannot find source layer '%s'",
205
0
                            srcLayerName.c_str());
206
0
                return false;
207
0
            }
208
0
            poOutDS->AddLayer(*poSrcLayer);
209
0
        }
210
0
        m_outputDataset.Set(std::move(poOutDS));
211
0
    }
212
0
    return true;
213
0
}
214
215
//! @endcond