/src/geos/include/geos/operation/relateng/RelateNode.h
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (c) 2024 Martin Davis |
7 | | * Copyright (C) 2024 Paul Ramsey <pramsey@cleverelephant.ca> |
8 | | * |
9 | | * This is free software; you can redistribute and/or modify it under |
10 | | * the terms of the GNU Lesser General Public Licence as published |
11 | | * by the Free Software Foundation. |
12 | | * See the COPYING file for more information. |
13 | | * |
14 | | **********************************************************************/ |
15 | | |
16 | | #pragma once |
17 | | |
18 | | #include <geos/operation/relateng/RelateEdge.h> |
19 | | |
20 | | #include <vector> |
21 | | #include <memory> |
22 | | #include <cassert> |
23 | | |
24 | | #include <geos/export.h> |
25 | | |
26 | | |
27 | | // Forward declarations |
28 | | namespace geos { |
29 | | namespace operation { |
30 | | namespace relateng { |
31 | | class NodeSection; |
32 | | } |
33 | | } |
34 | | namespace geom { |
35 | | class CoordinateXY; |
36 | | class Geometry; |
37 | | } |
38 | | } |
39 | | |
40 | | namespace geos { // geos. |
41 | | namespace operation { // geos.operation |
42 | | namespace relateng { // geos.operation.relateng |
43 | | |
44 | | |
45 | | class GEOS_DLL RelateNode { |
46 | | using CoordinateXY = geos::geom::CoordinateXY; |
47 | | using Geometry = geos::geom::Geometry; |
48 | | |
49 | | private: |
50 | | |
51 | | // Members |
52 | | |
53 | | /** |
54 | | * A list of the edges around the node in CCW order, |
55 | | * ordered by their CCW angle with the positive X-axis. |
56 | | */ |
57 | | std::vector<std::unique_ptr<RelateEdge>> edges; |
58 | | |
59 | | const CoordinateXY* nodePt; |
60 | | |
61 | | |
62 | | // Methods |
63 | | |
64 | | void updateEdgesInArea(bool isA, std::size_t indexFrom, std::size_t indexTo); |
65 | | |
66 | | void updateIfAreaPrev(bool isA, std::size_t index); |
67 | | |
68 | | void updateIfAreaNext(bool isA, std::size_t index); |
69 | | |
70 | | const RelateEdge* addLineEdge(bool isA, const CoordinateXY* dirPt); |
71 | | |
72 | | const RelateEdge* addAreaEdge(bool isA, const CoordinateXY* dirPt, bool isForward); |
73 | | |
74 | | /** |
75 | | * Adds or merges an edge to the node. |
76 | | * |
77 | | * @param isA |
78 | | * @param dirPt |
79 | | * @param dim dimension of the geometry element containing the edge |
80 | | * @param isForward the direction of the edge |
81 | | * |
82 | | * @return the created or merged edge for this point |
83 | | */ |
84 | | const RelateEdge* addEdge(bool isA, const CoordinateXY* dirPt, int dim, bool isForward); |
85 | | |
86 | | void finishNode(bool isA, bool isAreaInterior); |
87 | | |
88 | | void propagateSideLocations(bool isA, std::size_t startIndex); |
89 | | |
90 | | static std::size_t prevIndex(std::vector<std::unique_ptr<RelateEdge>>& list, std::size_t index); |
91 | | |
92 | | static std::size_t nextIndex(std::vector<std::unique_ptr<RelateEdge>>& list, std::size_t i); |
93 | | |
94 | | std::size_t indexOf( |
95 | | const std::vector<std::unique_ptr<RelateEdge>>& edges, |
96 | | const RelateEdge* edge) const; |
97 | | |
98 | | |
99 | | public: |
100 | | |
101 | | RelateNode(const CoordinateXY* pt) |
102 | 0 | : nodePt(pt) |
103 | 0 | {}; |
104 | | |
105 | | const CoordinateXY* getCoordinate() const; |
106 | | |
107 | | const std::vector<std::unique_ptr<RelateEdge>>& getEdges() const; |
108 | | |
109 | | void addEdges(std::vector<const NodeSection *>& nss); |
110 | | void addEdges(std::vector<std::unique_ptr<NodeSection>>& nss); |
111 | | |
112 | | void addEdges(const NodeSection* ns); |
113 | | |
114 | | /** |
115 | | * Computes the final topology for the edges around this node. |
116 | | * Although nodes lie on the boundary of areas or the interior of lines, |
117 | | * in a mixed GC they may also lie in the interior of an area. |
118 | | * This changes the locations of the sides and line to Interior. |
119 | | * |
120 | | * @param isAreaInteriorA true if the node is in the interior of A |
121 | | * @param isAreaInteriorB true if the node is in the interior of B |
122 | | */ |
123 | | void finish(bool isAreaInteriorA, bool isAreaInteriorB); |
124 | | |
125 | | std::string toString() const; |
126 | | |
127 | | bool hasExteriorEdge(bool isA); |
128 | | |
129 | | friend std::ostream& operator<<(std::ostream& os, const RelateNode& ns); |
130 | | |
131 | | /** |
132 | | * Disable copy construction and assignment. Apparently needed to make this |
133 | | * class compile under MSVC. (See https://stackoverflow.com/q/29565299) |
134 | | */ |
135 | | RelateNode(const RelateNode&) = delete; |
136 | | RelateNode& operator=(const RelateNode&) = delete; |
137 | | |
138 | | }; |
139 | | |
140 | | } // namespace geos.operation.relateng |
141 | | } // namespace geos.operation |
142 | | } // namespace geos |
143 | | |