/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 | | // Convex hull output type can be Point/LineString/Polygon depending on input. |
49 | | // To avoid schema/type conflicts, advertise unknown geometry type for |
50 | | // processed geometry fields. |
51 | | for (int i = 0; i < m_poFeatureDefn->GetGeomFieldCount(); ++i) |
52 | | { |
53 | | if (IsSelectedGeomField(i)) |
54 | | m_poFeatureDefn->GetGeomFieldDefn(i)->SetType(wkbUnknown); |
55 | | } |
56 | | } |
57 | | |
58 | | const OGRFeatureDefn *GetLayerDefn() const override |
59 | | { |
60 | | return m_poFeatureDefn.get(); |
61 | | } |
62 | | |
63 | | protected: |
64 | | using GDALVectorGeomOneToOneAlgorithmLayer::TranslateFeature; |
65 | | |
66 | | std::unique_ptr<OGRFeature> |
67 | | TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const override |
68 | | { |
69 | | const int nGeomFieldCount = poSrcFeature->GetGeomFieldCount(); |
70 | | for (int i = 0; i < nGeomFieldCount; ++i) |
71 | | { |
72 | | if (!IsSelectedGeomField(i)) |
73 | | continue; |
74 | | |
75 | | if (const OGRGeometry *poGeom = poSrcFeature->GetGeomFieldRef(i)) |
76 | | { |
77 | | std::unique_ptr<OGRGeometry> poHull(poGeom->ConvexHull()); |
78 | | if (!poHull) |
79 | | { |
80 | | CPLError( |
81 | | CE_Failure, CPLE_AppDefined, |
82 | | "Failed to compute convex hull of feature %" PRId64, |
83 | | static_cast<int64_t>(poSrcFeature->GetFID())); |
84 | | return nullptr; |
85 | | } |
86 | | |
87 | | poHull->assignSpatialReference(poGeom->getSpatialReference()); |
88 | | poSrcFeature->SetGeomField(i, std::move(poHull)); |
89 | | } |
90 | | } |
91 | | |
92 | | poSrcFeature->SetFDefnUnsafe(m_poFeatureDefn.get()); |
93 | | return poSrcFeature; |
94 | | } |
95 | | |
96 | | private: |
97 | | const OGRFeatureDefnRefCountedPtr m_poFeatureDefn; |
98 | | |
99 | | CPL_DISALLOW_COPY_ASSIGN(GDALVectorConvexHullAlgorithmLayer) |
100 | | }; |
101 | | |
102 | | } // namespace |
103 | | |
104 | | #endif // HAVE_GEOS |
105 | | |
106 | | std::unique_ptr<OGRLayerWithTranslateFeature> |
107 | | GDALVectorConvexHullAlgorithm::CreateAlgLayer( |
108 | | [[maybe_unused]] OGRLayer &srcLayer) |
109 | 0 | { |
110 | | #ifdef HAVE_GEOS |
111 | | return std::make_unique<GDALVectorConvexHullAlgorithmLayer>(srcLayer, |
112 | | m_opts); |
113 | | #else |
114 | 0 | CPLAssert(false); |
115 | 0 | return nullptr; |
116 | 0 | #endif |
117 | 0 | } |
118 | | |
119 | | bool GDALVectorConvexHullAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt) |
120 | 0 | { |
121 | | #ifdef HAVE_GEOS |
122 | | return GDALVectorGeomAbstractAlgorithm::RunStep(ctxt); |
123 | | #else |
124 | 0 | (void)ctxt; |
125 | 0 | ReportError(CE_Failure, CPLE_NotSupported, |
126 | 0 | "This algorithm is only supported for builds against GEOS"); |
127 | 0 | return false; |
128 | 0 | #endif |
129 | 0 | } |
130 | | |
131 | | GDALVectorConvexHullAlgorithmStandalone:: |
132 | 0 | ~GDALVectorConvexHullAlgorithmStandalone() = default; |
133 | | |
134 | | //! @endcond |