LCOV - code coverage report
Current view: top level - src/netbuild - NBNode.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 37 37 100.0 %
Date: 2024-05-07 15:28:01 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
       4             : // This program and the accompanying materials are made available under the
       5             : // terms of the Eclipse Public License 2.0 which is available at
       6             : // https://www.eclipse.org/legal/epl-2.0/
       7             : // This Source Code may also be made available under the following Secondary
       8             : // Licenses when the conditions for such availability set forth in the Eclipse
       9             : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10             : // or later which is available at
      11             : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12             : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13             : /****************************************************************************/
      14             : /// @file    NBNode.h
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Yun-Pang Floetteroed
      18             : /// @author  Michael Behrisch
      19             : /// @date    Tue, 20 Nov 2001
      20             : ///
      21             : // The representation of a single node
      22             : /****************************************************************************/
      23             : #pragma once
      24             : #include <config.h>
      25             : 
      26             : #include <vector>
      27             : #include <deque>
      28             : #include <utility>
      29             : #include <string>
      30             : #include <set>
      31             : #include <memory>
      32             : #include <utils/common/StdDefs.h>
      33             : #include <utils/common/Named.h>
      34             : #include <utils/geom/Bresenham.h>
      35             : #include <utils/geom/GeomHelper.h>
      36             : #include <utils/common/VectorHelper.h>
      37             : #include <utils/geom/Position.h>
      38             : #include <utils/geom/PositionVector.h>
      39             : #include <utils/xml/SUMOXMLDefinitions.h>
      40             : #include "NBEdge.h"
      41             : #include "NBConnection.h"
      42             : #include "NBConnectionDefs.h"
      43             : #include "NBContHelper.h"
      44             : 
      45             : 
      46             : // ===========================================================================
      47             : // class declarations
      48             : // ===========================================================================
      49             : class NBRequest;
      50             : class NBDistrict;
      51             : class OptionsCont;
      52             : class NBTrafficLightDefinition;
      53             : class NBTypeCont;
      54             : class NBTrafficLightLogicCont;
      55             : class NBDistrictCont;
      56             : class OutputDevice;
      57             : 
      58             : 
      59             : // ===========================================================================
      60             : // class definitions
      61             : // ===========================================================================
      62             : /**
      63             :  * @class NBNode
      64             :  * @brief Represents a single node (junction) during network building
      65             :  */
      66             : class NBNode : public Named, public Parameterised {
      67             :     friend class NBNodeCont;
      68             :     friend class GNEJunction;            // < used for visualization (netedit)
      69             :     friend class NBNodesEdgesSorter;     // < sorts the edges
      70             :     friend class NBNodeTypeComputer;     // < computes type
      71             :     friend class NBEdgePriorityComputer; // < computes priorities of edges per intersection
      72             : 
      73             : public:
      74             :     /**
      75             :      * @class ApproachingDivider
      76             :      * @brief Computes lane-2-lane connections
      77             :      *
      78             :      * Being a bresenham-callback, this class computes which lanes
      79             :      *  are approached by the current lane (first callback parameter).
      80             :      * The second callback parameter is the destination lane that is the
      81             :      *  middle of the computed lanes.
      82             :      * The lanes are spreaded from this middle position both to left and right
      83             :      *  but may also be transposed in full when there is not enough space.
      84             :      */
      85             :     class ApproachingDivider : public Bresenham::BresenhamCallBack {
      86             :     public:
      87             :         /**@brief Constructor
      88             :          * @param[in] approaching The list of the edges that approach the outgoing edge
      89             :          * @param[in] currentOutgoing The outgoing edge
      90             :          */
      91             :         ApproachingDivider(const EdgeVector& approaching, NBEdge* currentOutgoing);
      92             : 
      93             :         /// @brief Destructor
      94             :         ~ApproachingDivider();
      95             : 
      96             :         /// @ get number of available lanes
      97             :         int numAvailableLanes() const {
      98       87291 :             return (int)myAvailableLanes.size();
      99             :         }
     100             : 
     101             :         /// @brief the bresenham-callback
     102             :         void execute(const int src, const int dest);
     103             : 
     104             :         /// @brief the method that spreads the wished number of lanes from the lane given by the bresenham-call to both left and right
     105             :         std::deque<int>* spread(int numLanes, int dest) const;
     106             : 
     107             :     private:
     108             :         /// @brief The list of edges that approach the current edge
     109             :         const EdgeVector& myApproaching;
     110             : 
     111             :         /// @brief The approached current edge
     112             :         NBEdge* myCurrentOutgoing;
     113             : 
     114             :         /// @brief The available lanes to which connections shall be built
     115             :         std::vector<int> myAvailableLanes;
     116             : 
     117             :         /// directions from each incoming edge to the outgoing edge
     118             :         std::vector<LinkDirection> myDirections;
     119             : 
     120             :         /// @brief number of straight connections to the outgoing edge
     121             :         int myNumStraight;
     122             : 
     123             :         /// @brief whether the outgoing edge is exclusively used by bikes
     124             :         bool myIsBikeEdge;
     125             : 
     126             :     private:
     127             :         /// @brief Invalidated assignment operator.
     128             :         ApproachingDivider& operator=(const ApproachingDivider&) = delete;
     129             : 
     130             :     };
     131             : 
     132             :     /** @class Crossing
     133             :      * @brief A definition of a pedestrian crossing
     134             :      */
     135        3122 :     class Crossing final : public Parameterised {
     136             :     public:
     137             :         /// @brief constructor
     138             :         Crossing(const NBNode* _node, const EdgeVector& _edges, double _width, bool _priority, int _customTLIndex, int _customTLIndex2, const PositionVector& _customShape);
     139             :         /// @brief The parent node of this crossing
     140             :         const NBNode* node;
     141             :         /// @brief The edges being crossed
     142             :         EdgeVector edges;
     143             :         /// @brief The crossing's shape
     144             :         PositionVector shape;
     145             :         /// @brief The outline shape for this crossing
     146             :         PositionVector outlineShape;
     147             :         /// @brief This crossing's width
     148             :         double customWidth;
     149             :         /// @brief This crossing's width
     150             :         double width;
     151             :         /// @brief the (edge)-id of this crossing
     152             :         std::string id;
     153             :         /// @brief the lane-id of the previous walkingArea
     154             :         std::string prevWalkingArea;
     155             :         /// @brief the lane-id of the next walkingArea
     156             :         std::string nextWalkingArea;
     157             :         /// @brief whether the pedestrians have priority
     158             :         bool priority;
     159             :         /// @brief optional customShape for this crossing
     160             :         PositionVector customShape;
     161             :         /// @brief the traffic light index of this crossing (if controlled)
     162             :         int tlLinkIndex;
     163             :         int tlLinkIndex2;
     164             :         /// @brief the custom traffic light index of this crossing (if controlled)
     165             :         int customTLIndex;
     166             :         int customTLIndex2;
     167             :         /// @brief The id of the traffic light that controls this connection
     168             :         std::string tlID;
     169             :         /// @brief whether this crossing is valid (and can be written to the net.xml). This is needed for netedit because validity can only be checked during junction computation
     170             :         bool valid;
     171             :     };
     172             : 
     173             : 
     174             :     /** @struct WalkingArea
     175             :      * @brief A definition of a pedestrian walking area
     176             :      */
     177             :     struct WalkingArea {
     178             :         /// @brief constructor
     179        8098 :         WalkingArea(const std::string& _id, double _width) :
     180        8098 :             id(_id),
     181        8098 :             width(_width) {
     182        8098 :         }
     183             :         /// @brief the (edge)-id of this walkingArea
     184             :         std::string id;
     185             :         /// @brief This lane's width
     186             :         double width;
     187             :         /// @brief This lane's width
     188             :         double length = INVALID_DOUBLE;
     189             :         /// @brief The polygonal shape
     190             :         PositionVector shape;
     191             :         /// @brief the lane-id of the next crossing(s)
     192             :         std::vector<std::string> nextCrossings;
     193             :         /// @brief the lane-id of the previous crossing(s)
     194             :         std::vector<std::string> prevCrossings;
     195             :         /// @brief the lane-id of the next sidewalk lane or ""
     196             :         std::vector<std::string> nextSidewalks;
     197             :         /// @brief the lane-id of the previous sidewalk lane or ""
     198             :         std::vector<std::string> prevSidewalks;
     199             :         /// @brief whether this walkingArea has a custom shape
     200             :         bool hasCustomShape = false;
     201             :         /// @brief minimum number of edges crossed by nextCrossings
     202             :         int minNextCrossingEdges = std::numeric_limits<int>::max();
     203             :         /// @brief minimum number of edges crossed by incoming crossings
     204             :         int minPrevCrossingEdges = std::numeric_limits<int>::max();
     205             :         /// @brief reference edges that uniquely identify this walkingarea
     206             :         std::set<const NBEdge*, ComparatorIdLess> refEdges;
     207             :     };
     208             : 
     209         200 :     struct WalkingAreaCustomShape {
     210             :         std::set<const NBEdge*, ComparatorIdLess> edges;
     211             :         PositionVector shape;
     212             :         double width;
     213             :     };
     214             : 
     215             :     /// @brief edge directions (for pedestrian related stuff)
     216             :     static const int FORWARD;
     217             :     static const int BACKWARD;
     218             : 
     219             :     /// @brief unspecified lane width
     220             :     static const double UNSPECIFIED_RADIUS;
     221             : 
     222             :     /// @brief flags for controlling shape generation
     223             :     static const int AVOID_WIDE_RIGHT_TURN;
     224             :     static const int AVOID_WIDE_LEFT_TURN;
     225             :     static const int FOUR_CONTROL_POINTS;
     226             :     static const int AVOID_INTERSECTING_LEFT_TURNS;
     227             :     static const int SCURVE_IGNORE;
     228             :     static const int INDIRECT_LEFT;
     229             : 
     230             : public:
     231             :     /**@brief Constructor
     232             :      * @param[in] id The id of the node
     233             :      * @param[in] position The position of the node
     234             :      * @param[in] type The type of the node
     235             :      */
     236             :     NBNode(const std::string& id, const Position& position, SumoXMLNodeType type);
     237             : 
     238             :     /**@brief Constructor
     239             :      * @param[in] id The id of the node
     240             :      * @param[in] position The position of the node
     241             :      * @param[in] district The district this district node represents, 0 means no district node
     242             :      */
     243             :     NBNode(const std::string& id, const Position& position, NBDistrict* district = 0);
     244             : 
     245             :     /// @brief Destructor
     246             :     ~NBNode();
     247             : 
     248             :     /**@brief Resets initial values
     249             :      * @param[in] position The position of the node
     250             :      * @param[in] type The type of the node
     251             :      * @param[in] updateEdgeGeometries Whether the geometires of all
     252             :      *    connected edges shall be updated
     253             :      */
     254             :     void reinit(const Position& position, SumoXMLNodeType type,
     255             :                 bool updateEdgeGeometries = false);
     256             : 
     257             :     /// @name Atomar getter methods
     258             :     /// @{
     259             :     /// @brief Returns the position of this node
     260             :     inline const Position& getPosition() const {
     261      377809 :         return myPosition;
     262             :     }
     263             : 
     264             :     /// @brief Returns a position that is guaranteed to lie within the node shape
     265             :     Position getCenter() const;
     266             : 
     267             :     /// @brief Returns this node's incoming edges (The edges which yield in this node)
     268             :     inline const EdgeVector& getIncomingEdges() const {
     269       46279 :         return myIncomingEdges;
     270             :     }
     271             : 
     272             :     /// @brief Returns this node's outgoing edges (The edges which start at this node)
     273             :     inline const EdgeVector& getOutgoingEdges() const {
     274       80283 :         return myOutgoingEdges;
     275             :     }
     276             : 
     277             :     /// @brief Returns all edges which participate in this node (Edges that start or end at this node)
     278             :     inline const EdgeVector& getEdges() const {
     279      247267 :         return myAllEdges;
     280             :     }
     281             : 
     282             :     /**@brief Returns the type of this node
     283             :      * @see SumoXMLNodeType
     284             :      */
     285             :     inline SumoXMLNodeType getType() const {
     286     2847337 :         return myType;
     287             :     }
     288             : 
     289             :     /// @brief Returns the turning radius of this node
     290             :     inline double getRadius() const {
     291      257658 :         return myRadius;
     292             :     }
     293             : 
     294             :     /// @brief Returns the keepClear flag
     295             :     inline bool getKeepClear() const {
     296        1487 :         return myKeepClear;
     297             :     }
     298             : 
     299             :     /// @brief Returns hint on how to compute right of way
     300             :     inline RightOfWay getRightOfWay() const {
     301      178077 :         return myRightOfWay;
     302             :     }
     303             : 
     304             :     /// @brief Returns fringe type
     305             :     inline FringeType getFringeType() const {
     306      108197 :         return myFringeType;
     307             :     }
     308             : 
     309             :     /// @brief Returns intersection name
     310             :     inline const std::string& getName() const {
     311       71583 :         return myName;
     312             :     }
     313             :     /// @}
     314             : 
     315             :     /// @name Methods for dealing with assigned traffic lights
     316             :     /// @{
     317             :     /**@brief Adds a traffic light to the list of traffic lights that control this node
     318             :      * @param[in] tld The traffic light that controls this node
     319             :      */
     320             :     void addTrafficLight(NBTrafficLightDefinition* tlDef);
     321             : 
     322             :     /// @brief Removes the given traffic light from this node
     323             :     void removeTrafficLight(NBTrafficLightDefinition* tlDef);
     324             : 
     325             :     /// @brief Removes all references to traffic lights that control this tls
     326             :     void removeTrafficLights(bool setAsPriority = false);
     327             : 
     328             :     /**@brief Returns whether this node is controlled by any tls
     329             :      * @return Whether a traffic light was assigned to this node
     330             :      */
     331             :     bool isTLControlled() const {
     332       36964 :         return myTrafficLights.size() != 0;
     333             :     }
     334             : 
     335             :     /// @brief Returns the traffic lights that were assigned to this node (The set of tls that control this node)
     336             :     const std::set<NBTrafficLightDefinition*>& getControllingTLS() const {
     337             :         return myTrafficLights;
     338             :     }
     339             : 
     340             :     /// @brief causes the traffic light to be computed anew
     341             :     void invalidateTLS(NBTrafficLightLogicCont& tlCont, bool removedConnections, bool addedConnections);
     342             : 
     343             :     /// @brief patches loaded signal plans by modifying lane indices above threshold by the given offset
     344             :     void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1);
     345             :     /// @}
     346             : 
     347             : 
     348             :     /// @name Prunning the input
     349             :     /// @{
     350             : 
     351             :     /**@brief Removes edges which are both incoming and outgoing into this node
     352             :      *
     353             :      * If given, the connections to other edges participating in this node are updated
     354             :      *
     355             :      * @param[in, opt. changed] dc The districts container to update
     356             :      * @param[in, opt. changed] ec The edge container to remove the edges from
     357             :      * @param[in, opt. changed] tc The traffic lights container to update
     358             :      * @return The number of removed edges
     359             :      */
     360             :     int removeSelfLoops(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc);
     361             :     /// @}
     362             : 
     363             : 
     364             :     /// @name Applying offset
     365             :     /// @{
     366             :     /**@brief Applies an offset to the node
     367             :      * @param[in] xoff The x-offset to apply
     368             :      * @param[in] yoff The y-offset to apply
     369             :      */
     370             :     void reshiftPosition(double xoff, double yoff);
     371             : 
     372             :     /// @brief mirror coordinates along the x-axis
     373             :     void mirrorX();
     374             :     /// @}
     375             : 
     376             :     /// @brief adds an incoming edge
     377             :     void addIncomingEdge(NBEdge* edge);
     378             : 
     379             :     /// @brief adds an outgoing edge
     380             :     void addOutgoingEdge(NBEdge* edge);
     381             : 
     382             :     /// @brief computes the connections of lanes to edges
     383             :     void computeLanes2Lanes();
     384             : 
     385             :     /// @brief computes the node's type, logic and traffic light
     386             :     void computeLogic(const NBEdgeCont& ec);
     387             : 
     388             :     /// @brief compute right-of-way logic for all lane-to-lane connections
     389             :     void computeLogic2(bool checkLaneFoes);
     390             : 
     391             :     /// @brief compute keepClear status for all connections
     392             :     void computeKeepClear();
     393             : 
     394             :     /// @brief writes the XML-representation of the logic as a bitset-logic XML representation
     395             :     bool writeLogic(OutputDevice& into) const;
     396             : 
     397             :     /// @brief get the 'foes' string (conflict bit set) of the right-of-way logic
     398             :     const std::string getFoes(int linkIndex) const;
     399             : 
     400             :     /// @brief get the 'response' string (right-of-way bit set) of the right-of-way logic
     401             :     const std::string getResponse(int linkIndex) const;
     402             : 
     403             :     /// @brief whether there are conflicting streams of traffic at this node
     404             :     bool hasConflict() const;
     405             : 
     406             :     /// @brief whether the given edge has a conflicting stream of traffic at this node
     407             :     bool hasConflict(const NBEdge* e) const;
     408             : 
     409             :     /// @brief Returns something like the most unused direction Should only be used to add source or sink nodes
     410             :     Position getEmptyDir() const;
     411             : 
     412             :     /**@brief Returns whether the given edge ends at this node
     413             :      * @param[in] e The edge
     414             :      * @return Whether the given edge is one of this node's incoming edges
     415             :      */
     416             :     bool hasIncoming(const NBEdge* const e) const;
     417             : 
     418             :     /**@brief Returns whether the given edge starts at this node
     419             :      * @param[in] e The edge
     420             :      * @return Whether the given edge is one of this node's outgoing edges
     421             :      */
     422             :     bool hasOutgoing(const NBEdge* const e) const;
     423             : 
     424             :     /// @brief returns the opposite incoming edge of certain edge
     425             :     NBEdge* getOppositeIncoming(NBEdge* e) const;
     426             : 
     427             :     /// @brief invalidate incoming connections
     428             :     void invalidateIncomingConnections(bool reallowSetting = false);
     429             : 
     430             :     /// @brief invalidate outgoing connections
     431             :     void invalidateOutgoingConnections(bool reallowSetting = false);
     432             : 
     433             :     /// @brief remove duble edges
     434             :     void removeDoubleEdges();
     435             : 
     436             :     /// @brief get connection to certain node
     437             :     NBEdge* getConnectionTo(NBNode* n) const;
     438             : 
     439             :     /// @brief add shorted link FOES
     440             :     void addSortedLinkFoes(const NBConnection& mayDrive, const NBConnection& mustStop);
     441             : 
     442             :     /// @brief get possibly splitted incoming  edge
     443             :     NBEdge* getPossiblySplittedIncoming(const std::string& edgeid);
     444             : 
     445             :     /// @brief get possibly splitted outgoing edge
     446             :     NBEdge* getPossiblySplittedOutgoing(const std::string& edgeid);
     447             : 
     448             :     /// @brief Removes edge from this node and optionally removes connections as well
     449             :     void removeEdge(NBEdge* edge, bool removeFromConnections = true);
     450             : 
     451             :     /**@brief Computes whether the given connection is a left mover across the junction
     452             :      *
     453             :      * It is assumed, that it is a left-mover if the clockwise angle is lower
     454             :      *  than the counter-clockwise angle.
     455             :      *
     456             :      * @param[in] from The incoming edge (the begin of the connection)
     457             :      * @param[in] from The outgoing edge (the end of the connection)
     458             :      * @return Whether the described connection is a left-mover
     459             :      */
     460             :     bool isLeftMover(const NBEdge* const from, const NBEdge* const to) const;
     461             : 
     462             :     /**@brief Returns the information whether the described flow must let any other flow pass
     463             :      * @param[in] from The connection's start edge
     464             :      * @param[in] to The connection's end edge
     465             :      * @param[in] fromLane The lane the connection start at
     466             :      * @param[in] toLane The lane the connection ends at
     467             :      * @param[in] includePedCrossings Whether braking due to a pedestrian crossing counts
     468             :      * @return Whether the described connection must brake (has higher priorised foes)
     469             :      */
     470             :     bool mustBrake(const NBEdge* const from, const NBEdge* const to, int fromLane, int toLane, bool includePedCrossings) const;
     471             : 
     472             :     /**@brief Returns the information whether the described flow must brake for the given crossing
     473             :      * @param[in] from The connection's start edge
     474             :      * @param[in] to The connection's end edge
     475             :      * @param[in] crossing The pedestrian crossing to check
     476             :      * @return Whether the described connection must brake (has higher priorised foes)
     477             :      */
     478             :     bool mustBrakeForCrossing(const NBEdge* const from, const NBEdge* const to, const Crossing& crossing) const;
     479             : 
     480             :     /// @brief whether a connection to the given edge must brake for a crossing when leaving the intersection
     481             :     bool brakeForCrossingOnExit(const NBEdge* to) const;
     482             : 
     483             :     /// @brief return whether the given laneToLane connection is a right turn which must yield to a bicycle crossings
     484             :     static bool rightTurnConflict(const NBEdge* from, const NBEdge* to, int fromLane,
     485             :                                   const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorFromLane);
     486             : 
     487             :     /// @brief whether one of multple connections from the same edge targeting the same lane must yield
     488             :     bool mergeConflictYields(const NBEdge* from, int fromLane, int fromLaneFoe, NBEdge* to, int toLane) const;
     489             : 
     490             :     /// @brief whether multiple connections from the same edge target the same lane
     491             :     bool mergeConflict(const NBEdge* from, const NBEdge::Connection& con,
     492             :                        const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
     493             : 
     494             :     /// @brief whether the foe connections is oncoming on the same lane
     495             :     bool bidiConflict(const NBEdge* from, const NBEdge::Connection& con,
     496             :                       const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
     497             : 
     498             :     bool zipperConflict(const NBEdge* incoming, const NBEdge* outgoing, int fromLane, int toLane) const;
     499             : 
     500             :     /// @brief return whether the given laneToLane connection originate from the same edge and are in conflict due to turning across each other
     501             :     bool turnFoes(const NBEdge* from, const NBEdge* to, int fromLane,
     502             :                   const NBEdge* from2, const NBEdge* to2, int fromLane2,
     503             :                   bool lefthand = false) const;
     504             : 
     505             :     /**@brief Returns the information whether "prohibited" flow must let "prohibitor" flow pass
     506             :      * @param[in] possProhibitedFrom The maybe prohibited connection's begin
     507             :      * @param[in] possProhibitedTo The maybe prohibited connection's end
     508             :      * @param[in] possProhibitorFrom The maybe prohibiting connection's begin
     509             :      * @param[in] possProhibitorTo The maybe prohibiting connection's end
     510             :      * @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
     511             :      * @return Whether the second flow prohibits the first one
     512             :      */
     513             :     bool forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
     514             :                  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
     515             :                  bool regardNonSignalisedLowerPriority) const;
     516             : 
     517             :     /**@brief Returns the information whether the given flows cross
     518             :      * @param[in] from1 The starting edge of the first stream
     519             :      * @param[in] to1 The ending edge of the first stream
     520             :      * @param[in] from2 The starting edge of the second stream
     521             :      * @param[in] to2 The ending edge of the second stream
     522             :      * @return Whether both stream are foes (cross)
     523             :      */
     524             :     bool foes(const NBEdge* const from1, const NBEdge* const to1,
     525             :               const NBEdge* const from2, const NBEdge* const to2) const;
     526             : 
     527             :     /**@brief Returns the representation of the described stream's direction
     528             :      * @param[in] incoming The edge the stream starts at
     529             :      * @param[in] outgoing The edge the stream ends at
     530             :      * @param[in] leftHand Whether a lefthand network is being built. Should only be set at writing time
     531             :      * @return The direction of the stream
     532             :      */
     533             :     LinkDirection getDirection(const NBEdge* const incoming, const NBEdge* const outgoing, bool leftHand = false) const;
     534             : 
     535             :     /// @brief get link state
     536             :     LinkState getLinkState(const NBEdge* incoming, const NBEdge* outgoing,
     537             :                            int fromLane, int toLane, bool mayDefinitelyPass, const std::string& tlID) const;
     538             : 
     539             :     /**@brief Compute the junction shape for this node
     540             :      * @param[in] mismatchThreshold The threshold for warning about shapes which are away from myPosition
     541             :      */
     542             :     void computeNodeShape(double mismatchThreshold);
     543             : 
     544             :     /// @brief update geometry of node and surrounding edges
     545             :     void updateSurroundingGeometry();
     546             : 
     547             :     /// @brief retrieve the junction shape
     548             :     const PositionVector& getShape() const;
     549             : 
     550             :     /// @brief set the junction shape
     551             :     void setCustomShape(const PositionVector& shape);
     552             : 
     553             :     /// @brief reset node shape
     554             :     void resetShape() {
     555             :         myPoly.clear();
     556             :     }
     557             : 
     558             :     /// @brief set the turning radius
     559             :     void setRadius(double radius) {
     560          49 :         myRadius = radius;
     561          49 :     }
     562             : 
     563             :     /// @brief set the keepClear flag
     564             :     void setKeepClear(bool keepClear) {
     565           1 :         myKeepClear = keepClear;
     566           1 :     }
     567             : 
     568             :     /// @brief set method for computing right-of-way
     569             :     void setRightOfWay(RightOfWay rightOfWay) {
     570       36586 :         myRightOfWay = rightOfWay;
     571          12 :     }
     572             : 
     573             :     /// @brief set method for computing right-of-way
     574             :     void setFringeType(FringeType fringeType) {
     575       36698 :         myFringeType = fringeType;
     576         113 :     }
     577             : 
     578             :     /// @brief set intersection name
     579             :     void setName(const std::string& name) {
     580           4 :         myName = name;
     581           4 :     }
     582             : 
     583             :     /// @brief return whether the shape was set by the user
     584             :     bool hasCustomShape() const {
     585       71613 :         return myHaveCustomPoly;
     586             :     }
     587             : 
     588             :     /// @brief check if node is removable
     589             :     bool checkIsRemovable() const;
     590             : 
     591             :     /// @brief check if node is removable and return reason if not
     592             :     bool checkIsRemovableReporting(std::string& reason) const;
     593             : 
     594             :     /// @brief get edges to join
     595             :     std::vector<std::pair<NBEdge*, NBEdge*> > getEdgesToJoin() const;
     596             : 
     597             :     /// @chech if node is near district
     598             :     bool isNearDistrict() const;
     599             : 
     600             :     /// @brief check if node is a district
     601             :     bool isDistrict() const;
     602             : 
     603             :     /// @brief whether an internal junction should be built at from and respect other
     604             :     bool needsCont(const NBEdge* fromE, const NBEdge* otherFromE,
     605             :                    const NBEdge::Connection& c, const NBEdge::Connection& otherC, bool checkOnlyTLS = false) const;
     606             : 
     607             :     /// @brief whether the connection must yield if the foe remains on the intersection after its phase ends
     608             :     bool tlsContConflict(const NBEdge* from, const NBEdge::Connection& c,
     609             :                          const NBEdge* foeFrom, const NBEdge::Connection& foe) const;
     610             : 
     611             : 
     612             :     /**@brief Compute the shape for an internal lane
     613             :      * @param[in] fromE The starting edge
     614             :      * @param[in] con The connection for this internal lane
     615             :      * @param[in] numPoints The number of geometry points for the internal lane
     616             :      * @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
     617             :      * @return The shape of the internal lane
     618             :      */
     619             :     PositionVector computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& con, int numPoints, NBNode* recordError = 0, int shapeFlag = 0) const;
     620             : 
     621             :     /**@brief Compute a smooth curve between the given geometries
     622             :      * @param[in] begShape The geometry at the start
     623             :      * @param[in] endShape The geometry at the end
     624             :      * @param[in] numPoints The number of geometry points for the internal lane
     625             :      * @param[in] isTurnaround Whether this shall be the shape for a turnaround
     626             :      * @param[in] extrapolateBeg Extrapolation distance at the beginning
     627             :      * @param[in] extrapolateEnd Extrapolation distance at the end
     628             :      * @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
     629             :      * @return The shape of the internal lane
     630             :      */
     631             :     PositionVector computeSmoothShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints,
     632             :                                       bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
     633             :                                       NBNode* recordError = 0, int shapeFlag = 0) const;
     634             :     /// @brief get bezier control points
     635             :     static PositionVector bezierControlPoints(const PositionVector& begShape, const PositionVector& endShape,
     636             :             bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
     637             :             bool& ok, NBNode* recordError = 0, double straightThresh = DEG2RAD(5),
     638             :             int shapeFlag = 0);
     639             : 
     640             :     /// @brief compute shape of indirect left turn
     641             :     PositionVector indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const;
     642             : 
     643             :     /// @brief compute the displacement error during s-curve computation
     644             :     double getDisplacementError() const {
     645          32 :         return myDisplacementError;
     646             :     }
     647             : 
     648             :     /// @brief Replaces occurrences of the first edge within the list of incoming by the second Connections are remapped, too
     649             :     void replaceIncoming(NBEdge* which, NBEdge* by, int laneOff);
     650             : 
     651             :     /// @brief Replaces occurrences of every edge from the given list within the list of incoming by the second Connections are remapped, too
     652             :     void replaceIncoming(const EdgeVector& which, NBEdge* by);
     653             : 
     654             :     /// @brief Replaces occurrences of the first edge within the list of outgoing by the second Connections are remapped, too
     655             :     void replaceOutgoing(NBEdge* which, NBEdge* by, int laneOff);
     656             : 
     657             :     /// @brief Replaces occurrences of every edge from the given list within the list of outgoing by the second Connections are remapped, too
     658             :     void replaceOutgoing(const EdgeVector& which, NBEdge* by);
     659             : 
     660             :     /// @brief guess pedestrian crossings and return how many were guessed
     661             :     int guessCrossings();
     662             : 
     663             :     /* @brief check whether a crossing should be build for the candiate edges and build 0 to n crossings
     664             :      * @param[in] candidates The candidate vector of edges to be crossed
     665             :      * @param[in] checkOnly Whether only checking (of user supplied) crossings shall be performed
     666             :      * @return The number of crossings built
     667             :      * */
     668             :     int checkCrossing(EdgeVector candidates, bool checkOnly = false);
     669             : 
     670             :     /// @brief return true if there already exist a crossing with the same edges as the input
     671             :     bool checkCrossingDuplicated(EdgeVector edges);
     672             : 
     673             :     /// @brief build internal lanes, pedestrian crossings and walking areas
     674             :     double buildInnerEdges();
     675             : 
     676             :     /**@brief build pedestrian crossings
     677             :      * @return The next index for creating internal lanes
     678             :      **/
     679             :     int buildCrossings();
     680             : 
     681             :     /**@brief build pedestrian walking areas and set connections from/to walkingAreas
     682             :      * @param[in] cornerDetail The detail level when generating the inner curve
     683             :      */
     684             :     void buildWalkingAreas(int cornerDetail, double joinMinDist);
     685             : 
     686             :     /// @brief build crossing outlines after walkingareas are finished
     687             :     void buildCrossingOutlines();
     688             : 
     689             :     /// @brief build crossings, and walkingareas. Also removes invalid loaded crossings if wished
     690             :     void buildCrossingsAndWalkingAreas();
     691             : 
     692             :     /// @brief return all edges that lie clockwise between the given edges
     693             :     EdgeVector edgesBetween(const NBEdge* e1, const NBEdge* e2) const;
     694             : 
     695             :     /// @brief return true if the given edges are connected by a crossing
     696             :     bool crossingBetween(const NBEdge* e1, const NBEdge* e2) const;
     697             : 
     698             :     /// @brief return true if the given pedestrian paths are connected at another junction within dist
     699             :     bool alreadyConnectedPaths(const NBEdge* e1, const NBEdge* e2, double dist) const;
     700             : 
     701             :     /// @brief return true if the given sidewalks are separated by a fringe road
     702             :     bool crossesFringe(const NBEdge* e1, const NBEdge* e2) const;
     703             : 
     704             :     /// @brief get prohibitions (BLocked connections)
     705             :     const NBConnectionProhibits& getProhibitions() {
     706       71583 :         return myBlockedConnections;
     707             :     }
     708             : 
     709             :     /// @brief whether this is structurally similar to a geometry node
     710             :     bool geometryLike() const;
     711             :     bool geometryLike(const EdgeVector& incoming, const EdgeVector& outgoing) const;
     712             : 
     713             :     /// @brief update the type of this node as a roundabout
     714             :     void setRoundabout();
     715             : 
     716             :     /// @brief return whether this node is part of a roundabout
     717             :     bool isRoundabout() const;
     718             : 
     719             :     /// @brief add a pedestrian crossing to this node
     720             :     NBNode::Crossing* addCrossing(EdgeVector edges, double width, bool priority, int tlIndex = -1, int tlIndex2 = -1,
     721             :                                   const PositionVector& customShape = PositionVector::EMPTY, bool fromSumoNet = false, const Parameterised* params = nullptr);
     722             : 
     723             :     /// @brief add custom shape for walkingArea
     724             :     void addWalkingAreaShape(EdgeVector edges, const PositionVector& shape, double width);
     725             : 
     726             :     /// @brief remove a pedestrian crossing from this node (identified by its edges)
     727             :     void removeCrossing(const EdgeVector& edges);
     728             : 
     729             :     /// @brief discard all current (and optionally future) crossings
     730             :     void discardAllCrossings(bool rejectAll);
     731             : 
     732             :     /// @brief discard previously built walkingareas (required for repeated computation by netedit)
     733             :     void discardWalkingareas();
     734             : 
     735             :     /// @brief get num of crossings from sumo net
     736             :     int numCrossingsFromSumoNet() const {
     737        1250 :         return myCrossingsLoadedFromSumoNet;
     738             :     }
     739             : 
     740             :     /// @brief return this junctions pedestrian crossings
     741             :     std::vector<Crossing*> getCrossings() const;
     742             :     inline const std::vector<std::unique_ptr<Crossing> >& getCrossingsIncludingInvalid() const {
     743             :         return myCrossings;
     744             :     }
     745             : 
     746             :     /// @brief return this junctions pedestrian walking areas
     747             :     inline const std::vector<WalkingArea>& getWalkingAreas() const {
     748             :         return myWalkingAreas;
     749             :     }
     750             : 
     751             :     const std::vector<WalkingAreaCustomShape>& getWalkingAreaCustomShapes() const {
     752             :         return myWalkingAreaCustomShapes;
     753             :     }
     754             : 
     755             :     /// @brief return the crossing with the given id
     756             :     Crossing* getCrossing(const std::string& id) const;
     757             : 
     758             :     /// @brief return the crossing with the given Edges
     759             :     Crossing* getCrossing(const EdgeVector& edges, bool hardFail = true) const;
     760             : 
     761             :     /// @brief return the walkingArea with the given ID
     762             :     WalkingArea& getWalkingArea(const std::string& id);
     763             : 
     764             :     /* @brief set tl indices of this nodes crossing starting at the given index
     765             :      * @return Whether a custom index was used
     766             :      */
     767             :     bool setCrossingTLIndices(const std::string& tlID, int startIndex);
     768             : 
     769             :     /// @brief return the number of lane-to-lane connections at this junction (excluding crossings)
     770             :     int numNormalConnections() const;
     771             : 
     772             :     /// @brief fix overlap
     773             :     void avoidOverlap();
     774             : 
     775             :     /// @brief whether the given index must yield to the foeIndex while turing right on a red light
     776             :     bool rightOnRedConflict(int index, int foeIndex) const;
     777             : 
     778             :     /// @brief sort all edge containers for this node
     779             :     void sortEdges(bool useNodeShape);
     780             : 
     781             :     /// @brief return the index of the given connection
     782             :     int getConnectionIndex(const NBEdge* from, const NBEdge::Connection& con) const;
     783             : 
     784             :     /**
     785             :      * @class nodes_by_id_sorter
     786             :      * @brief Used for sorting the cells by the begin time they describe
     787             :      */
     788             :     class nodes_by_id_sorter {
     789             :     public:
     790             :         /// @brief Constructor
     791             :         explicit nodes_by_id_sorter() { }
     792             : 
     793             :         /// @brief Comparing operator
     794             :         int operator()(NBNode* n1, NBNode* n2) const {
     795             :             return n1->getID() < n2->getID();
     796             :         }
     797             :     };
     798             : 
     799             :     /** @class edge_by_direction_sorter
     800             :      * @brief Sorts outgoing before incoming edges
     801             :      */
     802             :     class edge_by_direction_sorter {
     803             :     public:
     804             :         /// @brief constructor
     805             :         explicit edge_by_direction_sorter(NBNode* n) : myNode(n) {}
     806             : 
     807             :         /// @brief operator of selection
     808             :         int operator()(NBEdge* e1, NBEdge* e2) const {
     809             :             UNUSED_PARAMETER(e2);
     810             :             return e1->getFromNode() == myNode;
     811             :         }
     812             : 
     813             :     private:
     814             :         /// @brief The node to compute the relative angle of
     815             :         NBNode* myNode;
     816             : 
     817             :     };
     818             : 
     819             :     /// @brief return whether the given type is a traffic light
     820             :     static bool isTrafficLight(SumoXMLNodeType type);
     821             : 
     822             :     inline bool isTrafficLight() const {
     823       15467 :         return isTrafficLight(myType);
     824             :     }
     825             : 
     826             :     /// @brief check if node is a simple continuation
     827             :     bool isSimpleContinuation(bool checkLaneNumbers = true, bool checkWidth = false) const;
     828             : 
     829             :     /// @brief mark whether a priority road turns at this node
     830             :     void markBentPriority(bool isBent) {
     831       90219 :         myIsBentPriority = isBent;
     832       15033 :     }
     833             : 
     834             :     /// @brief return whether a priority road turns at this node
     835             :     bool isBentPriority() const {
     836       85329 :         return myIsBentPriority;
     837             :     }
     838             : 
     839             :     /// @brief return whether a priority road turns at this node
     840             :     bool typeWasGuessed() const {
     841        1724 :         return myTypeWasGuessed;
     842             :     }
     843             : 
     844             :     /// @brief detects whether a given junction splits or merges lanes while keeping constant road width
     845             :     bool isConstantWidthTransition() const;
     846             : 
     847             :     /// @brief return list of unique endpoint coordinates of all edges at this node
     848             :     std::vector<std::pair<Position, std::string> > getEndPoints() const;
     849             : 
     850             : private:
     851             :     /// @brief sets the priorites in case of a priority junction
     852             :     void setPriorityJunctionPriorities();
     853             : 
     854             :     /// @brief returns a list of edges which are connected to the given outgoing edge
     855             :     void getEdgesThatApproach(NBEdge* currentOutgoing, EdgeVector& approaching);
     856             : 
     857             :     /// @brief replace incoming connections prohibitions
     858             :     void replaceInConnectionProhibitions(NBEdge* which, NBEdge* by, int whichLaneOff, int byLaneOff);
     859             : 
     860             :     /// @brief remap removed
     861             :     void remapRemoved(NBTrafficLightLogicCont& tc, NBEdge* removed, const EdgeVector& incoming, const EdgeVector& outgoing);
     862             : 
     863             :     /// @brief return whether there is a non-sidewalk lane after the given index;
     864             :     bool forbidsPedestriansAfter(std::vector<std::pair<NBEdge*, bool> > normalizedLanes, int startIndex);
     865             : 
     866             :     /// @brief returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
     867             :     EdgeVector getEdgesSortedByAngleAtNodeCenter() const;
     868             : 
     869             :     /// @brief check if is long enough
     870             :     static bool isLongEnough(NBEdge* out, double minLength);
     871             : 
     872             :     /// @brief remove all traffic light definitions that are part of a joined tls
     873             :     void removeJoinedTrafficLights();
     874             : 
     875             :     /// @brief displace lane shapes to account for change in lane width at this node
     876             :     void displaceShapeAtWidthChange(const NBEdge* from, const NBEdge::Connection& con, PositionVector& fromShape, PositionVector& toShape) const;
     877             : 
     878             :     /// @brief returns whether sub is a subset of super
     879             :     static bool includes(const std::set<const NBEdge*, ComparatorIdLess>& super,
     880             :                          const std::set<const NBEdge*, ComparatorIdLess>& sub);
     881             : 
     882             :     NBEdge* getNextCompatibleOutgoing(const NBEdge* incoming, SVCPermissions vehPerm, EdgeVector::const_iterator start, bool clockwise) const;
     883             : 
     884             :     /// @brief ensure connectivity for all vClasses
     885             :     void recheckVClassConnections(NBEdge* currentOutgoing);
     886             : 
     887             :     /// @brief get the reduction in driving lanes at this junction
     888             :     void getReduction(const NBEdge* in, const NBEdge* out, int& inOffset, int& outOffset, int& reduction) const;
     889             : 
     890             :     /// @brief check whether this edge has extra lanes on the right side
     891             :     int addedLanesRight(NBEdge* out, int addedLanes) const;
     892             : 
     893             :     /// @brief check whether the candidate edge is more likely to be the straight continuation
     894             :     bool isStraighter(const NBEdge* const incoming, const double angle, const SVCPermissions vehPerm, const int modeLanes, const NBEdge* const candidate) const;
     895             : 
     896             :     /// @brief return edges that permit passengers (either incoming or outgoing)
     897             :     EdgeVector getPassengerEdges(bool incoming) const;
     898             : 
     899             :     /// @brief detect explict rail turns with potential geometry problem
     900             :     static bool isExplicitRailNoBidi(const NBEdge* incoming, const NBEdge* outgoing);
     901             : 
     902             :     /// @brief geometry helper that cuts the first shape where bordered by the other two
     903             :     PositionVector cutAtShapes(const PositionVector& cut, const PositionVector& border1, const PositionVector& border2, const PositionVector& def);
     904             : 
     905             : private:
     906             :     /// @brief The position the node lies at
     907             :     Position myPosition;
     908             : 
     909             :     /// @brief Vector of incoming edges
     910             :     EdgeVector myIncomingEdges;
     911             : 
     912             :     /// @brief Vector of outgoing edges
     913             :     EdgeVector myOutgoingEdges;
     914             : 
     915             :     /// @brief Vector of incoming and outgoing edges
     916             :     EdgeVector myAllEdges;
     917             : 
     918             :     /// @brief Vector of crossings
     919             :     std::vector<std::unique_ptr<Crossing> > myCrossings;
     920             : 
     921             :     /// @brief Vector of walking areas
     922             :     std::vector<WalkingArea> myWalkingAreas;
     923             : 
     924             :     /// @brief Vector of custom walking areas shapes
     925             :     std::vector<WalkingAreaCustomShape> myWalkingAreaCustomShapes;
     926             : 
     927             :     /// @brief The type of the junction
     928             :     SumoXMLNodeType myType;
     929             : 
     930             :     /// @brief The container for connection block dependencies
     931             :     NBConnectionProhibits myBlockedConnections;
     932             : 
     933             :     /// @brief The district the node is the centre of
     934             :     NBDistrict* myDistrict;
     935             : 
     936             :     /// @brief the (outer) shape of the junction
     937             :     PositionVector myPoly;
     938             : 
     939             :     /// @brief whether this nodes shape was set by the user
     940             :     bool myHaveCustomPoly;
     941             : 
     942             :     /// @brief Node requests
     943             :     NBRequest* myRequest;
     944             : 
     945             :     /// @brief traffic lights of node
     946             :     std::set<NBTrafficLightDefinition*> myTrafficLights;
     947             : 
     948             :     /// @brief the turning radius (for all corners) at this node in m.
     949             :     double myRadius;
     950             : 
     951             :     /// @brief whether the junction area must be kept clear
     952             :     bool myKeepClear;
     953             : 
     954             :     /// @brief how to compute right of way for this node
     955             :     RightOfWay myRightOfWay;
     956             : 
     957             :     /// @brief fringe type of this node
     958             :     FringeType myFringeType;
     959             : 
     960             :     /// @brief The intersection name (or whatever arbitrary string you wish to attach)
     961             :     std::string myName;
     962             : 
     963             :     /// @brief whether to discard all pedestrian crossings
     964             :     bool myDiscardAllCrossings;
     965             : 
     966             :     /// @brief number of crossings loaded from a sumo net
     967             :     int myCrossingsLoadedFromSumoNet;
     968             : 
     969             :     /// @brief geometry error after computation of internal lane shapes
     970             :     double myDisplacementError;
     971             : 
     972             :     /* @brief whether this junction is a bent priority junction (main direction turns)
     973             :      * @note see NBEdgePriorityComputer
     974             :      */
     975             :     bool myIsBentPriority;
     976             : 
     977             :     /// @brief whether the node type was guessed rather than loaded
     978             :     bool myTypeWasGuessed;
     979             : 
     980             : private:
     981             :     /// @brief invalidated copy constructor
     982             :     NBNode(const NBNode& s);
     983             : 
     984             :     /// @brief invalidated assignment operator
     985             :     NBNode& operator=(const NBNode& s);
     986             : };

Generated by: LCOV version 1.14