/src/gdal/apps/gdalalg_vector_convex_hull.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: GDAL |
4 | | * Purpose: "gdal vector convex-hull" |
5 | | * Author: Daniel Baston |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 2026, ISciences LLC |
9 | | * |
10 | | * SPDX-License-Identifier: MIT |
11 | | ****************************************************************************/ |
12 | | |
13 | | #include "gdalalg_vector_convex_hull.h" |
14 | | |
15 | | #include "gdal_priv.h" |
16 | | #include "ogrsf_frmts.h" |
17 | | |
18 | | #include <cinttypes> |
19 | | |
20 | | //! @cond Doxygen_Suppress |
21 | | |
22 | | #ifndef _ |
23 | | #define _(x) (x) |
24 | | #endif |
25 | | |
26 | | GDALVectorConvexHullAlgorithm::GDALVectorConvexHullAlgorithm( |
27 | | bool standaloneStep) |
28 | 0 | : GDALVectorGeomAbstractAlgorithm(NAME, DESCRIPTION, HELP_URL, |
29 | 0 | standaloneStep, m_opts) |
30 | 0 | { |
31 | 0 | } |
32 | | |
33 | | #ifdef HAVE_GEOS |
34 | | |
35 | | namespace |
36 | | { |
37 | | |
38 | | class GDALVectorConvexHullAlgorithmLayer final |
39 | | : public GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorConvexHullAlgorithm> |
40 | | { |
41 | | public: |
42 | | GDALVectorConvexHullAlgorithmLayer( |
43 | | OGRLayer &oSrcLayer, const GDALVectorConvexHullAlgorithm::Options &opts) |
44 | | : GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorConvexHullAlgorithm>( |
45 | | oSrcLayer, opts), |
46 | | m_poFeatureDefn(oSrcLayer.GetLayerDefn()->Clone()) |
47 | | { |
48 | | m_poFeatureDefn->Reference(); |
49 | | |
50 | | // Convex hull output type can be Point/LineString/Polygon depending on input. |
51 | | // To avoid schema/type conflicts, advertise unknown geometry type for |
52 | | // processed geometry fields. |
53 | | for (int i = 0; i < m_poFeatureDefn->GetGeomFieldCount(); ++i) |
54 | | { |
55 | | if (IsSelectedGeomField(i)) |
56 | | m_poFeatureDefn->GetGeomFieldDefn(i)->SetType(wkbUnknown); |
57 | | } |
58 | | } |
59 | | |
60 | | ~GDALVectorConvexHullAlgorithmLayer() override |
61 | | { |
62 | | m_poFeatureDefn->Release(); |
63 | | } |
64 | | |
65 | | const OGRFeatureDefn *GetLayerDefn() const override |
66 | | { |
67 | | return m_poFeatureDefn; |
68 | | } |
69 | | |
70 | | protected: |
71 | | using GDALVectorGeomOneToOneAlgorithmLayer::TranslateFeature; |
72 | | |
73 | | std::unique_ptr<OGRFeature> |
74 | | TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const override |
75 | | { |
76 | | const int nGeomFieldCount = poSrcFeature->GetGeomFieldCount(); |
77 | | for (int i = 0; i < nGeomFieldCount; ++i) |
78 | | { |
79 | | if (!IsSelectedGeomField(i)) |
80 | | continue; |
81 | | |
82 | | if (const OGRGeometry *poGeom = poSrcFeature->GetGeomFieldRef(i)) |
83 | | { |
84 | | std::unique_ptr<OGRGeometry> poHull(poGeom->ConvexHull()); |
85 | | if (!poHull) |
86 | | { |
87 | | CPLError( |
88 | | CE_Failure, CPLE_AppDefined, |
89 | | "Failed to compute convex hull of feature %" PRId64, |
90 | | static_cast<int64_t>(poSrcFeature->GetFID())); |
91 | | return nullptr; |
92 | | } |
93 | | |
94 | | poHull->assignSpatialReference(poGeom->getSpatialReference()); |
95 | | poSrcFeature->SetGeomField(i, std::move(poHull)); |
96 | | } |
97 | | } |
98 | | |
99 | | poSrcFeature->SetFDefnUnsafe(m_poFeatureDefn); |
100 | | return poSrcFeature; |
101 | | } |
102 | | |
103 | | private: |
104 | | OGRFeatureDefn *const m_poFeatureDefn; |
105 | | |
106 | | CPL_DISALLOW_COPY_ASSIGN(GDALVectorConvexHullAlgorithmLayer) |
107 | | }; |
108 | | |
109 | | } // namespace |
110 | | |
111 | | #endif // HAVE_GEOS |
112 | | |
113 | | std::unique_ptr<OGRLayerWithTranslateFeature> |
114 | | GDALVectorConvexHullAlgorithm::CreateAlgLayer( |
115 | | [[maybe_unused]] OGRLayer &srcLayer) |
116 | 0 | { |
117 | | #ifdef HAVE_GEOS |
118 | | return std::make_unique<GDALVectorConvexHullAlgorithmLayer>(srcLayer, |
119 | | m_opts); |
120 | | #else |
121 | 0 | CPLAssert(false); |
122 | 0 | return nullptr; |
123 | 0 | #endif |
124 | 0 | } |
125 | | |
126 | | bool GDALVectorConvexHullAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt) |
127 | 0 | { |
128 | | #ifdef HAVE_GEOS |
129 | | return GDALVectorGeomAbstractAlgorithm::RunStep(ctxt); |
130 | | #else |
131 | 0 | (void)ctxt; |
132 | 0 | ReportError(CE_Failure, CPLE_NotSupported, |
133 | 0 | "This algorithm is only supported for builds against GEOS"); |
134 | 0 | return false; |
135 | 0 | #endif |
136 | 0 | } |
137 | | |
138 | | GDALVectorConvexHullAlgorithmStandalone:: |
139 | 0 | ~GDALVectorConvexHullAlgorithmStandalone() = default; |
140 | | |
141 | | //! @endcond |