-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
Copy pathgdalalg_vector_pipeline.h
190 lines (148 loc) · 6.35 KB
/
gdalalg_vector_pipeline.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
/******************************************************************************
*
* Project: GDAL
* Purpose: gdal "vector pipeline" subcommand
* Author: Even Rouault <even dot rouault at spatialys.com>
*
******************************************************************************
* Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/
#ifndef GDALALG_VECTOR_PIPELINE_INCLUDED
#define GDALALG_VECTOR_PIPELINE_INCLUDED
#include "gdalalgorithm.h"
#include "gdalalg_abstract_pipeline.h"
#include "ogrsf_frmts.h"
#include "ogrlayerwithtranslatefeature.h"
#include <map>
#include <vector>
//! @cond Doxygen_Suppress
/************************************************************************/
/* GDALVectorPipelineStepAlgorithm */
/************************************************************************/
class GDALVectorPipelineStepAlgorithm /* non final */ : public GDALAlgorithm
{
protected:
GDALVectorPipelineStepAlgorithm(const std::string &name,
const std::string &description,
const std::string &helpURL,
bool standaloneStep);
friend class GDALVectorPipelineAlgorithm;
friend class GDALAbstractPipelineAlgorithm<GDALVectorPipelineStepAlgorithm>;
virtual bool RunStep(GDALProgressFunc pfnProgress, void *pProgressData) = 0;
void AddInputArgs(bool hiddenForCLI);
void AddOutputArgs(bool hiddenForCLI, bool shortNameOutputLayerAllowed);
bool m_standaloneStep = false;
// Input arguments
GDALArgDatasetValue m_inputDataset{};
std::vector<std::string> m_openOptions{};
std::vector<std::string> m_inputFormats{};
std::vector<std::string> m_inputLayerNames{};
// Output arguments
GDALArgDatasetValue m_outputDataset{};
std::string m_format{};
std::vector<std::string> m_creationOptions{};
std::vector<std::string> m_layerCreationOptions{};
bool m_overwrite = false;
bool m_update = false;
bool m_overwriteLayer = false;
bool m_appendLayer = false;
std::string m_outputLayerName{};
private:
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override;
};
/************************************************************************/
/* GDALVectorPipelineAlgorithm */
/************************************************************************/
// This is an easter egg to pay tribute to PROJ pipeline syntax
// We accept "gdal vector +gdal=pipeline +step +gdal=read +input=poly.gpkg +step +gdal=reproject +dst-crs=EPSG:32632 +step +gdal=write +output=out.gpkg +overwrite"
// as an alternative to (recommended):
// "gdal vector pipeline ! read poly.gpkg ! reproject--dst-crs=EPSG:32632 ! write out.gpkg --overwrite"
#define GDAL_PIPELINE_PROJ_NOSTALGIA
class GDALVectorPipelineAlgorithm final
: public GDALAbstractPipelineAlgorithm<GDALVectorPipelineStepAlgorithm>
{
public:
static constexpr const char *NAME = "pipeline";
static constexpr const char *DESCRIPTION = "Process a vector dataset.";
static constexpr const char *HELP_URL =
"/programs/gdal_vector_pipeline.html";
static std::vector<std::string> GetAliases()
{
return {
#ifdef GDAL_PIPELINE_PROJ_NOSTALGIA
GDALAlgorithmRegistry::HIDDEN_ALIAS_SEPARATOR,
"+pipeline",
"+gdal=pipeline",
#endif
};
}
GDALVectorPipelineAlgorithm();
bool
ParseCommandLineArguments(const std::vector<std::string> &args) override;
std::string GetUsageForCLI(bool shortUsage,
const UsageOptions &usageOptions) const override;
protected:
GDALArgDatasetValue &GetOutputDataset() override
{
return m_outputDataset;
}
private:
std::string m_helpDocCategory{};
};
/************************************************************************/
/* GDALVectorPipelineOutputLayer */
/************************************************************************/
/** Class that implements GetNextFeature() by forwarding to
* OGRLayerWithTranslateFeature::TranslateFeature() implementation, which
* might return several features.
*/
class GDALVectorPipelineOutputLayer /* non final */
: public OGRLayerWithTranslateFeature,
public OGRGetNextFeatureThroughRaw<GDALVectorPipelineOutputLayer>
{
protected:
explicit GDALVectorPipelineOutputLayer(OGRLayer &oSrcLayer);
DEFINE_GET_NEXT_FEATURE_THROUGH_RAW(GDALVectorPipelineOutputLayer)
OGRLayer &m_srcLayer;
public:
void ResetReading() override;
OGRFeature *GetNextRawFeature();
private:
std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
size_t m_idxInPendingFeatures = 0;
};
/************************************************************************/
/* GDALVectorPipelineOutputDataset */
/************************************************************************/
/** Class used by vector pipeline steps to create an output on-the-fly
* dataset where they can store on-the-fly layers.
*/
class GDALVectorPipelineOutputDataset final : public GDALDataset
{
GDALDataset &m_srcDS;
std::map<OGRLayer *, OGRLayerWithTranslateFeature *>
m_mapSrcLayerToNewLayer{};
std::vector<std::unique_ptr<OGRLayerWithTranslateFeature>>
m_layersToDestroy{};
std::vector<OGRLayerWithTranslateFeature *> m_layers{};
OGRLayerWithTranslateFeature *m_belongingLayer = nullptr;
std::vector<std::unique_ptr<OGRFeature>> m_pendingFeatures{};
size_t m_idxInPendingFeatures = 0;
CPL_DISALLOW_COPY_ASSIGN(GDALVectorPipelineOutputDataset)
public:
explicit GDALVectorPipelineOutputDataset(GDALDataset &oSrcDS);
void AddLayer(OGRLayer &oSrcLayer,
std::unique_ptr<OGRLayerWithTranslateFeature> poNewLayer);
int GetLayerCount() override;
OGRLayer *GetLayer(int idx) override;
int TestCapability(const char *pszCap) override;
void ResetReading() override;
OGRFeature *GetNextFeature(OGRLayer **ppoBelongingLayer,
double *pdfProgressPct,
GDALProgressFunc pfnProgress,
void *pProgressData) override;
};
//! @endcond
#endif