GEOS 3.14.0dev
SurfaceImpl.h
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
28namespace geos {
29namespace geom {
30
31template<typename RingType>
32class SurfaceImpl : public Surface {
33
34protected:
35
36 SurfaceImpl(const SurfaceImpl& p)
37 :
38 Surface(p),
39 shell(static_cast<RingType*>(p.shell->clone().release())),
40 holes(p.holes.size())
41 {
42 for (std::size_t i = 0; i < holes.size(); ++i) {
43 holes[i].reset(static_cast<RingType*>(p.holes[i]->clone().release()));
44 }
45 }
46
65 SurfaceImpl(std::unique_ptr<RingType>&& newShell,
66 const GeometryFactory& newFactory) :
67 Surface(&newFactory),
68 shell(std::move(newShell))
69 {
70 if (shell == nullptr) {
71 shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
72 }
73 }
74
75 SurfaceImpl(std::unique_ptr<RingType>&& newShell,
76 std::vector<std::unique_ptr<RingType>>&& newHoles,
77 const GeometryFactory& newFactory) :
78 Surface(&newFactory),
79 shell(std::move(newShell)),
80 holes(std::move(newHoles))
81 {
82 if (shell == nullptr) {
83 shell.reset(static_cast<RingType*>(createEmptyRing(newFactory).release()));
84 }
85
86 if(shell->isEmpty() && hasNonEmptyElements(&holes)) {
87 throw geos::util::IllegalArgumentException("shell is empty but holes are not");
88 }
89 if (hasNullElements(&holes)) {
90 throw geos::util::IllegalArgumentException("holes must not contain null elements");
91 }
92 }
93
94public:
95
96 const RingType*
97 getExteriorRing() const override
98 {
99 return shell.get();
100 }
101
102 RingType*
103 getExteriorRing() override
104 {
105 return shell.get();
106 }
107
108 const RingType*
109 getInteriorRingN(std::size_t n) const override
110 {
111 return holes[n].get();
112 }
113
114 RingType*
115 getInteriorRingN(std::size_t n) override
116 {
117 return holes[n].get();
118 }
119
120 size_t getNumInteriorRing() const override
121 {
122 return holes.size();
123 }
124
133 std::unique_ptr<RingType>
134 releaseExteriorRing()
135 {
136 return std::move(shell);
137 }
138
147 std::vector<std::unique_ptr<RingType>> releaseInteriorRings()
148 {
149 return std::move(holes);
150 }
151
152protected:
153 std::unique_ptr<RingType> shell;
154 std::vector<std::unique_ptr<RingType>> holes;
155
156};
157
158}
159}
static bool hasNullElements(const CoordinateSequence *list)
Returns true if the CoordinateSequence contains any null elements.
static bool hasNonEmptyElements(const std::vector< T > *geometries)
Returns true if the array contains any non-empty Geometrys.
Definition Geometry.h:903
std::unique_ptr< Geometry > clone() const
Make a deep-copy of this Geometry.
Definition Geometry.h:213
Indicates one or more illegal arguments.
Definition IllegalArgumentException.h:33
Basic namespace for all GEOS functionalities.
Definition geos.h:39