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