Line data Source code
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 80 : GDALVectorConvexHullAlgorithm::GDALVectorConvexHullAlgorithm( 27 80 : bool standaloneStep) 28 : : GDALVectorGeomAbstractAlgorithm(NAME, DESCRIPTION, HELP_URL, 29 80 : standaloneStep, m_opts) 30 : { 31 80 : } 32 : 33 : #ifdef HAVE_GEOS 34 : 35 : namespace 36 : { 37 : 38 : class GDALVectorConvexHullAlgorithmLayer final 39 : : public GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorConvexHullAlgorithm> 40 : { 41 : public: 42 3 : GDALVectorConvexHullAlgorithmLayer( 43 : OGRLayer &oSrcLayer, const GDALVectorConvexHullAlgorithm::Options &opts) 44 3 : : GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorConvexHullAlgorithm>( 45 : oSrcLayer, opts), 46 3 : 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 6 : for (int i = 0; i < m_poFeatureDefn->GetGeomFieldCount(); ++i) 52 : { 53 3 : if (IsSelectedGeomField(i)) 54 3 : m_poFeatureDefn->GetGeomFieldDefn(i)->SetType(wkbUnknown); 55 : } 56 3 : } 57 : 58 6 : const OGRFeatureDefn *GetLayerDefn() const override 59 : { 60 6 : return m_poFeatureDefn.get(); 61 : } 62 : 63 : protected: 64 : using GDALVectorGeomOneToOneAlgorithmLayer::TranslateFeature; 65 : 66 : std::unique_ptr<OGRFeature> 67 3 : TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const override 68 : { 69 3 : const int nGeomFieldCount = poSrcFeature->GetGeomFieldCount(); 70 6 : for (int i = 0; i < nGeomFieldCount; ++i) 71 : { 72 3 : if (!IsSelectedGeomField(i)) 73 0 : continue; 74 : 75 3 : if (const OGRGeometry *poGeom = poSrcFeature->GetGeomFieldRef(i)) 76 : { 77 3 : std::unique_ptr<OGRGeometry> poHull(poGeom->ConvexHull()); 78 3 : if (!poHull) 79 : { 80 0 : CPLError( 81 : CE_Failure, CPLE_AppDefined, 82 : "Failed to compute convex hull of feature %" PRId64, 83 0 : static_cast<int64_t>(poSrcFeature->GetFID())); 84 0 : return nullptr; 85 : } 86 : 87 3 : poHull->assignSpatialReference(poGeom->getSpatialReference()); 88 3 : poSrcFeature->SetGeomField(i, std::move(poHull)); 89 : } 90 : } 91 : 92 3 : poSrcFeature->SetFDefnUnsafe(m_poFeatureDefn.get()); 93 3 : 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 3 : GDALVectorConvexHullAlgorithm::CreateAlgLayer( 108 : [[maybe_unused]] OGRLayer &srcLayer) 109 : { 110 : #ifdef HAVE_GEOS 111 3 : return std::make_unique<GDALVectorConvexHullAlgorithmLayer>(srcLayer, 112 3 : m_opts); 113 : #else 114 : CPLAssert(false); 115 : return nullptr; 116 : #endif 117 : } 118 : 119 3 : bool GDALVectorConvexHullAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt) 120 : { 121 : #ifdef HAVE_GEOS 122 3 : return GDALVectorGeomAbstractAlgorithm::RunStep(ctxt); 123 : #else 124 : (void)ctxt; 125 : ReportError(CE_Failure, CPLE_NotSupported, 126 : "This algorithm is only supported for builds against GEOS"); 127 : return false; 128 : #endif 129 : } 130 : 131 : GDALVectorConvexHullAlgorithmStandalone:: 132 : ~GDALVectorConvexHullAlgorithmStandalone() = default; 133 : 134 : //! @endcond