GEOS 3.15.0dev
CleanCoverage.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (c) 2025 Martin Davis
7 * Copyright (C) 2025 Paul Ramsey <pramsey@cleverelephant.ca>
8 *
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
13 *
14 **********************************************************************/
15
16#pragma once
17
18#include <geos/geom/Envelope.h>
19#include <geos/constants.h>
20#include <geos/index/quadtree/Quadtree.h>
21
22#include <vector>
23#include <memory>
24
25// Forward declarations
26namespace geos {
27namespace geom {
28 class Geometry;
29 class GeometryFactory;
30 class LineString;
31 class LinearRing;
32 class Polygon;
33}
34namespace operation {
35namespace relateng {
36 class RelateNG;
37}
38}
39namespace index {
40namespace quadtree {
41}
42}
43}
44
45
46namespace geos { // geos.
47namespace coverage { // geos.coverage
48
49class CleanCoverage {
50
51 using Envelope = geos::geom::Envelope;
52 using Geometry = geos::geom::Geometry;
53 using GeometryFactory = geos::geom::GeometryFactory;
54 using LineString = geos::geom::LineString;
55 using LinearRing = geos::geom::LinearRing;
56 using Polygon = geos::geom::Polygon;
58 using Quadtree = geos::index::quadtree::Quadtree;
59
60
61public:
62
63 // Classes
64
65 class CleanArea {
66
67 private:
68
69 // Members
70 std::vector<const Polygon*> polys;
71 Envelope env;
72
73 public:
74
75 // Methods
76 void add(const Polygon* poly);
77 const Envelope* getEnvelope();
78 double getBorderLength(const Polygon* adjPoly);
79 double getArea();
80 bool isAdjacent(RelateNG& rel);
81 std::unique_ptr<Geometry> getUnion();
82
83 }; // CleanArea
84
85
86 class MergeStrategy {
87
88 public:
89
90 virtual ~MergeStrategy() = default;
91
92 virtual std::size_t getTarget() const = 0;
93
94 virtual void checkMergeTarget(
95 std::size_t areaIndex,
96 CleanArea* cleanArea,
97 const Polygon* poly) = 0;
98
99 }; // MergeStrategy
100
101
102 class BorderMergeStrategy : public MergeStrategy {
103
104 private:
105
106 std::size_t m_targetIndex = INDEX_UNKNOWN;
107 double m_targetBorderLen;
108
109 public:
110
111 BorderMergeStrategy() {};
112
113 std::size_t getTarget() const override {
114 return m_targetIndex;
115 };
116
117 void checkMergeTarget(std::size_t areaIndex, CleanArea* area, const Polygon* poly) override {
118 double borderLen = area == nullptr ? 0.0 : area->getBorderLength(poly);
119 if (m_targetIndex == INDEX_UNKNOWN || borderLen > m_targetBorderLen) {
120 m_targetIndex = areaIndex;
121 m_targetBorderLen = borderLen;
122 }
123 };
124
125 }; // BorderStrategy
126
127
128 class AreaMergeStrategy : public MergeStrategy {
129
130 private:
131
132 std::size_t m_targetIndex = INDEX_UNKNOWN;
133 double m_targetArea;
134 bool m_isMax;
135
136 public:
137
138 AreaMergeStrategy(bool isMax) : m_isMax(isMax) {};
139
140 std::size_t getTarget() const override {
141 return m_targetIndex;
142 }
143
144 void checkMergeTarget(std::size_t areaIndex, CleanArea* area, const Polygon* poly) override {
145 (void)poly;
146 double areaVal = area == nullptr ? 0.0 : area->getArea();
147 bool isBetter = m_isMax
148 ? areaVal > m_targetArea
149 : areaVal < m_targetArea;
150 if (m_targetIndex == INDEX_UNKNOWN || isBetter) {
151 m_targetIndex = areaIndex;
152 m_targetArea = areaVal;
153 }
154 }
155
156 }; // AreaMergeStrategy
157
158
159 class IndexMergeStrategy : public MergeStrategy {
160
161 private:
162
163 std::size_t m_targetIndex = INDEX_UNKNOWN;
164 bool m_isMax;
165
166 public:
167
168 IndexMergeStrategy(bool isMax) : m_isMax(isMax) {};
169
170 std::size_t getTarget() const override {
171 return m_targetIndex;
172 }
173
174 void checkMergeTarget(std::size_t areaIndex, CleanArea* area, const Polygon* poly) override {
175 (void)area;
176 (void)poly;
177 bool isBetter = m_isMax
178 ? areaIndex > m_targetIndex
179 : areaIndex < m_targetIndex;
180 if (isBetter) {
181 m_targetIndex = areaIndex;
182 }
183 }
184 }; // MergeStrategy
185
186
187private:
188
189 // Members
190
195 std::vector<std::unique_ptr<CleanArea>> cov;
196 //-- used for finding areas to merge gaps
197 std::unique_ptr<Quadtree> covIndex = nullptr;
198
199 void mergeGap(const Polygon* gap);
200
201 CleanArea* findMaxBorderLength(const Polygon* poly, std::vector<CleanArea*>& areas);
202
203 std::vector<CleanArea*> findAdjacentAreas(const Geometry* poly);
204
205 void createIndex();
206
207
208public:
209
210 // Methods
211
212 CleanCoverage(std::size_t size);
213
214 void add(std::size_t i, const Polygon* poly);
215
216 void mergeOverlap(const Polygon* overlap,
217 MergeStrategy& mergeStrategy,
218 std::vector<std::size_t>& parentIndexes);
219
220 static std::size_t findMergeTarget(const Polygon* poly,
221 MergeStrategy& strategy,
222 std::vector<std::size_t>& parentIndexes,
223 std::vector<std::unique_ptr<CleanArea>>& cov);
224
225 void mergeGaps(std::vector<const Polygon*>& gaps);
226
227 std::vector<std::unique_ptr<Geometry>> toCoverage(const GeometryFactory* geomFactory);
228
233 CleanCoverage(const CleanCoverage&) = delete;
234 CleanCoverage& operator=(const CleanCoverage&) = delete;
235
236
237};
238
239} // namespace geos.coverage
240} // namespace geos
241
242
243
244
245
An Envelope defines a rectangulare region of the 2D coordinate plane.
Definition Envelope.h:59
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition GeometryFactory.h:70
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition Geometry.h:196
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
A Quadtree is a spatial index structure for efficient querying of 2D rectangles. If other kinds of sp...
Definition Quadtree.h:70
Definition RelateNG.h:86
Basic namespace for all GEOS functionalities.
Definition geos.h:38