Coverage Report

Created: 2026-07-16 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/geos/include/geos/geom/SurfaceImpl.h
Line
Count
Source
1
/**********************************************************************
2
 *
3
 * GEOS - Geometry Engine Open Source
4
 * http://geos.osgeo.org
5
 *
6
 * Copyright (C) 2024 ISciences, LLC
7
 * Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
8
 * Copyright (C) 2005 2006 Refractions Research Inc.
9
 * Copyright (C) 2001-2002 Vivid Solutions Inc.
10
 *
11
 * This is free software; you can redistribute and/or modify it under
12
 * the terms of the GNU Lesser General Public Licence as published
13
 * by the Free Software Foundation.
14
 * See the COPYING file for more information.
15
 *
16
 **********************************************************************/
17
18
#pragma once
19
20
#include <geos/geom/CoordinateSequenceFilter.h>
21
#include <geos/geom/Curve.h>
22
#include <geos/geom/GeometryComponentFilter.h>
23
#include <geos/geom/GeometryFilter.h>
24
#include <geos/geom/LinearRing.h>
25
#include <geos/geom/Surface.h>
26
#include <geos/util/IllegalArgumentException.h>
27
28
namespace geos {
29
namespace geom {
30
31
template<typename RingType>
32
class SurfaceImpl : public Surface {
33
34
protected:
35
36
    SurfaceImpl(const SurfaceImpl& p)
37
        :
38
11.5k
        Surface(p),
39
11.5k
        shell(static_cast<RingType*>(p.shell->clone().release())),
40
11.5k
        holes(p.holes.size())
41
11.5k
    {
42
27.1k
        for (std::size_t i = 0; i < holes.size(); ++i) {
43
15.5k
            holes[i].reset(static_cast<RingType*>(p.holes[i]->clone().release()));
44
15.5k
        }
45
11.5k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::SurfaceImpl(geos::geom::SurfaceImpl<geos::geom::LinearRing> const&)
Line
Count
Source
38
11.1k
        Surface(p),
39
11.1k
        shell(static_cast<RingType*>(p.shell->clone().release())),
40
11.1k
        holes(p.holes.size())
41
11.1k
    {
42
26.6k
        for (std::size_t i = 0; i < holes.size(); ++i) {
43
15.4k
            holes[i].reset(static_cast<RingType*>(p.holes[i]->clone().release()));
44
15.4k
        }
45
11.1k
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::SurfaceImpl(geos::geom::SurfaceImpl<geos::geom::Curve> const&)
Line
Count
Source
38
425
        Surface(p),
39
425
        shell(static_cast<RingType*>(p.shell->clone().release())),
40
425
        holes(p.holes.size())
41
425
    {
42
509
        for (std::size_t i = 0; i < holes.size(); ++i) {
43
84
            holes[i].reset(static_cast<RingType*>(p.holes[i]->clone().release()));
44
84
        }
45
425
    }
46
47
    /**
48
     * Constructs a <code>Surface</code> with the given exterior
49
     * and interior boundaries.
50
     *
51
     * @param  newShell  the outer boundary of the new Polygon,
52
     *                   or <code>null</code> or an empty
53
             *         Curve if the empty geometry
54
     *                   is to be created.
55
     *
56
     * @param  newHoles  the rings defining the inner
57
     *                   boundaries of the new Surface, or
58
     *                   null or empty Curve
59
     *                   if the empty geometry is to be created.
60
     *
61
     * @param newFactory the GeometryFactory used to create this geometry
62
     *
63
     * Polygon will take ownership of shell and hole curves
64
     */
65
    SurfaceImpl(std::unique_ptr<RingType>&& newShell,
66
                const GeometryFactory& newFactory) :
67
150k
        Surface(&newFactory),
68
150k
        shell(std::move(newShell))
69
150k
    {
70
150k
        if (shell == nullptr) {
71
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
72
0
        }
73
74
150k
        validateConstruction();
75
150k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::SurfaceImpl(std::__1::unique_ptr<geos::geom::LinearRing, std::__1::default_delete<geos::geom::LinearRing> >&&, geos::geom::GeometryFactory const&)
Line
Count
Source
67
149k
        Surface(&newFactory),
68
149k
        shell(std::move(newShell))
69
149k
    {
70
149k
        if (shell == nullptr) {
71
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
72
0
        }
73
74
149k
        validateConstruction();
75
149k
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::SurfaceImpl(std::__1::unique_ptr<geos::geom::Curve, std::__1::default_delete<geos::geom::Curve> >&&, geos::geom::GeometryFactory const&)
Line
Count
Source
67
802
        Surface(&newFactory),
68
802
        shell(std::move(newShell))
69
802
    {
70
802
        if (shell == nullptr) {
71
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
72
0
        }
73
74
802
        validateConstruction();
75
802
    }
76
77
    SurfaceImpl(std::unique_ptr<RingType>&& newShell,
78
                std::vector<std::unique_ptr<RingType>>&& newHoles,
79
                const GeometryFactory& newFactory) :
80
311k
        Surface(&newFactory),
81
311k
        shell(std::move(newShell)),
82
311k
        holes(std::move(newHoles))
83
311k
    {
84
311k
        if (shell == nullptr) {
85
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
86
0
        }
87
88
311k
        validateConstruction();
89
311k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::SurfaceImpl(std::__1::unique_ptr<geos::geom::LinearRing, std::__1::default_delete<geos::geom::LinearRing> >&&, std::__1::vector<std::__1::unique_ptr<geos::geom::LinearRing, std::__1::default_delete<geos::geom::LinearRing> >, std::__1::allocator<std::__1::unique_ptr<geos::geom::LinearRing, std::__1::default_delete<geos::geom::LinearRing> > > >&&, geos::geom::GeometryFactory const&)
Line
Count
Source
80
310k
        Surface(&newFactory),
81
310k
        shell(std::move(newShell)),
82
310k
        holes(std::move(newHoles))
83
310k
    {
84
310k
        if (shell == nullptr) {
85
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
86
0
        }
87
88
310k
        validateConstruction();
89
310k
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::SurfaceImpl(std::__1::unique_ptr<geos::geom::Curve, std::__1::default_delete<geos::geom::Curve> >&&, std::__1::vector<std::__1::unique_ptr<geos::geom::Curve, std::__1::default_delete<geos::geom::Curve> >, std::__1::allocator<std::__1::unique_ptr<geos::geom::Curve, std::__1::default_delete<geos::geom::Curve> > > >&&, geos::geom::GeometryFactory const&)
Line
Count
Source
80
329
        Surface(&newFactory),
81
329
        shell(std::move(newShell)),
82
329
        holes(std::move(newHoles))
83
329
    {
84
329
        if (shell == nullptr) {
85
0
            shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
86
0
        }
87
88
329
        validateConstruction();
89
329
    }
90
91
public:
92
93
    const RingType*
94
    getExteriorRing() const override
95
3.73M
    {
96
3.73M
        return shell.get();
97
3.73M
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::getExteriorRing() const
Line
Count
Source
95
3.70M
    {
96
3.70M
        return shell.get();
97
3.70M
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::getExteriorRing() const
Line
Count
Source
95
33.3k
    {
96
33.3k
        return shell.get();
97
33.3k
    }
98
99
    RingType*
100
    getExteriorRing() override
101
9.11k
    {
102
9.11k
        return shell.get();
103
9.11k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::getExteriorRing()
Line
Count
Source
101
9.11k
    {
102
9.11k
        return shell.get();
103
9.11k
    }
Unexecuted instantiation: geos::geom::SurfaceImpl<geos::geom::Curve>::getExteriorRing()
104
105
    const RingType*
106
    getInteriorRingN(std::size_t n) const override
107
985k
    {
108
985k
        return holes[n].get();
109
985k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::getInteriorRingN(unsigned long) const
Line
Count
Source
107
979k
    {
108
979k
        return holes[n].get();
109
979k
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::getInteriorRingN(unsigned long) const
Line
Count
Source
107
5.54k
    {
108
5.54k
        return holes[n].get();
109
5.54k
    }
110
111
    RingType*
112
    getInteriorRingN(std::size_t n) override
113
3.00k
    {
114
3.00k
        return holes[n].get();
115
3.00k
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::getInteriorRingN(unsigned long)
Line
Count
Source
113
3.00k
    {
114
3.00k
        return holes[n].get();
115
3.00k
    }
Unexecuted instantiation: geos::geom::SurfaceImpl<geos::geom::Curve>::getInteriorRingN(unsigned long)
116
117
    size_t getNumInteriorRing() const override
118
2.38M
    {
119
2.38M
        return holes.size();
120
2.38M
    }
geos::geom::SurfaceImpl<geos::geom::LinearRing>::getNumInteriorRing() const
Line
Count
Source
118
2.36M
    {
119
2.36M
        return holes.size();
120
2.36M
    }
geos::geom::SurfaceImpl<geos::geom::Curve>::getNumInteriorRing() const
Line
Count
Source
118
13.7k
    {
119
13.7k
        return holes.size();
120
13.7k
    }
121
122
    /**
123
    * \brief
124
    * Take ownership of this Surface's exterior ring.
125
    * After releasing the exterior ring, the Surface should be
126
    * considered in a moved-from state and should not be accessed,
127
    * except to release the interior rings (if desired.)
128
    * @return exterior ring
129
    */
130
    std::unique_ptr<RingType>
131
    releaseExteriorRing()
132
    {
133
        return std::move(shell);
134
    }
135
136
    /**
137
    * \brief
138
    * Take ownership of this Surfaces's interior rings.
139
    * After releasing the rings, the Surface should be
140
    * considered in a moved-from state and should not be accessed,
141
    * except to release the exterior ring (if desired.)
142
    * @return vector of rings (may be empty)
143
    */
144
    std::vector<std::unique_ptr<RingType>> releaseInteriorRings()
145
    {
146
        return std::move(holes);
147
    }
148
149
protected:
150
    std::unique_ptr<RingType> shell;
151
    std::vector<std::unique_ptr<RingType>> holes;
152
153
};
154
155
}
156
}