GEOS  3.13.0dev
BoundaryChainNoder.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (c) Martin Davis 2022
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/Noder.h> // for composition
18 #include <geos/noding/SegmentString.h> // for composition
19 #include <geos/geom/LineSegment.h> // for composition
20 
21 #include <unordered_set>
22 
23 // Forward declarations
24 namespace geos {
25 namespace geom {
26 class CoordinateSequence;
27 class Coordinate;
28 }
29 namespace noding {
30 class NodedSegmentString;
31 }
32 }
33 
35 
36 namespace geos { // geos
37 namespace noding { // geos::noding
38 
57 class GEOS_DLL BoundaryChainNoder : public Noder {
58 
59 private:
60 
61  class BoundarySegmentMap {
62 
63  private:
64 
65  // Members
66  SegmentString* segString;
67  std::vector<bool> isBoundary;
68 
69  static SegmentString* createChain(
70  const SegmentString* segString,
71  std::size_t startIndex,
72  std::size_t endIndex,
73  bool constructZ,
74  bool constructM);
75 
76  std::size_t findChainStart(std::size_t index) const;
77  std::size_t findChainEnd(std::size_t index) const;
78 
79  public:
80 
81  BoundarySegmentMap(SegmentString* ss)
82  : segString(ss) {
83  isBoundary.resize(ss->size()-1, false);
84  };
85 
86  void setBoundarySegment(std::size_t index);
87  void createChains(std::vector<SegmentString*>& chainList, bool constructZ, bool constructM);
88  };
89 
90  class Segment {
91  public:
92  Segment(const geom::CoordinateSequence& seq,
93  BoundarySegmentMap& segMap,
94  std::size_t index)
95  : m_seq(seq)
96  , m_segMap(segMap)
97  , m_index(index)
98  , m_flip(seq.getAt<geom::CoordinateXY>(index).compareTo(seq.getAt<geom::CoordinateXY>(index + 1)) < 0)
99  {}
100 
101  const geom::CoordinateXY& p0() const {
102  return m_seq.getAt<geom::CoordinateXY>(m_flip ? m_index : m_index + 1);
103  }
104 
105  const geom::CoordinateXY& p1() const {
106  return m_seq.getAt<geom::CoordinateXY>(m_flip ? m_index + 1 : m_index);
107  }
108 
109  void markInBoundary() const {
110  m_segMap.setBoundarySegment(m_index);
111  };
112 
113  bool operator==(const Segment& other) const {
114  return p0().equals2D(other.p0()) && p1().equals2D(other.p1());
115  }
116 
117  struct HashCode {
118  std::size_t operator()(const Segment& s) const {
119  std::size_t h = std::hash<double>{}(s.p0().x);
120  h ^= (std::hash<double>{}(s.p0().y) << 1);
121  h ^= (std::hash<double>{}(s.p1().x) << 1);
122  h ^= (std::hash<double>{}(s.p1().y) << 1);
123  return h;
124  }
125  };
126 
127  private:
128  const geom::CoordinateSequence& m_seq;
129  BoundarySegmentMap& m_segMap;
130  std::size_t m_index;
131  bool m_flip;
132  };
133 
134 public:
135  using SegmentSet = std::unordered_set<Segment, Segment::HashCode>;
136 
137  BoundaryChainNoder() : chainList(nullptr), m_constructZ(false), m_constructM(false) {};
138 
139  // Noder virtual methods
140  std::vector<SegmentString*>* getNodedSubstrings() const override;
141  void computeNodes(std::vector<SegmentString*>* inputSegStrings) override;
142 
143 
144 private:
145 
146  // Members
147  std::vector<SegmentString*>* chainList;
148  bool m_constructZ;
149  bool m_constructM;
150 
151  // Methods
152  void addSegments(std::vector<SegmentString*>* segStrings,
153  SegmentSet& segSet,
154  std::vector<BoundarySegmentMap>& includedSegs);
155 
156  static void addSegments(SegmentString* segString,
157  BoundarySegmentMap& segInclude,
158  SegmentSet& segSet);
159 
160  static void markBoundarySegments(SegmentSet& segSet);
161 
162  std::vector<SegmentString*>* extractChains(std::vector<BoundarySegmentMap>& sections) const;
163 
164  static bool segSetContains(SegmentSet& segSet, Segment& seg);
165 
166 };
167 
168 } // namespace geos::noding
169 } // namespace geos
170 
171 
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:216
Definition: BoundaryChainNoder.h:57
std::vector< SegmentString * > * getNodedSubstrings() const override
Returns a collection of fully noded SegmentStrings. The SegmentStrings have the same context as their...
void computeNodes(std::vector< SegmentString * > *inputSegStrings) override
Computes the noding for a collection of SegmentStrings.
Computes all intersections between segments in a set of SegmentString.
Definition: Noder.h:46
An interface for classes which represent a sequence of contiguous line segments.
Definition: SegmentString.h:47
const T & getAt(std::size_t i) const
Returns a read-only reference to Coordinate at position i.
Definition: CoordinateSequence.h:249
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25