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
24namespace geos {
25namespace geom {
26class CoordinateSequence;
27class Coordinate;
28}
29namespace noding {
30class NodedSegmentString;
31}
32}
33
34namespace geos { // geos
35namespace noding { // geos::noding
36
55class GEOS_DLL BoundaryChainNoder : public Noder {
57
58private:
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
133public:
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
143private:
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 geos.h:39