GEOS 3.13.1
RingHull.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2021 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/simplify/LinkedRing.h>
19#include <geos/index/VertexSequencePackedRtree.h>
20
21#include <queue>
22
23namespace geos {
24namespace geom {
25class Envelope;
26class LinearRing;
27class LineString;
28class Polygon;
29}
30namespace simplify {
31class RingHullIndex;
32}
33}
34
35
42
43
44namespace geos {
45namespace simplify { // geos::simplify
46
47
48class RingHull
49{
50
51public:
52
53 /*
54 * Creates a new instance.
55 *
56 * @param p_ring the ring vertices to process
57 * @param p_isOuter whether the hull is outer or inner
58 */
59 RingHull(const LinearRing* p_ring, bool p_isOuter);
60
61 void setMinVertexNum(std::size_t minVertexNum);
62
63 void setMaxAreaDelta(double maxAreaDelta);
64
65 const Envelope* getEnvelope() const;
66
67 std::unique_ptr<LinearRing> getHull(RingHullIndex& hullIndex);
68
69 static bool isConvex(const LinkedRing& vertexRing, std::size_t index);
70
71 static double area(const LinkedRing& vertexRing, std::size_t index);
72
73 void compute(RingHullIndex& hullIndex);
74
75 std::unique_ptr<Polygon> toGeometry() const;
76
77
78private:
79
80
81 class Corner
82 {
83
84 private:
85
86 std::size_t index;
87 std::size_t prev;
88 std::size_t next;
89 double area;
90
91 public:
92
93 Corner(std::size_t p_idx, std::size_t p_prev, std::size_t p_next, double p_area)
94 : index(p_idx)
95 , prev(p_prev)
96 , next(p_next)
97 , area(p_area)
98 {};
99
100 inline int compareTo(const Corner& rhs) const {
101 if (area == rhs.getArea()) {
102 if (index == rhs.getIndex())
103 return 0;
104 else return index < rhs.getIndex() ? -1 : 1;
105 }
106 else return area < rhs.getArea() ? -1 : 1;
107 }
108
109 inline bool operator< (const Corner& rhs) const {
110 return compareTo(rhs) < 0;
111 };
112
113 inline bool operator> (const Corner& rhs) const {
114 return compareTo(rhs) > 0;
115 };
116
117 inline bool operator==(const Corner& rhs) const {
118 return compareTo(rhs) == 0;
119 };
120
121 bool isVertex(std::size_t p_index) const;
122 std::size_t getIndex() const;
123 double getArea() const;
124 void envelope(const LinkedRing& ring, Envelope& env) const;
125 bool intersects(const Coordinate& v, const LinkedRing& ring) const;
126 bool isRemoved(const LinkedRing& ring) const;
127 std::unique_ptr<LineString> toLineString(const LinkedRing& ring);
128
129 struct Greater {
130 inline bool operator()(const Corner & a, const Corner & b) const {
131 return a > b;
132 }
133 };
134
135 using PriorityQueue = std::priority_queue<Corner, std::vector<Corner>, Corner::Greater>;
136
137 }; // class Corner
138
139
140
141 const LinearRing* inputRing;
142 double targetVertexNum = -1.0;
143 double targetAreaDelta = -1.0;
144
150 std::unique_ptr<CoordinateSequence> vertex;
151 std::unique_ptr<LinkedRing> vertexRing;
152 double areaDelta = 0;
153
159 std::unique_ptr<VertexSequencePackedRtree> vertexIndex;
160
161 Corner::PriorityQueue cornerQueue;
162
163
164 void init(CoordinateSequence& ring, bool isOuter);
165 void addCorner(std::size_t i, Corner::PriorityQueue& cornerQueue);
166 bool isAtTarget(const Corner& corner);
167
177 void removeCorner(const Corner& corner, Corner::PriorityQueue& cornerQueue);
178 bool isRemovable(const Corner& corner, const RingHullIndex& hullIndex) const;
179
189 bool hasIntersectingVertex(
190 const Corner& corner,
191 const Envelope& cornerEnv,
192 const RingHull* hull) const;
193
194 const Coordinate& getCoordinate(std::size_t index) const;
195
196 void query(
197 const Envelope& cornerEnv,
198 std::vector<std::size_t>& result) const;
199
200 void queryHull(const Envelope& queryEnv, std::vector<Coordinate>& pts);
201
202
203
204
205}; // RingHull
206
207
208} // geos::simplify
209} // 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:217
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition Envelope.h:59
Definition LineString.h:66
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:61
Definition VertexSequencePackedRtree.h:54
Basic namespace for all GEOS functionalities.
Definition geos.h:39