Coverage Report

Created: 2026-09-14 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
        bool mdimOutputAcceptsClassicRaster = false;  // only for mdim output
128
129
        inline ConstructorOptions &SetStandaloneStep(bool b)
130
0
        {
131
0
            standaloneStep = b;
132
0
            return *this;
133
0
        }
134
135
        inline ConstructorOptions &SetAddDefaultArguments(bool b)
136
0
        {
137
0
            addDefaultArguments = b;
138
0
            return *this;
139
0
        }
140
141
        inline ConstructorOptions &SetAddInputLayerNameArgument(bool b)
142
0
        {
143
0
            addInputLayerNameArgument = b;
144
0
            return *this;
145
0
        }
146
147
        inline ConstructorOptions &SetInputDatasetRequired(bool b)
148
0
        {
149
0
            inputDatasetRequired = b;
150
0
            return *this;
151
0
        }
152
153
        inline ConstructorOptions &SetInputDatasetPositional(bool b)
154
0
        {
155
0
            inputDatasetPositional = b;
156
0
            return *this;
157
0
        }
158
159
        inline ConstructorOptions &SetInputDatasetMaxCount(int maxCount)
160
0
        {
161
0
            inputDatasetMaxCount = maxCount;
162
0
            return *this;
163
0
        }
164
165
        inline ConstructorOptions &SetInputDatasetInputFlags(int flags)
166
0
        {
167
0
            inputDatasetInputFlags = flags;
168
0
            return *this;
169
0
        }
170
171
        inline ConstructorOptions &SetInputDatasetHelpMsg(const std::string &s)
172
0
        {
173
0
            inputDatasetHelpMsg = s;
174
0
            return *this;
175
0
        }
176
177
        inline ConstructorOptions &SetInputDatasetAlias(const std::string &s)
178
0
        {
179
0
            inputDatasetAlias = s;
180
0
            return *this;
181
0
        }
182
183
        inline ConstructorOptions &SetInputDatasetMetaVar(const std::string &s)
184
0
        {
185
0
            inputDatasetMetaVar = s;
186
0
            return *this;
187
0
        }
188
189
        inline ConstructorOptions &SetOutputDatasetHelpMsg(const std::string &s)
190
0
        {
191
0
            outputDatasetHelpMsg = s;
192
0
            return *this;
193
0
        }
194
195
        inline ConstructorOptions &SetAutoOpenInputDatasets(bool b)
196
0
        {
197
0
            autoOpenInputDatasets = b;
198
0
            return *this;
199
0
        }
200
201
        inline ConstructorOptions &SetOutputDatasetRequired(bool b)
202
0
        {
203
0
            outputDatasetRequired = b;
204
0
            return *this;
205
0
        }
206
207
        inline ConstructorOptions &
208
        SetOutputFormatCreateCapability(const std::string &capability)
209
0
        {
210
0
            outputFormatCreateCapability = capability;
211
0
            return *this;
212
0
        }
213
214
        /** Whether the output format of a multidimensional algorithm may also
215
         * be a classic raster driver, which is the case of algorithms whose
216
         * output is written by GDALMultiDimTranslate(). */
217
        inline ConstructorOptions &SetMdimOutputAcceptsClassicRaster(bool b)
218
0
        {
219
0
            mdimOutputAcceptsClassicRaster = b;
220
0
            return *this;
221
0
        }
222
223
        inline ConstructorOptions &SetAddAppendLayerArgument(bool b)
224
0
        {
225
0
            addAppendLayerArgument = b;
226
0
            return *this;
227
0
        }
228
229
        inline ConstructorOptions &SetAddOverwriteLayerArgument(bool b)
230
0
        {
231
0
            addOverwriteLayerArgument = b;
232
0
            return *this;
233
0
        }
234
235
        inline ConstructorOptions &SetAddUpdateArgument(bool b)
236
0
        {
237
0
            addUpdateArgument = b;
238
0
            return *this;
239
0
        }
240
241
        inline ConstructorOptions &SetAddUpsertArgument(bool b)
242
0
        {
243
0
            addUpsertArgument = b;
244
0
            return *this;
245
0
        }
246
247
        inline ConstructorOptions &SetNoCreateEmptyLayersArgument(bool b)
248
0
        {
249
0
            addNoCreateEmptyLayersArgument = b;
250
0
            return *this;
251
0
        }
252
253
        inline ConstructorOptions &SetAddSkipErrorsArgument(bool b)
254
0
        {
255
0
            addSkipErrorsArgument = b;
256
0
            return *this;
257
0
        }
258
259
        inline ConstructorOptions &SetAddOutputLayerNameArgument(bool b)
260
0
        {
261
0
            addOutputLayerNameArgument = b;
262
0
            return *this;
263
0
        }
264
265
        inline ConstructorOptions &
266
        SetOutputLayerNameAvailableInPipelineStep(bool b)
267
0
        {
268
0
            outputLayerNameAvailableInPipelineStep = b;
269
0
            return *this;
270
0
        }
271
    };
272
273
    GDALPipelineStepAlgorithm(const std::string &name,
274
                              const std::string &description,
275
                              const std::string &helpURL,
276
                              const ConstructorOptions &);
277
278
    friend class GDALPipelineAlgorithm;
279
    friend class GDALRasterPipelineAlgorithm;
280
    friend class GDALVectorPipelineAlgorithm;
281
    friend class GDALMdimPipelineAlgorithm;
282
    friend class GDALAbstractPipelineAlgorithm;
283
284
    virtual bool CanBeFirstStep() const
285
0
    {
286
0
        return false;
287
0
    }
288
289
    virtual bool CanBeMiddleStep() const
290
0
    {
291
0
        return !CanBeFirstStep() && !CanBeLastStep();
292
0
    }
293
294
    virtual bool CanBeLastStep() const
295
0
    {
296
0
        return false;
297
0
    }
298
299
    //! Whether a user parameter can cause a file to be written at a specified location
300
    virtual bool GeneratesFilesFromUserInput() const
301
0
    {
302
0
        return false;
303
0
    }
304
305
    virtual bool IsNativelyStreamingCompatible() const
306
0
    {
307
0
        return true;
308
0
    }
309
310
    virtual bool SupportsInputMultiThreading() const
311
0
    {
312
0
        return false;
313
0
    }
314
315
    virtual bool CanHandleNextStep(GDALPipelineStepAlgorithm *) const
316
0
    {
317
0
        return false;
318
0
    }
319
320
    virtual bool OutputDatasetAllowedBeforeRunningStep() const
321
0
    {
322
0
        return false;
323
0
    }
324
325
    virtual CPLJSONObject Get_OGR_SCHEMA_OpenOption_Layer() const
326
0
    {
327
0
        CPLJSONObject obj;
328
0
        obj.Deinit();
329
0
        return obj;
330
0
    }
331
332
    virtual bool RunStep(GDALPipelineStepRunContext &ctxt) = 0;
333
334
    bool m_standaloneStep = false;
335
    const ConstructorOptions m_constructorOptions;
336
    bool m_outputVRTCompatible = true;
337
    std::string m_helpDocCategory{};
338
339
    // Input arguments
340
    std::vector<GDALArgDatasetValue> m_inputDataset{};
341
    std::vector<std::string> m_openOptions{};
342
    std::vector<std::string> m_inputFormats{};
343
    std::vector<std::string> m_inputLayerNames{};
344
345
    // Output arguments
346
    bool m_stdout = false;
347
    std::string m_output{};
348
    GDALArgDatasetValue m_outputDataset{};
349
    std::string m_format{};
350
    std::vector<std::string> m_outputOpenOptions{};
351
    std::vector<std::string> m_creationOptions{};
352
    bool m_overwrite = false;
353
    std::string m_outputLayerName{};
354
    GDALInConstructionAlgorithmArg *m_outputFormatArg = nullptr;
355
    bool m_appendRaster = false;
356
357
    // Output arguments (vector specific)
358
    std::vector<std::string> m_layerCreationOptions{};
359
    bool m_update = false;
360
    bool m_overwriteLayer = false;
361
    bool m_appendLayer = false;
362
    bool m_upsert = false;
363
    bool m_skipErrors = false;
364
    bool m_noCreateEmptyLayers = false;
365
366
    void AddRasterInputArgs(bool openForMixedRasterVector, bool hiddenForCLI);
367
    void AddRasterOutputArgs(bool hiddenForCLI);
368
    void AddRasterHiddenInputDatasetArg();
369
370
    void AddVectorInputArgs(bool hiddenForCLI);
371
    void AddVectorHiddenInputDatasetArg();
372
    void AddVectorOutputArgs(bool hiddenForCLI,
373
                             bool shortNameOutputLayerAllowed);
374
    using GDALAlgorithm::AddOutputLayerNameArg;
375
    void AddOutputLayerNameArg(bool hiddenForCLI,
376
                               bool shortNameOutputLayerAllowed);
377
378
    void AddMdimInputArgs(bool openForMixedRasterVector, bool hiddenForCLI,
379
                          bool acceptRaster);
380
    void AddMdimOutputArgs(bool hiddenForCLI);
381
    void AddMdimHiddenInputDatasetArg();
382
383
    bool CreateDatasetSingleOutputLayerIfNeeded(
384
        GDALPipelineStepRunContext &ctxt, const std::string &defaultLayerName,
385
        GDALDataset *&poDstDS, bool &bTemporaryFile,
386
        std::unique_ptr<GDALDataset> &poNewRetDS, std::string &outputLayerName,
387
        OGRLayer *&poDstLayer);
388
389
  private:
390
    bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
391
    GDALAlgorithm::ProcessGDALGOutputRet ProcessGDALGOutput() override;
392
    bool CheckSafeForStreamOutput() override;
393
394
    CPL_DISALLOW_COPY_ASSIGN(GDALPipelineStepAlgorithm)
395
};
396
397
//! @endcond
398
399
#endif