Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalpipelinestepalgorithm.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  gdal "raster/vector pipeline" subcommand
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
#ifndef GDALPIPELINESTEPALGORITHM_INCLUDED
14
#define GDALPIPELINESTEPALGORITHM_INCLUDED
15
16
//! @cond Doxygen_Suppress
17
18
#include "gdalalgorithm.h"
19
20
#include "gdalpipelinestepruncontext.h"
21
22
/************************************************************************/
23
/*                      GDALPipelineStepAlgorithm                       */
24
/************************************************************************/
25
26
class OGRLayer;
27
28
class GDALPipelineStepAlgorithm /* non final */ : public GDALAlgorithm
29
{
30
  public:
31
    std::vector<GDALArgDatasetValue> &GetInputDatasets()
32
0
    {
33
0
        return m_inputDataset;
34
0
    }
35
36
    const std::vector<GDALArgDatasetValue> &GetInputDatasets() const
37
0
    {
38
0
        return m_inputDataset;
39
0
    }
40
41
    GDALArgDatasetValue &GetOutputDataset()
42
0
    {
43
0
        return m_outputDataset;
44
0
    }
45
46
    const GDALArgDatasetValue &GetOutputDataset() const
47
0
    {
48
0
        return m_outputDataset;
49
0
    }
50
51
    const std::string &GetOutputString() const
52
0
    {
53
0
        return m_output;
54
0
    }
55
56
    const std::string &GetOutputLayerName() const
57
0
    {
58
0
        return m_outputLayerName;
59
0
    }
60
61
    const std::string &GetOutputFormat() const
62
0
    {
63
0
        return m_format;
64
0
    }
65
66
    const std::vector<std::string> &GetCreationOptions() const
67
0
    {
68
0
        return m_creationOptions;
69
0
    }
70
71
    const std::vector<std::string> &GetLayerCreationOptions() const
72
0
    {
73
0
        return m_layerCreationOptions;
74
0
    }
75
76
    bool GetOverwriteLayer() const
77
0
    {
78
0
        return m_overwriteLayer;
79
0
    }
80
81
    bool GetAppendLayer() const
82
0
    {
83
0
        return m_appendLayer;
84
0
    }
85
86
    virtual int GetInputType() const = 0;
87
88
    virtual int GetOutputType() const = 0;
89
90
    bool Finalize() override;
91
92
    // Used by GDALDispatcherAlgorithm for vector info/convert
93
    GDALDataset *GetInputDatasetRef()
94
0
    {
95
0
        return m_inputDataset.empty() ? nullptr
96
0
                                      : m_inputDataset[0].GetDatasetRef();
97
0
    }
98
99
    // Used by GDALDispatcherAlgorithm for vector info/convert
100
    void SetInputDataset(GDALDataset *poDS);
101
102
  protected:
103
    struct ConstructorOptions
104
    {
105
        bool standaloneStep = false;
106
        bool addDefaultArguments = true;
107
        bool autoOpenInputDatasets = true;
108
        bool inputDatasetRequired = true;
109
        bool inputDatasetPositional = true;
110
        bool outputDatasetRequired = true;
111
        bool addInputLayerNameArgument = true;        // only for vector input
112
        bool addUpdateArgument = true;                // only for vector output
113
        bool addAppendLayerArgument = true;           // only for vector output
114
        bool addNoCreateEmptyLayersArgument = false;  // only for vector output
115
        bool addOverwriteLayerArgument = true;        // only for vector output
116
        bool addUpsertArgument = true;                // only for vector output
117
        bool addSkipErrorsArgument = true;            // only for vector output
118
        bool addOutputLayerNameArgument = true;       // only for vector output
119
        bool outputLayerNameAvailableInPipelineStep = false;
120
        int inputDatasetMaxCount = 1;
121
        int inputDatasetInputFlags = GADV_NAME | GADV_OBJECT;
122
        std::string inputDatasetHelpMsg{};
123
        std::string inputDatasetAlias{};
124
        std::string inputDatasetMetaVar = "INPUT";
125
        std::string outputDatasetHelpMsg{};
126
        std::string outputFormatCreateCapability = GDAL_DCAP_CREATECOPY;
127
128
        inline ConstructorOptions &SetStandaloneStep(bool b)
129
0
        {
130
0
            standaloneStep = b;
131
0
            return *this;
132
0
        }
133
134
        inline ConstructorOptions &SetAddDefaultArguments(bool b)
135
0
        {
136
0
            addDefaultArguments = b;
137
0
            return *this;
138
0
        }
139
140
        inline ConstructorOptions &SetAddInputLayerNameArgument(bool b)
141
0
        {
142
0
            addInputLayerNameArgument = b;
143
0
            return *this;
144
0
        }
145
146
        inline ConstructorOptions &SetInputDatasetRequired(bool b)
147
0
        {
148
0
            inputDatasetRequired = b;
149
0
            return *this;
150
0
        }
151
152
        inline ConstructorOptions &SetInputDatasetPositional(bool b)
153
0
        {
154
0
            inputDatasetPositional = b;
155
0
            return *this;
156
0
        }
157
158
        inline ConstructorOptions &SetInputDatasetMaxCount(int maxCount)
159
0
        {
160
0
            inputDatasetMaxCount = maxCount;
161
0
            return *this;
162
0
        }
163
164
        inline ConstructorOptions &SetInputDatasetInputFlags(int flags)
165
0
        {
166
0
            inputDatasetInputFlags = flags;
167
0
            return *this;
168
0
        }
169
170
        inline ConstructorOptions &SetInputDatasetHelpMsg(const std::string &s)
171
0
        {
172
0
            inputDatasetHelpMsg = s;
173
0
            return *this;
174
0
        }
175
176
        inline ConstructorOptions &SetInputDatasetAlias(const std::string &s)
177
0
        {
178
0
            inputDatasetAlias = s;
179
0
            return *this;
180
0
        }
181
182
        inline ConstructorOptions &SetInputDatasetMetaVar(const std::string &s)
183
0
        {
184
0
            inputDatasetMetaVar = s;
185
0
            return *this;
186
0
        }
187
188
        inline ConstructorOptions &SetOutputDatasetHelpMsg(const std::string &s)
189
0
        {
190
0
            outputDatasetHelpMsg = s;
191
0
            return *this;
192
0
        }
193
194
        inline ConstructorOptions &SetAutoOpenInputDatasets(bool b)
195
0
        {
196
0
            autoOpenInputDatasets = b;
197
0
            return *this;
198
0
        }
199
200
        inline ConstructorOptions &SetOutputDatasetRequired(bool b)
201
0
        {
202
0
            outputDatasetRequired = b;
203
0
            return *this;
204
0
        }
205
206
        inline ConstructorOptions &
207
        SetOutputFormatCreateCapability(const std::string &capability)
208
0
        {
209
0
            outputFormatCreateCapability = capability;
210
0
            return *this;
211
0
        }
212
213
        inline ConstructorOptions &SetAddAppendLayerArgument(bool b)
214
0
        {
215
0
            addAppendLayerArgument = b;
216
0
            return *this;
217
0
        }
218
219
        inline ConstructorOptions &SetAddOverwriteLayerArgument(bool b)
220
0
        {
221
0
            addOverwriteLayerArgument = b;
222
0
            return *this;
223
0
        }
224
225
        inline ConstructorOptions &SetAddUpdateArgument(bool b)
226
0
        {
227
0
            addUpdateArgument = b;
228
0
            return *this;
229
0
        }
230
231
        inline ConstructorOptions &SetAddUpsertArgument(bool b)
232
0
        {
233
0
            addUpsertArgument = b;
234
0
            return *this;
235
0
        }
236
237
        inline ConstructorOptions &SetNoCreateEmptyLayersArgument(bool b)
238
0
        {
239
0
            addNoCreateEmptyLayersArgument = b;
240
0
            return *this;
241
0
        }
242
243
        inline ConstructorOptions &SetAddSkipErrorsArgument(bool b)
244
0
        {
245
0
            addSkipErrorsArgument = b;
246
0
            return *this;
247
0
        }
248
249
        inline ConstructorOptions &SetAddOutputLayerNameArgument(bool b)
250
0
        {
251
0
            addOutputLayerNameArgument = b;
252
0
            return *this;
253
0
        }
254
255
        inline ConstructorOptions &
256
        SetOutputLayerNameAvailableInPipelineStep(bool b)
257
0
        {
258
0
            outputLayerNameAvailableInPipelineStep = b;
259
0
            return *this;
260
0
        }
261
    };
262
263
    GDALPipelineStepAlgorithm(const std::string &name,
264
                              const std::string &description,
265
                              const std::string &helpURL,
266
                              const ConstructorOptions &);
267
268
    friend class GDALPipelineAlgorithm;
269
    friend class GDALRasterPipelineAlgorithm;
270
    friend class GDALVectorPipelineAlgorithm;
271
    friend class GDALMdimPipelineAlgorithm;
272
    friend class GDALAbstractPipelineAlgorithm;
273
274
    virtual bool CanBeFirstStep() const
275
0
    {
276
0
        return false;
277
0
    }
278
279
    virtual bool CanBeMiddleStep() const
280
0
    {
281
0
        return !CanBeFirstStep() && !CanBeLastStep();
282
0
    }
283
284
    virtual bool CanBeLastStep() const
285
0
    {
286
0
        return false;
287
0
    }
288
289
    //! Whether a user parameter can cause a file to be written at a specified location
290
    virtual bool GeneratesFilesFromUserInput() const
291
0
    {
292
0
        return false;
293
0
    }
294
295
    virtual bool IsNativelyStreamingCompatible() const
296
0
    {
297
0
        return true;
298
0
    }
299
300
    virtual bool SupportsInputMultiThreading() const
301
0
    {
302
0
        return false;
303
0
    }
304
305
    virtual bool CanHandleNextStep(GDALPipelineStepAlgorithm *) const
306
0
    {
307
0
        return false;
308
0
    }
309
310
    virtual bool OutputDatasetAllowedBeforeRunningStep() const
311
0
    {
312
0
        return false;
313
0
    }
314
315
    virtual CPLJSONObject Get_OGR_SCHEMA_OpenOption_Layer() const
316
0
    {
317
0
        CPLJSONObject obj;
318
0
        obj.Deinit();
319
0
        return obj;
320
0
    }
321
322
    virtual bool RunStep(GDALPipelineStepRunContext &ctxt) = 0;
323
324
    bool m_standaloneStep = false;
325
    const ConstructorOptions m_constructorOptions;
326
    bool m_outputVRTCompatible = true;
327
    std::string m_helpDocCategory{};
328
329
    // Input arguments
330
    std::vector<GDALArgDatasetValue> m_inputDataset{};
331
    std::vector<std::string> m_openOptions{};
332
    std::vector<std::string> m_inputFormats{};
333
    std::vector<std::string> m_inputLayerNames{};
334
335
    // Output arguments
336
    bool m_stdout = false;
337
    std::string m_output{};
338
    GDALArgDatasetValue m_outputDataset{};
339
    std::string m_format{};
340
    std::vector<std::string> m_outputOpenOptions{};
341
    std::vector<std::string> m_creationOptions{};
342
    bool m_overwrite = false;
343
    std::string m_outputLayerName{};
344
    GDALInConstructionAlgorithmArg *m_outputFormatArg = nullptr;
345
    bool m_appendRaster = false;
346
347
    // Output arguments (vector specific)
348
    std::vector<std::string> m_layerCreationOptions{};
349
    bool m_update = false;
350
    bool m_overwriteLayer = false;
351
    bool m_appendLayer = false;
352
    bool m_upsert = false;
353
    bool m_skipErrors = false;
354
    bool m_noCreateEmptyLayers = false;
355
356
    void AddRasterInputArgs(bool openForMixedRasterVector, bool hiddenForCLI);
357
    void AddRasterOutputArgs(bool hiddenForCLI);
358
    void AddRasterHiddenInputDatasetArg();
359
360
    void AddVectorInputArgs(bool hiddenForCLI);
361
    void AddVectorHiddenInputDatasetArg();
362
    void AddVectorOutputArgs(bool hiddenForCLI,
363
                             bool shortNameOutputLayerAllowed);
364
    using GDALAlgorithm::AddOutputLayerNameArg;
365
    void AddOutputLayerNameArg(bool hiddenForCLI,
366
                               bool shortNameOutputLayerAllowed);
367
368
    void AddMdimInputArgs(bool openForMixedRasterVector, bool hiddenForCLI,
369
                          bool acceptRaster);
370
    void AddMdimOutputArgs(bool hiddenForCLI);
371
    void AddMdimHiddenInputDatasetArg();
372
373
    bool CreateDatasetSingleOutputLayerIfNeeded(
374
        GDALPipelineStepRunContext &ctxt, const std::string &defaultLayerName,
375
        GDALDataset *&poDstDS, bool &bTemporaryFile,
376
        std::unique_ptr<GDALDataset> &poNewRetDS, std::string &outputLayerName,
377
        OGRLayer *&poDstLayer);
378
379
  private:
380
    bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
381
    GDALAlgorithm::ProcessGDALGOutputRet ProcessGDALGOutput() override;
382
    bool CheckSafeForStreamOutput() override;
383
384
    CPL_DISALLOW_COPY_ASSIGN(GDALPipelineStepAlgorithm)
385
};
386
387
//! @endcond
388
389
#endif