/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2020 Paul Ramsey * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * **********************************************************************/ #pragma once #include #include #include #include #include #include #include // Forward declarations namespace geos { namespace geom { class Coordinate; class CoordinateSequence; } namespace operation { namespace overlayng { class OverlayEdgeRing; class MaximalEdgeRing; } } } using geos::geom::Coordinate; using geos::geom::CoordinateXYZM; using geos::geom::CoordinateSequence; using geos::geom::Location; namespace geos { // geos. namespace operation { // geos.operation namespace overlayng { // geos.operation.overlayng /** * Creates a single OverlayEdge. */ class GEOS_DLL OverlayEdge : public edgegraph::HalfEdge { private: // Members const CoordinateSequence* pts; /** * 'true' indicates direction is forward along segString * 'false' is reverse direction * The label must be interpreted accordingly. */ bool direction; CoordinateXYZM dirPt; OverlayLabel* label; bool m_isInResultArea; bool m_isInResultLine; bool m_isVisited; OverlayEdge* nextResultEdge; const OverlayEdgeRing* edgeRing; const MaximalEdgeRing* maxEdgeRing; OverlayEdge* nextResultMaxEdge; void markVisited() { m_isVisited = true; }; public: OverlayEdge(const CoordinateXYZM& p_orig, const CoordinateXYZM& p_dirPt, bool p_direction, OverlayLabel* p_label, const CoordinateSequence* p_pts) : HalfEdge(p_orig) , pts(p_pts) , direction(p_direction) , dirPt(p_dirPt) , label(p_label) , m_isInResultArea(false) , m_isInResultLine(false) , m_isVisited(false) , nextResultEdge(nullptr) , edgeRing(nullptr) , maxEdgeRing(nullptr) , nextResultMaxEdge(nullptr) {} ~OverlayEdge() override {}; bool isForward() const { return direction; }; const CoordinateXYZM& directionPt() const override { return dirPt; }; OverlayLabel* getLabel() const { return label; }; Location getLocation(uint8_t index, int position) const { return label->getLocation(index, position, direction); }; const CoordinateXYZM& getCoordinate() const { return orig(); }; const CoordinateSequence* getCoordinatesRO() const { return pts; }; std::unique_ptr getCoordinates() { // return a copy of pts return pts->clone(); }; std::unique_ptr getCoordinatesOriented(); /** * Adds the coordinates of this edge to the given list, * in the direction of the edge. * Duplicate coordinates are removed * (which means that this is safe to use for a path * of connected edges in the topology graph). * * @param coords the coordinate list to add to */ void addCoordinates(CoordinateSequence* coords) const; OverlayEdge* symOE() const { return static_cast(sym()); }; OverlayEdge* oNextOE() const { return static_cast(oNext()); }; bool isInResultArea() const { return m_isInResultArea; }; bool isInResultAreaBoth() const { return m_isInResultArea && symOE()->m_isInResultArea; }; bool isInResultEither() const { return isInResult() || symOE()->isInResult(); }; void unmarkFromResultAreaBoth() { m_isInResultArea = false; symOE()->m_isInResultArea = false; }; void markInResultArea() { m_isInResultArea = true; }; void markInResultAreaBoth() { m_isInResultArea = true; symOE()->m_isInResultArea = true; }; bool isInResultLine() const { return m_isInResultLine; }; void markInResultLine() { m_isInResultLine = true; symOE()->m_isInResultLine = true; }; bool isInResult() const { return m_isInResultArea || m_isInResultLine; }; void setNextResult(OverlayEdge* e) { // Assert: e.orig() == this.dest(); nextResultEdge = e; }; OverlayEdge* nextResult() const { return nextResultEdge; }; bool isResultLinked() const { return nextResultEdge != nullptr; }; void setNextResultMax(OverlayEdge* e) { // Assert: e.orig() == this.dest(); nextResultMaxEdge = e; }; OverlayEdge* nextResultMax() const { return nextResultMaxEdge; }; bool isResultMaxLinked() const { return nextResultMaxEdge != nullptr; }; bool isVisited() const { return m_isVisited; }; void markVisitedBoth() { markVisited(); symOE()->markVisited(); }; void setEdgeRing(const OverlayEdgeRing* p_edgeRing) { edgeRing = p_edgeRing; }; const OverlayEdgeRing* getEdgeRing() const { return edgeRing; }; const MaximalEdgeRing* getEdgeRingMax() const { return maxEdgeRing; }; void setEdgeRingMax(const MaximalEdgeRing* p_maximalEdgeRing) { maxEdgeRing = p_maximalEdgeRing; }; friend std::ostream& operator<<(std::ostream& os, const OverlayEdge& oe); std::string resultSymbol() const; }; } // namespace geos.operation.overlayng } // namespace geos.operation } // namespace geos