Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_abstract_pipeline.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 GDALALG_ABSTRACT_PIPELINE_INCLUDED
14
#define GDALALG_ABSTRACT_PIPELINE_INCLUDED
15
16
//! @cond Doxygen_Suppress
17
18
#include "cpl_json.h"
19
20
#include "gdalalgorithm.h"
21
#include "gdalpipelinestepalgorithm.h"
22
#include "gdal_priv.h"
23
24
#include <algorithm>
25
26
// This is an easter egg to pay tribute to PROJ pipeline syntax
27
// We accept "gdal vector +gdal=pipeline +step +gdal=read +input=in.tif +step +gdal=reproject +output-crs=EPSG:32632 +step +gdal=write +output=out.tif +overwrite"
28
// as an alternative to (recommended):
29
// "gdal vector pipeline ! read in.tif ! reproject--output-crs=EPSG:32632 ! write out.tif --overwrite"
30
#ifndef GDAL_PIPELINE_PROJ_NOSTALGIA
31
#define GDAL_PIPELINE_PROJ_NOSTALGIA
32
#endif
33
34
/************************************************************************/
35
/*                    GDALAbstractPipelineAlgorithm                     */
36
/************************************************************************/
37
38
class GDALAbstractPipelineAlgorithm CPL_NON_FINAL
39
    : public GDALPipelineStepAlgorithm
40
{
41
  public:
42
    std::vector<std::string> GetAutoComplete(std::vector<std::string> &args,
43
                                             bool lastWordIsComplete,
44
                                             bool /* showAllOptions*/) override;
45
46
    bool Finalize() override;
47
48
    std::string GetUsageAsJSON() const override;
49
50
    bool
51
    ParseCommandLineArguments(const std::vector<std::string> &args) override;
52
53
    bool HasSteps() const
54
0
    {
55
0
        return !m_steps.empty();
56
0
    }
57
58
    static constexpr const char *OPEN_NESTED_PIPELINE = "[";
59
    static constexpr const char *CLOSE_NESTED_PIPELINE = "]";
60
61
    static constexpr const char *RASTER_SUFFIX = "-raster";
62
    static constexpr const char *VECTOR_SUFFIX = "-vector";
63
    static constexpr const char *MULTIDIM_SUFFIX = "-multidim";
64
65
  protected:
66
    friend class GDALTeeStepAlgorithmAbstract;
67
68
    GDALAbstractPipelineAlgorithm(
69
        const std::string &name, const std::string &description,
70
        const std::string &helpURL,
71
        const GDALPipelineStepAlgorithm::ConstructorOptions &options)
72
0
        : GDALPipelineStepAlgorithm(
73
0
              name, description, helpURL,
74
0
              ConstructorOptions(options).SetAutoOpenInputDatasets(false))
75
0
    {
76
0
    }
77
78
    std::string m_pipeline{};
79
80
    virtual GDALAlgorithmRegistry &GetStepRegistry() = 0;
81
82
    virtual const GDALAlgorithmRegistry &GetStepRegistry() const = 0;
83
84
    std::unique_ptr<GDALPipelineStepAlgorithm>
85
    GetStepAlg(const std::string &name) const;
86
87
    bool HasOutputString() const override;
88
89
    static bool IsReadSpecificArgument(const char *pszArgName);
90
    static bool IsWriteSpecificArgument(const char *pszArgName);
91
92
  private:
93
    friend class GDALPipelineAlgorithm;
94
    friend class GDALRasterPipelineAlgorithm;
95
    friend class GDALVectorPipelineAlgorithm;
96
    friend class GDALMdimPipelineAlgorithm;
97
98
    std::vector<std::unique_ptr<GDALPipelineStepAlgorithm>> m_steps{};
99
100
    std::unique_ptr<GDALPipelineStepAlgorithm> m_stepOnWhichHelpIsRequested{};
101
102
    bool m_bInnerPipeline = false;
103
    bool m_bExpectReadStep = true;
104
    int m_nFirstStepWithUnknownInputType = -1;
105
106
    enum class StepConstraint
107
    {
108
        MUST_BE,
109
        CAN_BE,
110
        CAN_NOT_BE
111
    };
112
113
    StepConstraint m_eLastStepAsWrite = StepConstraint::CAN_BE;
114
115
    std::vector<std::unique_ptr<GDALAbstractPipelineAlgorithm>>
116
        m_apoNestedPipelines{};
117
118
    // More would lead to unreadable pipelines
119
    static constexpr int MAX_NESTING_LEVEL = 3;
120
121
    bool
122
    CheckFirstAndLastStep(const std::vector<GDALPipelineStepAlgorithm *> &steps,
123
                          bool forAutoComplete) const;
124
125
    static int GetInputDatasetType(const GDALPipelineStepAlgorithm *alg);
126
127
    bool CopyStepAlgorithmFromAnother(GDALPipelineStepAlgorithm *dst,
128
                                      const GDALPipelineStepAlgorithm *src,
129
                                      bool maybeWriteStep) const;
130
131
    bool ParseCommandLineArguments(
132
        const std::vector<std::string> &args, bool forAutoComplete,
133
        std::vector<std::string> *pCurArgsForAutocomplete);
134
135
    bool RunStep(GDALPipelineStepRunContext &ctxt) override;
136
    enum class RunStepState
137
    {
138
        PROCESSED,
139
        GO_ON,
140
        ERROR,
141
    };
142
    RunStepState
143
    RunStepDealWithMultiProcessing(GDALPipelineStepRunContext &ctxt);
144
    RunStepState RunStepDealWithGDALGJson();
145
    bool RunStepDealWithStepUnknownInputType(size_t i, int nCurDatasetType);
146
    bool CheckStepHasNoInputDatasetAlreadySet(size_t i, GDALDataset *poCurDS);
147
148
    std::string
149
    BuildNestedPipeline(GDALPipelineStepAlgorithm *curAlg,
150
                        std::vector<std::string> &nestedPipelineArgs,
151
                        bool forAutoComplete,
152
                        std::vector<std::string> *pCurArgsForAutocomplete);
153
154
    bool SaveGDALGIntoFileOrString(const std::string &outFilename,
155
                                   std::string &outString) const;
156
157
    virtual std::unique_ptr<GDALAbstractPipelineAlgorithm>
158
    CreateNestedPipeline() const = 0;
159
};
160
161
//! @endcond
162
163
#endif