GEOS  3.14.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 
34 namespace geos { // geos
35 namespace noding { // geos::noding
36 
55 class GEOS_DLL BoundaryChainNoder : public Noder {
57 
58 private:
59 
60  class BoundarySegmentMap {
61 
62  private:
63 
64  // Members
65  SegmentString* segString;
66  std::vector<bool> isBoundary;
67 
68  static SegmentString* createChain(
69  const SegmentString* segString,
70  std::size_t startIndex,
71  std::size_t endIndex,
72  bool constructZ,
73  bool constructM);
74 
75  std::size_t findChainStart(std::size_t index) const;
76  std::size_t findChainEnd(std::size_t index) const;
77 
78  public:
79 
80  BoundarySegmentMap(SegmentString* ss)
81  : segString(ss) {
82  isBoundary.resize(ss->size()-1, false);
83  };
84 
85  void setBoundarySegment(std::size_t index);
86  void createChains(std::vector<SegmentString*>& chainList, bool constructZ, bool constructM);
87  };
88 
89  class Segment {
90  public:
91  Segment(const geom::CoordinateSequence& seq,
92  BoundarySegmentMap& segMap,
93  std::size_t index)
94  : m_seq(seq)
95  , m_segMap(segMap)
96  , m_index(index)
97  , m_flip(seq.getAt<geom::CoordinateXY>(index).compareTo(seq.getAt<geom::CoordinateXY>(index + 1)) < 0)
98  {}
99 
100  const geom::CoordinateXY& p0() const {
101  return m_seq.getAt<geom::CoordinateXY>(m_flip ? m_index : m_index + 1);
102  }
103 
104  const geom::CoordinateXY& p1() const {
105  return m_seq.getAt<geom::CoordinateXY>(m_flip ? m_index + 1 : m_index);
106  }
107 
108  void markInBoundary() const {
109  m_segMap.setBoundarySegment(m_index);
110  };
111 
112  bool operator==(const Segment& other) const {
113  return p0().equals2D(other.p0()) && p1().equals2D(other.p1());
114  }
115 
116  struct HashCode {
117  std::size_t operator()(const Segment& s) const {
118  std::size_t h = std::hash<double>{}(s.p0().x);
119  h ^= (std::hash<double>{}(s.p0().y) << 1);
120  h ^= (std::hash<double>{}(s.p1().x) << 1);
121  h ^= (std::hash<double>{}(s.p1().y) << 1);
122  return h;
123  }
124  };
125 
126  private:
127  const geom::CoordinateSequence& m_seq;
128  BoundarySegmentMap& m_segMap;
129  std::size_t m_index;
130  bool m_flip;
131  };
132 
133 public:
134  using SegmentSet = std::unordered_set<Segment, Segment::HashCode>;
135 
136  BoundaryChainNoder() : chainList(nullptr), m_constructZ(false), m_constructM(false) {};
137 
138  // Noder virtual methods
139  std::vector<SegmentString*>* getNodedSubstrings() const override;
140  void computeNodes(std::vector<SegmentString*>* inputSegStrings) override;
141 
142 
143 private:
144 
145  // Members
146  std::vector<SegmentString*>* chainList;
147  bool m_constructZ;
148  bool m_constructM;
149 
150  // Methods
151  void addSegments(std::vector<SegmentString*>* segStrings,
152  SegmentSet& segSet,
153  std::vector<BoundarySegmentMap>& includedSegs);
154 
155  static void addSegments(SegmentString* segString,
156  BoundarySegmentMap& segInclude,
157  SegmentSet& segSet);
158 
159  static void markBoundarySegments(SegmentSet& segSet);
160 
161  std::vector<SegmentString*>* extractChains(std::vector<BoundarySegmentMap>& sections) const;
162 
163  static bool segSetContains(SegmentSet& segSet, Segment& seg);
164 
165 };
166 
167 } // namespace geos::noding
168 } // namespace geos
169 
170 
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
Definition: BoundaryChainNoder.h:55
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