GDAL
gdalalg_vector_pipeline.h
1/******************************************************************************
2 *
3 * Project: GDAL
4 * Purpose: gdal "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_VECTOR_PIPELINE_INCLUDED
14#define GDALALG_VECTOR_PIPELINE_INCLUDED
15
16#include "gdalalgorithm.h"
17#include "gdalalg_abstract_pipeline.h"
18
19#include "ogrsf_frmts.h"
20#include "ogrlayerwithtranslatefeature.h"
21
22#include <map>
23#include <vector>
24
26
27/************************************************************************/
28/* GDALVectorPipelineStepAlgorithm */
29/************************************************************************/
30
31class GDALRasterAlgorithmStepRegistry;
32
33class GDALVectorPipelineStepAlgorithm /* non final */
34 : public GDALPipelineStepAlgorithm
35{
36 public:
37 ~GDALVectorPipelineStepAlgorithm() override;
38
39 protected:
40 GDALVectorPipelineStepAlgorithm(const std::string &name,
41 const std::string &description,
42 const std::string &helpURL,
43 bool standaloneStep);
44
45 GDALVectorPipelineStepAlgorithm(const std::string &name,
46 const std::string &description,
47 const std::string &helpURL,
48 const ConstructorOptions &options);
49
50 friend class GDALVectorPipelineAlgorithm;
51 friend class GDALVectorConcatAlgorithm;
52
53 int GetInputType() const override
54 {
55 return GDAL_OF_VECTOR;
56 }
57
58 int GetOutputType() const override
59 {
60 return GDAL_OF_VECTOR;
61 }
62};
63
64/************************************************************************/
65/* GDALVectorAlgorithmStepRegistry */
66/************************************************************************/
67
68class GDALVectorAlgorithmStepRegistry : public virtual GDALAlgorithmRegistry
69{
70 public:
71 GDALVectorAlgorithmStepRegistry() = default;
72 ~GDALVectorAlgorithmStepRegistry() override;
73
76 template <class MyAlgorithm>
77 bool Register(const std::string &name = std::string())
78 {
79 static_assert(
80 std::is_base_of_v<GDALVectorPipelineStepAlgorithm, MyAlgorithm>,
81 "Algorithm is not a GDALVectorPipelineStepAlgorithm");
82
83 AlgInfo info;
84 info.m_name = name.empty() ? MyAlgorithm::NAME : name;
85 info.m_aliases = MyAlgorithm::GetAliasesStatic();
86 info.m_creationFunc = []() -> std::unique_ptr<GDALAlgorithm>
87 { return std::make_unique<MyAlgorithm>(); };
89 }
90};
91
92/************************************************************************/
93/* GDALVectorPipelineAlgorithm */
94/************************************************************************/
95
96class GDALVectorPipelineAlgorithm final : public GDALAbstractPipelineAlgorithm
97{
98 public:
99 static constexpr const char *NAME = "pipeline";
100 static constexpr const char *DESCRIPTION =
101 "Process a vector dataset applying several steps.";
102 static constexpr const char *HELP_URL =
103 "/programs/gdal_vector_pipeline.html";
104
105 static std::vector<std::string> GetAliasesStatic()
106 {
107 return {
108#ifdef GDAL_PIPELINE_PROJ_NOSTALGIA
110 "+pipeline",
111 "+gdal=pipeline",
112#endif
113 };
114 }
115
116 GDALVectorPipelineAlgorithm();
117
118 std::string GetUsageForCLI(bool shortUsage,
119 const UsageOptions &usageOptions) const override;
120
121 static void RegisterAlgorithms(GDALVectorAlgorithmStepRegistry &registry,
122 bool forMixedPipeline);
123
124 int GetInputType() const override
125 {
126 return GDAL_OF_VECTOR;
127 }
128
129 int GetOutputType() const override
130 {
131 return GDAL_OF_VECTOR;
132 }
133
134 protected:
135 GDALVectorAlgorithmStepRegistry m_stepRegistry{};
136
137 GDALAlgorithmRegistry &GetStepRegistry() override
138 {
139 return m_stepRegistry;
140 }
141
142 const GDALAlgorithmRegistry &GetStepRegistry() const override
143 {
144 return m_stepRegistry;
145 }
146
147 private:
148 std::unique_ptr<GDALAbstractPipelineAlgorithm>
149 CreateNestedPipeline() const override
150 {
151 auto pipeline = std::make_unique<GDALVectorPipelineAlgorithm>();
152 pipeline->m_bInnerPipeline = true;
153 return pipeline;
154 }
155};
156
157/************************************************************************/
158/* GDALVectorOutputDataset */
159/************************************************************************/
160
161class GDALVectorOutputDataset final : public GDALDataset
162{
163
164 public:
165 int GetLayerCount() const override
166 {
167 return static_cast<int>(m_layers.size());
168 }
169
170 const OGRLayer *GetLayer(int idx) const override
171 {
172 return m_layers[idx].get();
173 }
174
175 int TestCapability(const char *) const override;
176
177 void AddLayer(std::unique_ptr<OGRLayer> layer)
178 {
179 m_layers.emplace_back(std::move(layer));
180 }
181
182 private:
183 std::vector<std::unique_ptr<OGRLayer>> m_layers{};
184};
185
186/************************************************************************/
187/* GDALVectorPipelineOutputLayer */
188/************************************************************************/
189
194class GDALVectorPipelineOutputLayer /* non final */
195 : public OGRLayerWithTranslateFeature,
196 public OGRGetNextFeatureThroughRaw<GDALVectorPipelineOutputLayer>
197{
198 protected:
199 explicit GDALVectorPipelineOutputLayer(OGRLayer &oSrcLayer);
200 ~GDALVectorPipelineOutputLayer() override;
201
202 DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorPipelineOutputLayer)
203
204 OGRLayer &m_srcLayer;
205
206 void FailTranslation()
207 {
208 m_translateError = true;
209 }
210
211 public:
212 void ResetReading() override;
213 OGRFeature *GetNextRawFeature();
214
215 private:
216 std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
217 size_t m_idxInPendingFeatures = 0;
218 bool m_translateError = false;
219};
220
221/************************************************************************/
222/* GDALVectorPipelinePassthroughLayer */
223/************************************************************************/
224
228class GDALVectorPipelinePassthroughLayer /* non final */
229 : public GDALVectorPipelineOutputLayer
230{
231 public:
232 explicit GDALVectorPipelinePassthroughLayer(OGRLayer &oSrcLayer)
233 : GDALVectorPipelineOutputLayer(oSrcLayer)
234 {
235 }
236
237 const OGRFeatureDefn *GetLayerDefn() const override;
238
239 int TestCapability(const char *pszCap) const override
240 {
241 return m_srcLayer.TestCapability(pszCap);
242 }
243
244 void TranslateFeature(
245 std::unique_ptr<OGRFeature> poSrcFeature,
246 std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
247 {
248 apoOutFeatures.push_back(std::move(poSrcFeature));
249 }
250};
251
252/************************************************************************/
253/* GDALVectorNonStreamingAlgorithmDataset */
254/************************************************************************/
255
256class MEMDataset;
257
262class GDALVectorNonStreamingAlgorithmDataset /* non final */
263 : public GDALDataset
264{
265 public:
266 GDALVectorNonStreamingAlgorithmDataset();
267 ~GDALVectorNonStreamingAlgorithmDataset() override;
268
269 virtual bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) = 0;
270
271 bool AddProcessedLayer(OGRLayer &srcLayer);
272 bool AddProcessedLayer(OGRLayer &srcLayer, OGRFeatureDefn &dstDefn);
273 void AddPassThroughLayer(OGRLayer &oLayer);
274 int GetLayerCount() const final override;
275 OGRLayer *GetLayer(int idx) const final override;
276 int TestCapability(const char *pszCap) const override;
277
278 private:
279 std::vector<std::unique_ptr<OGRLayer>> m_passthrough_layers{};
280 std::vector<OGRLayer *> m_layers{};
281 std::unique_ptr<MEMDataset> m_ds{};
282};
283
284/************************************************************************/
285/* GDALVectorPipelineOutputDataset */
286/************************************************************************/
287
291class GDALVectorPipelineOutputDataset final : public GDALDataset
292{
293 GDALDataset &m_srcDS;
294 std::map<OGRLayer *, OGRLayerWithTranslateFeature *>
295 m_mapSrcLayerToNewLayer{};
296 std::vector<std::unique_ptr<OGRLayerWithTranslateFeature>>
297 m_layersToDestroy{};
298 std::vector<OGRLayerWithTranslateFeature *> m_layers{};
299
300 OGRLayerWithTranslateFeature *m_belongingLayer = nullptr;
301 std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
302 size_t m_idxInPendingFeatures = 0;
303
304 CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineOutputDataset)
305
306 public:
307 explicit GDALVectorPipelineOutputDataset(GDALDataset &oSrcDS);
308
309 void AddLayer(OGRLayer &oSrcLayer,
310 std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer);
311
312 int GetLayerCount() const override;
313
314 OGRLayer *GetLayer(int idx) const override;
315
316 int TestCapability(const char *pszCap) const override;
317
318 void ResetReading() override;
319
320 OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
321 double *pdfProgressPct,
322 GDALProgressFunc pfnProgress,
323 void *pProgressData) override;
324};
325
327
328#endif
Registry of GDAL algorithms.
Definition gdalalgorithm_cpp.h:2132
static constexpr const char * HIDDEN_ALIAS_SEPARATOR
Special value to put in m_aliases to separate public alias from hidden aliases.
Definition gdalalgorithm_cpp.h:2136
bool Register()
Register the algorithm of type MyAlgorithm.
Definition gdalalgorithm_cpp.h:2159
A set of associated raster bands, usually from one file.
Definition gdal_dataset.h:76
virtual const OGRLayer * GetLayer(int iLayer) const
Fetch a layer by index.
Definition gdaldataset.cpp:7864
virtual void ResetReading()
Reset feature reading to start on the first feature.
Definition gdaldataset.cpp:7926
virtual OGRFeature * GetNextFeature(OGRLayer **ppoBelongingLayer, double *pdfProgressPct, GDALProgressFunc pfnProgress, void *pProgressData)
Fetch the next available feature from this dataset.
Definition gdaldataset.cpp:8016
virtual int TestCapability(const char *) const
Test if capability is available.
Definition gdaldataset.cpp:8241
virtual int GetLayerCount() const
Get the number of layers in this dataset.
Definition gdaldataset.cpp:7831
Template class offering a GetNextFeature() implementation relying on GetNextRawFeature().
Definition ogrsf_frmts.h:501
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition cpl_port.h:936
#define GDAL_OF_VECTOR
Allow vector drivers to be used.
Definition gdal.h:1091
Classes related to registration of format support, and opening datasets.
#define DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(BaseLayer)
Utility macro to define GetNextFeature() through GetNextRawFeature().
Definition ogrsf_frmts.h:531