/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 |