GEOS 3.13.1
CoveragePolygonValidator.h
1/**********************************************************************
2 *
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
5 *
6 * Copyright (C) 2022 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/noding/BasicSegmentString.h>
18#include <geos/geom/LineSegment.h>
19#include <geos/algorithm/locate/IndexedPointInAreaLocator.h>
20#include <geos/coverage/CoveragePolygon.h>
21#include <geos/coverage/CoverageRing.h>
22
23#include <unordered_map>
24#include <map>
25
26// Forward declarations
27namespace geos {
28namespace geom {
29class Coordinate;
30class Envelope;
31class Geometry;
32class GeometryFactory;
33}
34}
35
42
43namespace geos { // geos
44namespace coverage { // geos::coverage
45
46
99
100private:
101
111 class CoverageRingSegment : public LineSegment
112 {
113 public:
114
115 // Members
116 CoverageRing* ringForward;
117 std::size_t indexForward;
118 CoverageRing* ringOpp;
119 std::size_t indexOpp;
120
121 CoverageRingSegment(
122 const Coordinate& p_p0, const Coordinate& p_p1,
123 CoverageRing* p_ring, std::size_t p_index)
124 : LineSegment(p_p0, p_p1)
125 , ringForward(nullptr)
126 , indexForward(0)
127 , ringOpp(nullptr)
128 , indexOpp(0)
129 {
130 if (p_p1.compareTo(p_p0) < 0) {
131 reverse();
132 ringOpp = p_ring;
133 indexOpp = p_index;
134 }
135 else {
136 ringForward = p_ring;
137 indexForward = p_index;
138 }
139 };
140
141 void match(const CoverageRingSegment* seg) {
142 bool isInvalid = checkInvalid(seg);
143 if (isInvalid) {
144 return;
145 }
146 //-- record the match
147 if (ringForward == nullptr) {
148 ringForward = seg->ringForward;
149 indexForward = seg->indexForward;
150 }
151 else {
152 ringOpp = seg->ringOpp;
153 indexOpp = seg->indexOpp;
154 }
155 //-- mark ring segments as matched
156 ringForward->markMatched(indexForward);
157 ringOpp->markMatched(indexOpp);
158 }
159
160 bool checkInvalid(const CoverageRingSegment* seg) const {
161 if (ringForward != nullptr && seg->ringForward != nullptr) {
162 ringForward->markInvalid(indexForward);
163 seg->ringForward->markInvalid(seg->indexForward);
164 return true;
165 }
166 if (ringOpp != nullptr && seg->ringOpp != nullptr) {
167 ringOpp->markInvalid(indexOpp);
168 seg->ringOpp->markInvalid(seg->indexOpp);
169 return true;
170 }
171 return false;
172 }
173
174 struct CoverageRingSegHash {
175 std::size_t
176 operator() (CoverageRingSegment const* s) const {
177 std::size_t h = std::hash<double>{}(s->p0.x);
178 h ^= (std::hash<double>{}(s->p0.y) << 1);
179 h ^= (std::hash<double>{}(s->p1.x) << 1);
180 return h ^ (std::hash<double>{}(s->p1.y) << 1);
181 }
182 };
183
184 struct CoverageRingSegEq {
185 bool
186 operator() (CoverageRingSegment const* lhs, CoverageRingSegment const* rhs) const {
187 return lhs->p0.x == rhs->p0.x
188 && lhs->p0.y == rhs->p0.y
189 && lhs->p1.x == rhs->p1.x
190 && lhs->p1.y == rhs->p1.y;
191 }
192 };
193
194 };
195
196 // Members
197 const Geometry* targetGeom;
198 std::vector<const Geometry*> adjGeoms;
199 //std::vector<const Polygon*> m_adjPolygons;
200 const GeometryFactory* geomFactory;
201 double gapWidth = 0.0;
202 std::vector<std::unique_ptr<CoveragePolygon>> m_adjCovPolygons;
203 std::deque<CoverageRing> coverageRingStore;
204 std::vector<std::unique_ptr<CoordinateSequence>> localCoordinateSequences;
205 std::deque<CoverageRingSegment> coverageRingSegmentStore;
206
207 typedef std::unordered_map<CoverageRingSegment*, CoverageRingSegment*, CoverageRingSegment::CoverageRingSegHash, CoverageRingSegment::CoverageRingSegEq> CoverageRingSegmentMap;
208
209 // Declare type as noncopyable
211 CoveragePolygonValidator& operator=(const CoveragePolygonValidator& rhs) = delete;
212
213public:
214
223 static std::unique_ptr<Geometry> validate(
224 const Geometry* targetPolygon,
225 std::vector<const Geometry*>& adjPolygons);
226
240 static std::unique_ptr<Geometry> validate(
241 const Geometry* targetPolygon,
242 std::vector<const Geometry*>& adjPolygons,
243 double gapWidth);
244
256 const Geometry* targetPolygon,
257 std::vector<const Geometry*>& adjPolygons);
258
264 void setGapWidth(double p_gapWidth);
265
272 std::unique_ptr<Geometry> validate();
273
274private:
275
276 static std::vector<std::unique_ptr<CoveragePolygon>>
277 toCoveragePolygons(const std::vector<const Polygon*> polygons);
278 static std::vector<const Polygon*> extractPolygons(std::vector<const Geometry*>& geoms);
279
280 /* private */
281 std::unique_ptr<Geometry> createEmptyResult();
282
300 void markMatchedSegments(
301 std::vector<CoverageRing*>& targetRings,
302 std::vector<CoverageRing*>& adjRings,
303 const Envelope& targetEnv);
304
314 void markMatchedSegments(
315 std::vector<CoverageRing*>& rings,
316 const Envelope& envLimit,
317 CoverageRingSegmentMap& segmentMap);
318
319 CoverageRingSegment* createCoverageRingSegment(
320 CoverageRing* ring, std::size_t index);
321
331 void markInvalidInteractingSegments(
332 std::vector<CoverageRing*>& targetRings,
333 std::vector<CoverageRing*>& adjRings,
334 double distanceTolerance);
335
343 void markInvalidInteriorSegments(
344 std::vector<CoverageRing*>& targetRings,
345 std::vector<std::unique_ptr<CoveragePolygon>>& adjCovPolygons);
346
347 void markInvalidInteriorSection(
348 CoverageRing& ring,
349 std::size_t iStart,
350 std::size_t iEnd,
351 std::vector<std::unique_ptr<CoveragePolygon>>& adjCovPolygons );
352
353 void markInvalidInteriorSegment(
354 CoverageRing& ring, std::size_t i, CoveragePolygon* adjPoly);
355
356 void checkTargetRings(
357 std::vector<CoverageRing*>& targetRings,
358 std::vector<CoverageRing*>& adjRngs,
359 const Envelope& targetEnv);
360
361 std::unique_ptr<Geometry> createInvalidLines(std::vector<CoverageRing*>& rings);
362
363 std::vector<CoverageRing*> createRings(const Geometry* geom);
364
365 std::vector<CoverageRing*> createRings(std::vector<const Polygon*>& polygons);
366
367 void createRings(const Polygon* poly, std::vector<CoverageRing*>& rings);
368
369 void addRing(
370 const LinearRing* ring,
371 bool isShell,
372 std::vector<CoverageRing*>& rings);
373
374 CoverageRing* createRing(const LinearRing* ring, bool isShell);
375
376
377
378};
379
380} // namespace geos::coverage
381} // namespace geos
Determines the location of Coordinates relative to an areal geometry, using indexing for efficiency.
Definition IndexedPointInAreaLocator.h:54
Definition CoveragePolygonValidator.h:98
std::unique_ptr< Geometry > validate()
static std::unique_ptr< Geometry > validate(const Geometry *targetPolygon, std::vector< const Geometry * > &adjPolygons)
CoveragePolygonValidator(const Geometry *targetPolygon, std::vector< const Geometry * > &adjPolygons)
static std::unique_ptr< Geometry > validate(const Geometry *targetPolygon, std::vector< const Geometry * > &adjPolygons, double gapWidth)
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
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:197
Definition LineSegment.h:61
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
Basic namespace for all GEOS functionalities.
Definition geos.h:39