GDAL
gdalalg_vector_geom.h
1/******************************************************************************
2 *
3 * Project: GDAL
4 * Purpose: "geom" step of "vector pipeline", or "gdal vector geom" standalone
5 * Author: Even Rouault <even dot rouault at spatialys.com>
6 *
7 ******************************************************************************
8 * Copyright (c) 2025, Even Rouault <even dot rouault at spatialys.com>
9 *
10 * SPDX-License-Identifier: MIT
11 ****************************************************************************/
12
13#ifndef GDALALG_VECTOR_GEOM_INCLUDED
14#define GDALALG_VECTOR_GEOM_INCLUDED
15
16#include "gdalalg_vector_pipeline.h"
17#include "ogr_geos.h"
18
20
21/************************************************************************/
22/* GDALVectorGeomAlgorithm */
23/************************************************************************/
24
25class GDALVectorGeomAlgorithm /* non final */
26 : public GDALVectorPipelineStepAlgorithm
27{
28 public:
29 static constexpr const char *NAME = "geom";
30 static constexpr const char *DESCRIPTION =
31 "Geometry operations on a vector dataset.";
32 static constexpr const char *HELP_URL = "/programs/gdal_vector_geom.html";
33
34 explicit GDALVectorGeomAlgorithm(bool standaloneStep = false);
35
36 private:
37 bool RunStep(GDALPipelineStepRunContext &ctxt) override;
38
39 void WarnIfDeprecated() override;
40
43 template <class MyAlgorithm> bool RegisterSubAlgorithm(bool standalone)
44 {
45 GDALAlgorithmRegistry::AlgInfo info;
46 info.m_name = MyAlgorithm::NAME;
47 info.m_aliases = MyAlgorithm::GetAliasesStatic();
48 info.m_creationFunc = [standalone]() -> std::unique_ptr<GDALAlgorithm>
49 { return std::make_unique<MyAlgorithm>(standalone); };
51 }
52};
53
54/************************************************************************/
55/* GDALVectorGeomAlgorithmStandalone */
56/************************************************************************/
57
58class GDALVectorGeomAlgorithmStandalone final : public GDALVectorGeomAlgorithm
59{
60 public:
61 GDALVectorGeomAlgorithmStandalone()
62 : GDALVectorGeomAlgorithm(/* standaloneStep = */ true)
63 {
64 }
65
66 ~GDALVectorGeomAlgorithmStandalone() override;
67};
68
69/************************************************************************/
70/* GDALVectorGeomAbstractAlgorithm */
71/************************************************************************/
72
73class GDALVectorGeomAbstractAlgorithm /* non final */
74 : public GDALVectorPipelineStepAlgorithm
75{
76 protected:
77 struct OptionsBase
78 {
79 std::string m_activeLayer{};
80 std::string m_geomField{};
81 };
82
83 virtual std::unique_ptr<OGRLayerWithTranslateFeature>
84 CreateAlgLayer(OGRLayer &srcLayer) = 0;
85
86 GDALVectorGeomAbstractAlgorithm(const std::string &name,
87 const std::string &description,
88 const std::string &helpURL,
89 bool standaloneStep, OptionsBase &opts);
90
91 bool RunStep(GDALPipelineStepRunContext &ctxt) override;
92
93 private:
94 std::string &m_activeLayer;
95};
96
97/************************************************************************/
98/* GDALVectorGeomOneToOneAlgorithmLayer */
99/************************************************************************/
100
101template <class T>
102class GDALVectorGeomOneToOneAlgorithmLayer /* non final */
103 : public GDALVectorPipelineOutputLayer
104{
105 public:
106 const OGRFeatureDefn *GetLayerDefn() const override
107 {
108 return m_srcLayer.GetLayerDefn();
109 }
110
111 GIntBig GetFeatureCount(int bForce) override
112 {
113 if (!m_poAttrQuery && !m_poFilterGeom)
114 return m_srcLayer.GetFeatureCount(bForce);
115 return OGRLayer::GetFeatureCount(bForce);
116 }
117
118 OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
119 bool bForce) override
120 {
121 return m_srcLayer.GetExtent(iGeomField, psExtent, bForce);
122 }
123
124 OGRFeature *GetFeature(GIntBig nFID) override
125 {
126 auto poSrcFeature =
127 std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID));
128 if (!poSrcFeature)
129 return nullptr;
130 return TranslateFeature(std::move(poSrcFeature)).release();
131 }
132
133 int TestCapability(const char *pszCap) const override
134 {
135 if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) ||
136 EQUAL(pszCap, OLCMeasuredGeometries) ||
137 EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) ||
138 (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery &&
139 !m_poFilterGeom) ||
140 EQUAL(pszCap, OLCStringsAsUTF8))
141 {
142 return m_srcLayer.TestCapability(pszCap);
143 }
144 return false;
145 }
146
147 protected:
148 const typename T::Options m_opts;
149
150 GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer,
151 const typename T::Options &opts)
152 : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts)
153 {
154 SetDescription(oSrcLayer.GetDescription());
155 SetMetadata(oSrcLayer.GetMetadata());
156 if (!m_opts.m_geomField.empty())
157 {
158 const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex(
159 m_opts.m_geomField.c_str());
160 if (nIdx >= 0)
161 m_iGeomIdx = nIdx;
162 else
163 m_iGeomIdx = INT_MAX;
164 }
165 }
166
167 bool IsSelectedGeomField(int idx) const
168 {
169 return m_iGeomIdx < 0 || idx == m_iGeomIdx;
170 }
171
172 virtual std::unique_ptr<OGRFeature>
173 TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0;
174
175 void TranslateFeature(
176 std::unique_ptr<OGRFeature> poSrcFeature,
177 std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
178 {
179 auto poDstFeature = TranslateFeature(std::move(poSrcFeature));
180 if (poDstFeature)
181 apoOutFeatures.push_back(std::move(poDstFeature));
182 }
183
184 private:
185 int m_iGeomIdx = -1;
186};
187
188#ifdef HAVE_GEOS
189
190/************************************************************************/
191/* GDALGeosNonStreamingAlgorithmDataset */
192/************************************************************************/
193
200class GDALGeosNonStreamingAlgorithmDataset
201 : public GDALVectorNonStreamingAlgorithmDataset
202{
203 public:
204 GDALGeosNonStreamingAlgorithmDataset();
205
206 ~GDALGeosNonStreamingAlgorithmDataset() override;
207
208 CPL_DISALLOW_COPY_ASSIGN(GDALGeosNonStreamingAlgorithmDataset)
209
210 bool Process(OGRLayer &srcLayer, OGRLayer &dstLayer) override;
211
212 virtual bool ProcessGeos() = 0;
213
215 virtual bool PolygonsOnly() const = 0;
216
218 virtual bool SkipEmpty() const = 0;
219
220 void SetSourceGeometryField(int i)
221 {
222 m_sourceGeometryField = i;
223 }
224
225 protected:
226 GEOSContextHandle_t m_poGeosContext{nullptr};
227 std::vector<GEOSGeometry *> m_apoGeosInputs{};
228 GEOSGeometry *m_poGeosResultAsCollection{nullptr};
229 GEOSGeometry **m_papoGeosResults{nullptr};
230
231 private:
232 bool ConvertInputsToGeos(OGRLayer &srcLayer, OGRLayer &dstLayer,
233 bool sameDefn);
234
235 bool ConvertOutputsFromGeos(OGRLayer &dstLayer);
236
237 void Cleanup();
238
239 std::vector<std::unique_ptr<OGRFeature>> m_apoFeatures{};
240 unsigned int m_nGeosResultSize{0};
241 int m_sourceGeometryField{0};
242};
243
244#endif
245
247
248#endif /* GDALALG_VECTOR_GEOM_INCLUDED */
std::function m_creationFunc
Creation function.
Definition gdalalgorithm_cpp.h:2150
std::string m_name
Algorithm (short) name.
Definition gdalalgorithm_cpp.h:2145
std::vector< std::string > m_aliases
Aliases.
Definition gdalalgorithm_cpp.h:2147
bool RegisterSubAlgorithm()
Register the sub-algorithm of type MyAlgorithm.
Definition gdalalgorithm_cpp.h:2635
virtual char ** GetMetadata(const char *pszDomain="")
Fetch metadata.
Definition gdalmajorobject.cpp:228
virtual const char * GetDescription() const
Fetch object description.
Definition gdalmajorobject.cpp:61
virtual int GetGeomFieldIndex(const char *) const
Find geometry field by name.
Definition ogrfeaturedefn.cpp:950
virtual GIntBig GetFeatureCount(int bForce=TRUE)
Fetch the feature count in this layer.
Definition ogrlayer.cpp:205
virtual const OGRFeatureDefn * GetLayerDefn() const =0
Fetch the schema information for this layer.
#define EQUAL(a, b)
Alias for strcasecmp() == 0.
Definition cpl_port.h:541
#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
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition cpl_port.h:205
#define OLCStringsAsUTF8
Layer capability for strings returned with UTF-8 \ encoding.
Definition ogr_core.h:998
#define OLCFastFeatureCount
Layer capability for fast feature count retrieval .
Definition ogr_core.h:965
#define OLCZGeometries
Layer capability for geometry with Z dimension support.
Definition ogr_core.h:1010
#define OLCRandomRead
Layer capability for random read.
Definition ogr_core.h:959
#define OLCFastGetExtent
Layer capability for fast extent retrieval.
Definition ogr_core.h:968
#define OLCMeasuredGeometries
Layer capability for measured geometries support .
Definition ogr_core.h:1007
int OGRErr
Type for a OGR error.
Definition ogr_core.h:370
#define OLCCurveGeometries
Layer capability for curve geometries support.
Definition ogr_core.h:1005
struct GEOSContextHandle_HS * GEOSContextHandle_t
GEOS context handle type.
Definition ogr_geometry.h:110