1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2020 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/edgegraph/HalfEdge.h>
18 #include <geos/geom/Location.h>
19 
20 #include <geos/export.h>
21 
22 #include <memory>
23 
24 // Forward declarations
25 namespace geos {
26 namespace geom {
27 class Coordinate;
28 class CoordinateSequence;
29 class CoordinateArraySequence;
30 }
31 namespace operation {
32 namespace overlayng {
33 class OverlayEdgeRing;
34 class MaximalEdgeRing;
35 class OverlayLabel;
36 }
37 }
38 }
39 
40 namespace geos {      // geos.
41 namespace operation { // geos.operation
42 namespace overlayng { // geos.operation.overlayng
43 
44 using namespace geos::geom;
45 
46 /**
47 * Creates a single OverlayEdge.
48 */
49 class GEOS_DLL OverlayEdge : public edgegraph::HalfEdge {
50 
51 private:
52 
53     // Members
54     const CoordinateSequence* pts;
55     /**
56     * 'true' indicates direction is forward along segString
57     * 'false' is reverse direction
58     * The label must be interpreted accordingly.
59     */
60     bool direction;
61     Coordinate dirPt;
62     OverlayLabel* label;
63     bool m_isInResultArea;
64     bool m_isInResultLine;
65     bool m_isVisited;
66     OverlayEdge* nextResultEdge;
67     const OverlayEdgeRing* edgeRing;
68     const MaximalEdgeRing* maxEdgeRing;
69     OverlayEdge* nextResultMaxEdge;
70 
71     void markVisited();
72 
73 
74 public:
75 
76     // takes ownershiph of CoordinateSequence
OverlayEdge(const Coordinate & p_orig,const Coordinate & p_dirPt,bool p_direction,OverlayLabel * p_label,const CoordinateSequence * p_pts)77     OverlayEdge(const Coordinate& p_orig, const Coordinate& p_dirPt,
78                 bool p_direction, OverlayLabel* p_label,
79                 const CoordinateSequence* p_pts)
80         : HalfEdge(p_orig)
81         , pts(p_pts)
82         , direction(p_direction)
83         , dirPt(p_dirPt)
84         , label(p_label)
85         , m_isInResultArea(false)
86         , m_isInResultLine(false)
87         , m_isVisited(false)
88         , nextResultEdge(nullptr)
89         , edgeRing(nullptr)
90         , maxEdgeRing(nullptr)
91         , nextResultMaxEdge(nullptr)
92      {}
93 
94     bool isForward() const;
95 
96     const Coordinate& directionPt() const override;
~OverlayEdge()97     ~OverlayEdge() override {};
98 
99     OverlayLabel* getLabel() const;
100 
101     Location getLocation(int index, int position) const;
102 
103     const Coordinate& getCoordinate() const;
104 
105     const CoordinateSequence* getCoordinatesRO() const;
106 
107     std::unique_ptr<CoordinateSequence> getCoordinates();
108 
109     std::unique_ptr<CoordinateSequence> getCoordinatesOriented();
110 
111     /**
112     * Adds the coordinates of this edge to the given list,
113     * in the direction of the edge.
114     * Duplicate coordinates are removed
115     * (which means that this is safe to use for a path
116     * of connected edges in the topology graph).
117     *
118     * @param coords the coordinate list to add to
119     */
120     void addCoordinates(CoordinateArraySequence* coords);
121 
122     OverlayEdge* symOE() const;
123     OverlayEdge* oNextOE() const;
124 
125     bool isInResultArea() const;
126 
127     bool isInResultAreaBoth() const;
128 
129     void unmarkFromResultAreaBoth();
130 
131     void markInResultArea();
132 
133     void markInResultAreaBoth();
134 
135     bool isInResultLine() const;
136 
137     void markInResultLine();
138 
139     bool isInResult() const;
140 
141     bool isInResultEither() const;
142 
143     void setNextResult(OverlayEdge* e);
144 
145     OverlayEdge* nextResult() const;
146 
147     bool isResultLinked() const;
148 
149     void setNextResultMax(OverlayEdge* e);
150 
151     OverlayEdge* nextResultMax() const;
152 
153     bool isResultMaxLinked() const;
154 
155     bool isVisited() const;
156     void markVisitedBoth();
157 
158     const OverlayEdgeRing* getEdgeRing() const;
159     void setEdgeRing(const OverlayEdgeRing* p_edgeRing);
160 
161     const MaximalEdgeRing* getEdgeRingMax() const;
162     void setEdgeRingMax(const MaximalEdgeRing* maximalEdgeRing);
163 
164     friend std::ostream& operator<<(std::ostream& os, const OverlayEdge& oe);
165     std::string resultSymbol() const;
166 
167 };
168 
169 
170 } // namespace geos.operation.overlayng
171 } // namespace geos.operation
172 } // namespace geos
173 
174