GEOS  3.13.0dev
PolygonHoleJoiner.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2023 Paul Ramsey <pramsey@cleverelephant.ca>
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU Lesser General Public Licence as published
10  * by the Free Software Foundation.
11  * See the COPYING file for more information.
12  *
13  **********************************************************************/
14 
15 #pragma once
16 
17 #include <geos/geom/Coordinate.h>
18 #include <geos/geom/CoordinateSequence.h>
19 #include <geos/algorithm/LineIntersector.h>
20 #include <geos/noding/SegmentIntersector.h>
21 #include <geos/noding/BasicSegmentString.h>
22 #include <geos/noding/SegmentSetMutualIntersector.h>
23 #include <geos/constants.h>
24 
25 #include <set>
26 #include <limits>
27 
28 // Forward declarations
29 namespace geos {
30 namespace geom {
31 class Envelope;
32 class Geometry;
33 class LinearRing;
34 }
35 namespace noding {
36 }
37 }
38 
45 
46 
47 namespace geos {
48 namespace triangulate {
49 namespace polygon {
50 
51 
52 
69 class GEOS_DLL PolygonHoleJoiner {
70 
71 private:
72 
73  // Members
74 
75  const Polygon* inputPolygon;
76 
77  //-- normalized, sorted and noded polygon rings
78  std::unique_ptr<CoordinateSequence> shellRing;
79  std::vector<std::unique_ptr<CoordinateSequence>> holeRings;
80 
81  //-- indicates whether a hole should be testing for touching
82  std::vector<bool> isHoleTouchingHint;
83 
84  CoordinateSequence joinedRing;
85 
86  // a sorted and searchable version of the joinedRing
87  std::set<Coordinate> joinedPts;
88 
89  std::unique_ptr<SegmentSetMutualIntersector> boundaryIntersector;
90 
91  // holding place for some BasicSegmentStrings
92  std::vector<std::unique_ptr<BasicSegmentString>> polySegStringStore;
93 
94 
95  // Classes
96  class InteriorIntersectionDetector;
97  friend class PolygonHoleJoiner::InteriorIntersectionDetector;
98 
99 
100  void extractOrientedRings(const Polygon* polygon);
101  static std::unique_ptr<CoordinateSequence> extractOrientedRing(const LinearRing* ring, bool isCW);
102  void nodeRings();
103  void joinHoles();
104 
105  void joinHole(std::size_t index, const CoordinateSequence& holeCoords);
106 
114  bool joinTouchingHole(const CoordinateSequence& holeCoords);
115 
125  std::size_t findHoleTouchIndex(const CoordinateSequence& holeCoords);
126 
132  void joinNonTouchingHole(
133  const CoordinateSequence& holeCoords);
134 
135  const Coordinate& findJoinableVertex(
136  const Coordinate& holeJoinCoord);
137 
148  std::size_t findJoinIndex(
149  const Coordinate& joinCoord,
150  const Coordinate& holeJoinCoord);
151 
161  static bool isLineInterior(
162  const CoordinateSequence& ring,
163  std::size_t ringIndex,
164  const Coordinate& linePt);
165 
166  static std::size_t prev(std::size_t i, std::size_t size);
167  static std::size_t next(std::size_t i, std::size_t size);
168 
181  void addJoinedHole(
182  std::size_t joinIndex,
183  const CoordinateSequence& holeCoords,
184  std::size_t holeJoinIndex);
185 
196  std::vector<Coordinate> createHoleSection(
197  const CoordinateSequence& holeCoords,
198  std::size_t holeJoinIndex,
199  const Coordinate& joinPt);
200 
207  static std::vector<const LinearRing*> sortHoles(
208  const Polygon* poly);
209 
210  static std::size_t findLowestLeftVertexIndex(
211  const CoordinateSequence& holeCoords);
212 
221  bool intersectsBoundary(
222  const Coordinate& p0,
223  const Coordinate& p1);
224 
225  std::unique_ptr<SegmentSetMutualIntersector> createBoundaryIntersector();
226 
227 
228 public:
229 
230  PolygonHoleJoiner(const Polygon* p_inputPolygon)
231  : inputPolygon(p_inputPolygon)
232  , boundaryIntersector(nullptr)
233  {};
234 
242  static std::unique_ptr<Polygon> joinAsPolygon(
243  const Polygon* p_inputPolygon);
244 
252  static std::unique_ptr<CoordinateSequence> join(
253  const Polygon* p_inputPolygon);
254 
260  std::unique_ptr<CoordinateSequence> compute();
261 
262 };
263 
264 
265 } // namespace geos.triangulate.polygon
266 } // namespace geos.triangulate
267 } // namespace geos
The internal representation of a list of coordinates inside a Geometry.
Definition: CoordinateSequence.h:56
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:216
Models an OGC SFS LinearRing. A LinearRing is a LineString which is both closed and simple.
Definition: LinearRing.h:54
Represents a linear polygon, which may include holes.
Definition: Polygon.h:60
Represents a list of contiguous line segments, and supports noding the segments.
Definition: BasicSegmentString.h:44
An intersector for the red-blue intersection problem.
Definition: SegmentSetMutualIntersector.h:36
Definition: PolygonHoleJoiner.h:69
static std::unique_ptr< Polygon > joinAsPolygon(const Polygon *p_inputPolygon)
std::unique_ptr< CoordinateSequence > compute()
static std::unique_ptr< CoordinateSequence > join(const Polygon *p_inputPolygon)
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25