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
27 namespace geos {
28 namespace geom {
29 class Coordinate;
30 class Envelope;
31 class Geometry;
32 class GeometryFactory;
33 }
34 }
35 
42 
43 namespace geos { // geos
44 namespace coverage { // geos::coverage
45 
46 
98 class GEOS_DLL CoveragePolygonValidator {
99 
100 private:
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
210  CoveragePolygonValidator(const CoveragePolygonValidator& other) = delete;
211  CoveragePolygonValidator& operator=(const CoveragePolygonValidator& rhs) = delete;
212 
213 public:
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 
274 private:
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, double gapWidth)
static std::unique_ptr< Geometry > validate(const Geometry *targetPolygon, std::vector< const Geometry * > &adjPolygons)
CoveragePolygonValidator(const Geometry *targetPolygon, std::vector< const Geometry * > &adjPolygons)
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: Angle.h:25