GEOS  3.13.1
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 
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  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 
94 public:
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 
152 protected:
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:904
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: Angle.h:25