Coverage Report

Created: 2026-07-25 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/apps/gdalalg_vector_geom.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  GDAL
4
 * Purpose:  Base classes for some geometry-related vector algorithms
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 "gdalvectorpipelinestepalgorithm.h"
17
18
#include "ogr_geos.h"
19
20
//! @cond Doxygen_Suppress
21
22
/************************************************************************/
23
/*                   GDALVectorGeomAbstractAlgorithm                    */
24
/************************************************************************/
25
26
class GDALVectorGeomAbstractAlgorithm /* non final */
27
    : public GDALVectorPipelineStepAlgorithm
28
{
29
  protected:
30
    struct OptionsBase
31
    {
32
        std::string m_activeLayer{};
33
        std::string m_geomField{};
34
    };
35
36
    virtual std::unique_ptr<OGRLayerWithTranslateFeature>
37
    CreateAlgLayer(OGRLayer &srcLayer) = 0;
38
39
    GDALVectorGeomAbstractAlgorithm(const std::string &name,
40
                                    const std::string &description,
41
                                    const std::string &helpURL,
42
                                    bool standaloneStep, OptionsBase &opts);
43
44
    bool RunStep(GDALPipelineStepRunContext &ctxt) override;
45
46
  private:
47
    std::string &m_activeLayer;
48
};
49
50
/************************************************************************/
51
/*                 GDALVectorGeomOneToOneAlgorithmLayer                 */
52
/************************************************************************/
53
54
template <class T>
55
class GDALVectorGeomOneToOneAlgorithmLayer /* non final */
56
    : public GDALVectorPipelineOutputLayer
57
{
58
  public:
59
    const OGRFeatureDefn *GetLayerDefn() const override
60
0
    {
61
0
        return m_srcLayer.GetLayerDefn();
62
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::GetLayerDefn() const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::GetLayerDefn() const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::GetLayerDefn() const
63
64
    GIntBig GetFeatureCount(int bForce) override
65
0
    {
66
0
        if (!m_poAttrQuery && !m_poFilterGeom)
67
0
            return m_srcLayer.GetFeatureCount(bForce);
68
0
        return OGRLayer::GetFeatureCount(bForce);
69
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::GetFeatureCount(int)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::GetFeatureCount(int)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::GetFeatureCount(int)
70
71
    OGRErr IGetExtent(int iGeomField, OGREnvelope *psExtent,
72
                      bool bForce) override
73
0
    {
74
0
        return m_srcLayer.GetExtent(iGeomField, psExtent, bForce);
75
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::IGetExtent(int, OGREnvelope*, bool)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::IGetExtent(int, OGREnvelope*, bool)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::IGetExtent(int, OGREnvelope*, bool)
76
77
    OGRFeature *GetFeature(GIntBig nFID) override
78
0
    {
79
0
        auto poSrcFeature =
80
0
            std::unique_ptr<OGRFeature>(m_srcLayer.GetFeature(nFID));
81
0
        if (!poSrcFeature)
82
0
            return nullptr;
83
0
        return TranslateFeature(std::move(poSrcFeature)).release();
84
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::GetFeature(long long)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::GetFeature(long long)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::GetFeature(long long)
85
86
    int TestCapability(const char *pszCap) const override
87
0
    {
88
0
        if (EQUAL(pszCap, OLCRandomRead) || EQUAL(pszCap, OLCCurveGeometries) ||
89
0
            EQUAL(pszCap, OLCMeasuredGeometries) ||
90
0
            EQUAL(pszCap, OLCZGeometries) || EQUAL(pszCap, OLCFastGetExtent) ||
91
0
            (EQUAL(pszCap, OLCFastFeatureCount) && !m_poAttrQuery &&
92
0
             !m_poFilterGeom) ||
93
0
            EQUAL(pszCap, OLCStringsAsUTF8))
94
0
        {
95
0
            return m_srcLayer.TestCapability(pszCap);
96
0
        }
97
0
        return false;
98
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::TestCapability(char const*) const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::TestCapability(char const*) const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::TestCapability(char const*) const
99
100
  protected:
101
    const typename T::Options m_opts;
102
103
    GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer &oSrcLayer,
104
                                         const typename T::Options &opts)
105
0
        : GDALVectorPipelineOutputLayer(oSrcLayer), m_opts(opts)
106
0
    {
107
0
        SetDescription(oSrcLayer.GetDescription());
108
0
        SetMetadata(oSrcLayer.GetMetadata());
109
0
        if (!m_opts.m_geomField.empty())
110
0
        {
111
0
            const int nIdx = oSrcLayer.GetLayerDefn()->GetGeomFieldIndex(
112
0
                m_opts.m_geomField.c_str());
113
0
            if (nIdx >= 0)
114
0
                m_iGeomIdx = nIdx;
115
0
            else
116
0
                m_iGeomIdx = INT_MAX;
117
0
        }
118
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer&, GDALVectorSetGeomTypeAlgorithm::Options const&)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer&, GDALVectorSegmentizeAlgorithm::Options const&)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::GDALVectorGeomOneToOneAlgorithmLayer(OGRLayer&, GDALVectorSwapXYAlgorithm::Options const&)
119
120
    bool IsSelectedGeomField(int idx) const
121
0
    {
122
0
        return m_iGeomIdx < 0 || idx == m_iGeomIdx;
123
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::IsSelectedGeomField(int) const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::IsSelectedGeomField(int) const
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::IsSelectedGeomField(int) const
124
125
    virtual std::unique_ptr<OGRFeature>
126
    TranslateFeature(std::unique_ptr<OGRFeature> poSrcFeature) const = 0;
127
128
    bool TranslateFeature(
129
        std::unique_ptr<OGRFeature> poSrcFeature,
130
        std::vector<std::unique_ptr<OGRFeature>> &apoOutFeatures) override
131
0
    {
132
0
        auto poDstFeature = TranslateFeature(std::move(poSrcFeature));
133
0
        if (poDstFeature && PassesFilters(poDstFeature.get()))
134
0
            apoOutFeatures.push_back(std::move(poDstFeature));
135
0
        return true;
136
0
    }
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSetGeomTypeAlgorithm>::TranslateFeature(std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::vector<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::allocator<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> > > >&)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSegmentizeAlgorithm>::TranslateFeature(std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::vector<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::allocator<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> > > >&)
Unexecuted instantiation: GDALVectorGeomOneToOneAlgorithmLayer<GDALVectorSwapXYAlgorithm>::TranslateFeature(std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::vector<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> >, std::__1::allocator<std::__1::unique_ptr<OGRFeature, std::__1::default_delete<OGRFeature> > > >&)
137
138
  private:
139
    int m_iGeomIdx = -1;
140
};
141
142
#ifdef HAVE_GEOS
143
144
/************************************************************************/
145
/*                  GDALGeosNonStreamingAlgorithmLayer                  */
146
/************************************************************************/
147
148
/** A GDALGeosNonStreamingAlgorithmLayer manages the work of reading features
149
 *  from an input layer, converting OGR geometries into GEOS geometries,
150
 *  applying a GEOS function, and creating OGRFeatures for the results. It
151
 *  appropriate only for GEOS algorithms that operate on all input geometries
152
 *  at a single time.
153
 */
154
class GDALGeosNonStreamingAlgorithmLayer
155
    : public GDALVectorNonStreamingAlgorithmLayer
156
{
157
  public:
158
    GDALGeosNonStreamingAlgorithmLayer(OGRLayer &srcLayer, int geomFieldIndex);
159
160
    ~GDALGeosNonStreamingAlgorithmLayer() override;
161
162
    void ResetReading() override;
163
164
    CPL_DISALLOW_COPY_ASSIGN(GDALGeosNonStreamingAlgorithmLayer)
165
166
    bool Process(GDALProgressFunc pfnProgress, void *pProgressData) override;
167
168
    std::unique_ptr<OGRFeature> GetNextProcessedFeature() override;
169
170
    virtual bool ProcessGeos() = 0;
171
172
    /// Whether the operation should fail if non-polygonal geometries are present
173
    virtual bool PolygonsOnly() const = 0;
174
175
    /// Whether empty result features should be excluded from the output
176
    virtual bool SkipEmpty() const = 0;
177
178
  protected:
179
    GEOSContextHandle_t m_poGeosContext{nullptr};
180
    std::vector<GEOSGeometry *> m_apoGeosInputs{};
181
    GEOSGeometry *m_poGeosResultAsCollection{nullptr};
182
    GEOSGeometry **m_papoGeosResults{nullptr};
183
184
  private:
185
    bool ConvertInputsToGeos(OGRLayer &srcLayer, int geomFieldIndex,
186
                             GDALProgressFunc pfnProgress, void *pProgressData);
187
188
    void Cleanup();
189
190
    std::vector<std::unique_ptr<OGRFeature>> m_apoFeatures{};
191
    unsigned int m_nGeosResultSize{0};
192
    unsigned int m_readPos{0};
193
};
194
195
#endif
196
197
//! @endcond
198
199
#endif /* GDALALG_VECTOR_GEOM_INCLUDED */