Coverage Report

Created: 2026-04-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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