LCOV - code coverage report
Current view: top level - src/netbuild - NBNode.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 39 39
Test Date: 2025-11-13 15:38:19 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2025 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        72067 :             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         2046 :     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         5340 :         WalkingArea(const std::string& _id, double _width) :
     180         5340 :             id(_id),
     181         5340 :             width(_width) {
     182         5340 :         }
     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       309844 :         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        37162 :         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        60126 :         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       189044 :         return myAllEdges;
     280              :     }
     281              : 
     282              :     /**@brief Returns the type of this node
     283              :      * @see SumoXMLNodeType
     284              :      */
     285              :     inline SumoXMLNodeType getType() const {
     286      2263904 :         return myType;
     287              :     }
     288              : 
     289              :     /// @brief Returns the turning radius of this node
     290              :     inline double getRadius() const {
     291       192458 :         return myRadius;
     292              :     }
     293              : 
     294              :     /// @brief Returns the keepClear flag
     295              :     inline bool getKeepClear() const {
     296         1226 :         return myKeepClear;
     297              :     }
     298              : 
     299              :     /// @brief Returns hint on how to compute right of way
     300              :     inline RightOfWay getRightOfWay() const {
     301       146206 :         return myRightOfWay;
     302              :     }
     303              : 
     304              :     /// @brief Returns fringe type
     305              :     inline FringeType getFringeType() const {
     306        88658 :         return myFringeType;
     307              :     }
     308              : 
     309              :     /// @brief Returns roundabout type
     310              :     inline RoundaboutType getRoundaboutType() const {
     311       121532 :         return myRoundaboutType;
     312              :     }
     313              : 
     314              :     /// @brief Returns intersection name
     315              :     inline const std::string& getName() const {
     316        56971 :         return myName;
     317              :     }
     318              :     /// @}
     319              : 
     320              :     /// @name Methods for dealing with assigned traffic lights
     321              :     /// @{
     322              :     /**@brief Adds a traffic light to the list of traffic lights that control this node
     323              :      * @param[in] tld The traffic light that controls this node
     324              :      */
     325              :     void addTrafficLight(NBTrafficLightDefinition* tlDef);
     326              : 
     327              :     /// @brief Removes the given traffic light from this node
     328              :     void removeTrafficLight(NBTrafficLightDefinition* tlDef);
     329              : 
     330              :     /// @brief Removes all references to traffic lights that control this tls
     331              :     void removeTrafficLights(bool setAsPriority = false);
     332              : 
     333              :     /**@brief Returns whether this node is controlled by any tls
     334              :      * @return Whether a traffic light was assigned to this node
     335              :      */
     336              :     bool isTLControlled() const {
     337        27942 :         return myTrafficLights.size() != 0;
     338              :     }
     339              : 
     340              : 
     341              :     /// @brief whether this node was marked as having a signal in the (OSM) input
     342              :     bool hadSignal() const;
     343              : 
     344              :     /// @brief Returns the traffic lights that were assigned to this node (The set of tls that control this node)
     345              :     const std::set<NBTrafficLightDefinition*>& getControllingTLS() const {
     346              :         return myTrafficLights;
     347              :     }
     348              : 
     349              :     /// @brief causes the traffic light to be computed anew
     350              :     void invalidateTLS(NBTrafficLightLogicCont& tlCont, bool addedConnections, bool removedConnections);
     351              : 
     352              :     /// @brief patches loaded signal plans by modifying lane indices above threshold by the given offset
     353              :     void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1);
     354              :     /// @}
     355              : 
     356              : 
     357              :     /// @name Prunning the input
     358              :     /// @{
     359              : 
     360              :     /**@brief Removes edges which are both incoming and outgoing into this node
     361              :      *
     362              :      * If given, the connections to other edges participating in this node are updated
     363              :      *
     364              :      * @param[in, opt. changed] dc The districts container to update
     365              :      * @param[in, opt. changed] ec The edge container to remove the edges from
     366              :      * @param[in, opt. changed] tc The traffic lights container to update
     367              :      * @return The number of removed edges
     368              :      */
     369              :     int removeSelfLoops(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc);
     370              :     /// @}
     371              : 
     372              : 
     373              :     /// @name Applying offset
     374              :     /// @{
     375              :     /**@brief Applies an offset to the node
     376              :      * @param[in] xoff The x-offset to apply
     377              :      * @param[in] yoff The y-offset to apply
     378              :      */
     379              :     void reshiftPosition(double xoff, double yoff);
     380              : 
     381              :     /// @brief ensure consistency between input and output geometries
     382              :     void roundGeometry();
     383              : 
     384              :     /// @brief mirror coordinates along the x-axis
     385              :     void mirrorX();
     386              :     /// @}
     387              : 
     388              :     /// @brief adds an incoming edge
     389              :     void addIncomingEdge(NBEdge* edge);
     390              : 
     391              :     /// @brief adds an outgoing edge
     392              :     void addOutgoingEdge(NBEdge* edge);
     393              : 
     394              :     /// @brief computes the connections of lanes to edges
     395              :     void computeLanes2Lanes();
     396              : 
     397              :     /// @brief computes the node's type, logic and traffic light
     398              :     void computeLogic(const NBEdgeCont& ec);
     399              : 
     400              :     /// @brief compute right-of-way logic for all lane-to-lane connections
     401              :     void computeLogic2(bool checkLaneFoes);
     402              : 
     403              :     /// @brief compute keepClear status for all connections
     404              :     void computeKeepClear();
     405              : 
     406              :     /// @brief writes the XML-representation of the logic as a bitset-logic XML representation
     407              :     bool writeLogic(OutputDevice& into) const;
     408              : 
     409              :     /// @brief get the 'foes' string (conflict bit set) of the right-of-way logic
     410              :     const std::string getFoes(int linkIndex) const;
     411              : 
     412              :     /// @brief get the 'response' string (right-of-way bit set) of the right-of-way logic
     413              :     const std::string getResponse(int linkIndex) const;
     414              : 
     415              :     /// @brief whether there are conflicting streams of traffic at this node
     416              :     bool hasConflict() const;
     417              : 
     418              :     /// @brief whether the given edge has a conflicting stream of traffic at this node
     419              :     bool hasConflict(const NBEdge* e) const;
     420              : 
     421              :     /// @brief Returns something like the most unused direction Should only be used to add source or sink nodes
     422              :     Position getEmptyDir() const;
     423              : 
     424              :     /**@brief Returns whether the given edge ends at this node
     425              :      * @param[in] e The edge
     426              :      * @return Whether the given edge is one of this node's incoming edges
     427              :      */
     428              :     bool hasIncoming(const NBEdge* const e) const;
     429              : 
     430              :     /**@brief Returns whether the given edge starts at this node
     431              :      * @param[in] e The edge
     432              :      * @return Whether the given edge is one of this node's outgoing edges
     433              :      */
     434              :     bool hasOutgoing(const NBEdge* const e) const;
     435              : 
     436              :     /// @brief returns the opposite incoming edge of certain edge
     437              :     NBEdge* getOppositeIncoming(NBEdge* e) const;
     438              : 
     439              :     /// @brief invalidate incoming connections
     440              :     void invalidateIncomingConnections(bool reallowSetting = false);
     441              : 
     442              :     /// @brief invalidate outgoing connections
     443              :     void invalidateOutgoingConnections(bool reallowSetting = false);
     444              : 
     445              :     /// @brief remove duble edges
     446              :     void removeDoubleEdges();
     447              : 
     448              :     /// @brief get connection to certain node
     449              :     NBEdge* getConnectionTo(NBNode* n) const;
     450              : 
     451              :     /// @brief add shorted link FOES
     452              :     void addSortedLinkFoes(const NBConnection& mayDrive, const NBConnection& mustStop);
     453              : 
     454              :     /// @brief get possibly splitted incoming  edge
     455              :     NBEdge* getPossiblySplittedIncoming(const std::string& edgeid);
     456              : 
     457              :     /// @brief get possibly splitted outgoing edge
     458              :     NBEdge* getPossiblySplittedOutgoing(const std::string& edgeid);
     459              : 
     460              :     /// @brief Removes edge from this node and optionally removes connections as well
     461              :     void removeEdge(NBEdge* edge, bool removeFromConnections = true);
     462              : 
     463              :     /**@brief Computes whether the given connection is a left mover across the junction
     464              :      *
     465              :      * It is assumed, that it is a left-mover if the clockwise angle is lower
     466              :      *  than the counter-clockwise angle.
     467              :      *
     468              :      * @param[in] from The incoming edge (the begin of the connection)
     469              :      * @param[in] from The outgoing edge (the end of the connection)
     470              :      * @return Whether the described connection is a left-mover
     471              :      */
     472              :     bool isLeftMover(const NBEdge* const from, const NBEdge* const to) const;
     473              : 
     474              :     /**@brief Returns the information whether the described flow must let any other flow pass
     475              :      * @param[in] from The connection's start edge
     476              :      * @param[in] to The connection's end edge
     477              :      * @param[in] fromLane The lane the connection start at
     478              :      * @param[in] toLane The lane the connection ends at
     479              :      * @param[in] includePedCrossings Whether braking due to a pedestrian crossing counts
     480              :      * @return Whether the described connection must brake (has higher priorised foes)
     481              :      */
     482              :     bool mustBrake(const NBEdge* const from, const NBEdge* const to, int fromLane, int toLane, bool includePedCrossings) const;
     483              : 
     484              :     /**@brief Returns the information whether the described flow must brake for the given crossing
     485              :      * @param[in] from The connection's start edge
     486              :      * @param[in] to The connection's end edge
     487              :      * @param[in] crossing The pedestrian crossing to check
     488              :      * @return Whether the described connection must brake (has higher priorised foes)
     489              :      */
     490              :     bool mustBrakeForCrossing(const NBEdge* const from, const NBEdge* const to, const Crossing& crossing) const;
     491              : 
     492              :     /// @brief whether a connection to the given edge must brake for a crossing when leaving the intersection
     493              :     bool brakeForCrossingOnExit(const NBEdge* to, LinkDirection dir, bool indirect) const;
     494              : 
     495              :     /// @brief return whether the given laneToLane connection is a right turn which must yield to a bicycle crossings
     496              :     static bool rightTurnConflict(const NBEdge* from, const NBEdge* to, int fromLane,
     497              :                                   const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorFromLane);
     498              : 
     499              :     /// @brief whether one of multple connections from the same edge targeting the same lane must yield
     500              :     bool mergeConflictYields(const NBEdge* from, int fromLane, int fromLaneFoe, NBEdge* to, int toLane) const;
     501              : 
     502              :     /// @brief whether multiple connections from the same edge target the same lane
     503              :     bool mergeConflict(const NBEdge* from, const NBEdge::Connection& con,
     504              :                        const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
     505              : 
     506              :     /// @brief whether the foe connections is oncoming on the same lane
     507              :     bool bidiConflict(const NBEdge* from, const NBEdge::Connection& con,
     508              :                       const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
     509              : 
     510              :     bool zipperConflict(const NBEdge* incoming, const NBEdge* outgoing, int fromLane, int toLane) const;
     511              : 
     512              :     /// @brief return whether the given laneToLane connection originate from the same edge and are in conflict due to turning across each other
     513              :     bool turnFoes(const NBEdge* from, const NBEdge* to, int fromLane,
     514              :                   const NBEdge* from2, const NBEdge* to2, int fromLane2,
     515              :                   bool lefthand = false) const;
     516              : 
     517              :     /**@brief Returns the information whether "prohibited" flow must let "prohibitor" flow pass
     518              :      * @param[in] possProhibitedFrom The maybe prohibited connection's begin
     519              :      * @param[in] possProhibitedTo The maybe prohibited connection's end
     520              :      * @param[in] possProhibitorFrom The maybe prohibiting connection's begin
     521              :      * @param[in] possProhibitorTo The maybe prohibiting connection's end
     522              :      * @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
     523              :      * @return Whether the second flow prohibits the first one
     524              :      */
     525              :     bool forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
     526              :                  const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
     527              :                  bool regardNonSignalisedLowerPriority) const;
     528              : 
     529              :     /**@brief Returns the information whether the given flows cross
     530              :      * @param[in] from1 The starting edge of the first stream
     531              :      * @param[in] to1 The ending edge of the first stream
     532              :      * @param[in] from2 The starting edge of the second stream
     533              :      * @param[in] to2 The ending edge of the second stream
     534              :      * @return Whether both stream are foes (cross)
     535              :      */
     536              :     bool foes(const NBEdge* const from1, const NBEdge* const to1,
     537              :               const NBEdge* const from2, const NBEdge* const to2) const;
     538              : 
     539              :     /**@brief Returns the representation of the described stream's direction
     540              :      * @param[in] incoming The edge the stream starts at
     541              :      * @param[in] outgoing The edge the stream ends at
     542              :      * @param[in] leftHand Whether a lefthand network is being built. Should only be set at writing time
     543              :      * @return The direction of the stream
     544              :      */
     545              :     LinkDirection getDirection(const NBEdge* const incoming, const NBEdge* const outgoing, bool leftHand = false) const;
     546              : 
     547              :     /// @brief get link state
     548              :     LinkState getLinkState(const NBEdge* incoming, const NBEdge* outgoing,
     549              :                            int fromLane, int toLane, bool mayDefinitelyPass, const std::string& tlID) const;
     550              : 
     551              :     /**@brief Compute the junction shape for this node
     552              :      * @param[in] mismatchThreshold The threshold for warning about shapes which are away from myPosition
     553              :      */
     554              :     void computeNodeShape(double mismatchThreshold);
     555              : 
     556              :     /// @brief update geometry of node and surrounding edges
     557              :     void updateSurroundingGeometry();
     558              : 
     559              :     /// @brief retrieve the junction shape
     560              :     const PositionVector& getShape() const;
     561              : 
     562              :     /// @brief set the junction shape
     563              :     void setCustomShape(const PositionVector& shape);
     564              : 
     565              :     /// @brief reset node shape
     566              :     void resetShape() {
     567              :         myPoly.clear();
     568              :     }
     569              : 
     570              :     /// @brief set the turning radius
     571              :     void setRadius(double radius) {
     572           75 :         myRadius = radius;
     573           75 :     }
     574              : 
     575              :     /// @brief set the keepClear flag
     576              :     void setKeepClear(bool keepClear) {
     577            1 :         myKeepClear = keepClear;
     578            1 :     }
     579              : 
     580              :     /// @brief set method for computing right-of-way
     581              :     void setRightOfWay(RightOfWay rightOfWay) {
     582        31660 :         myRightOfWay = rightOfWay;
     583           13 :     }
     584              : 
     585              :     /// @brief set fringe type
     586              :     void setFringeType(FringeType fringeType) {
     587        31756 :         myFringeType = fringeType;
     588           98 :     }
     589              : 
     590              :     /// @brief set roundabout type
     591              :     void setRoundaboutType(RoundaboutType roundaboutType) {
     592        31647 :         myRoundaboutType = roundaboutType;
     593              :     }
     594              : 
     595              :     /// @brief set intersection name
     596              :     void setName(const std::string& name) {
     597            4 :         myName = name;
     598            4 :     }
     599              : 
     600              :     /// @brief return whether the shape was set by the user
     601              :     bool hasCustomShape() const {
     602        71319 :         return myHaveCustomPoly;
     603              :     }
     604              : 
     605              :     /// @brief check if node is removable
     606              :     bool checkIsRemovable() const;
     607              : 
     608              :     /// @brief check if node is removable and return reason if not
     609              :     bool checkIsRemovableReporting(std::string& reason) const;
     610              : 
     611              :     /// @brief get edges to join
     612              :     std::vector<std::pair<NBEdge*, NBEdge*> > getEdgesToJoin() const;
     613              : 
     614              :     /// @chech if node is near district
     615              :     bool isNearDistrict() const;
     616              : 
     617              :     /// @brief check if node is a district
     618              :     bool isDistrict() const;
     619              : 
     620              :     /// @brief whether an internal junction should be built at from and respect other
     621              :     bool needsCont(const NBEdge* fromE, const NBEdge* otherFromE,
     622              :                    const NBEdge::Connection& c, const NBEdge::Connection& otherC, bool checkOnlyTLS = false) const;
     623              : 
     624              :     /// @brief whether the connection must yield if the foe remains on the intersection after its phase ends
     625              :     bool tlsStrandedConflict(const NBEdge* from, const NBEdge::Connection& c,
     626              :                          const NBEdge* foeFrom, const NBEdge::Connection& foe) const;
     627              : 
     628              : 
     629              :     /**@brief Compute the shape for an internal lane
     630              :      * @param[in] fromE The starting edge
     631              :      * @param[in] con The connection for this internal lane
     632              :      * @param[in] numPoints The number of geometry points for the internal lane
     633              :      * @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
     634              :      * @return The shape of the internal lane
     635              :      */
     636              :     PositionVector computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& con, int numPoints, NBNode* recordError = 0, int shapeFlag = 0) const;
     637              : 
     638              :     /**@brief Compute a smooth curve between the given geometries
     639              :      * @param[in] begShape The geometry at the start
     640              :      * @param[in] endShape The geometry at the end
     641              :      * @param[in] numPoints The number of geometry points for the internal lane
     642              :      * @param[in] isTurnaround Whether this shall be the shape for a turnaround
     643              :      * @param[in] extrapolateBeg Extrapolation distance at the beginning
     644              :      * @param[in] extrapolateEnd Extrapolation distance at the end
     645              :      * @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
     646              :      * @return The shape of the internal lane
     647              :      */
     648              :     PositionVector computeSmoothShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints,
     649              :                                       bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
     650              :                                       NBNode* recordError = 0, int shapeFlag = 0) const;
     651              :     /// @brief get bezier control points
     652              :     static PositionVector bezierControlPoints(const PositionVector& begShape, const PositionVector& endShape,
     653              :             bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
     654              :             bool& ok, NBNode* recordError = 0, double straightThresh = DEG2RAD(5),
     655              :             int shapeFlag = 0);
     656              : 
     657              :     /// @brief compute shape of indirect left turn
     658              :     PositionVector indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const;
     659              : 
     660              :     /// @brief compute the displacement error during s-curve computation
     661              :     double getDisplacementError() const {
     662           32 :         return myDisplacementError;
     663              :     }
     664              : 
     665              :     /// @brief Replaces occurrences of the first edge within the list of incoming by the second Connections are remapped, too
     666              :     void replaceIncoming(NBEdge* which, NBEdge* by, int laneOff);
     667              : 
     668              :     /// @brief Replaces occurrences of every edge from the given list within the list of incoming by the second Connections are remapped, too
     669              :     void replaceIncoming(const EdgeVector& which, NBEdge* by);
     670              : 
     671              :     /// @brief Replaces occurrences of the first edge within the list of outgoing by the second Connections are remapped, too
     672              :     void replaceOutgoing(NBEdge* which, NBEdge* by, int laneOff);
     673              : 
     674              :     /// @brief Replaces occurrences of every edge from the given list within the list of outgoing by the second Connections are remapped, too
     675              :     void replaceOutgoing(const EdgeVector& which, NBEdge* by);
     676              : 
     677              :     /// @brief guess pedestrian crossings and return how many were guessed
     678              :     int guessCrossings();
     679              : 
     680              :     /* @brief check whether a crossing should be build for the candiate edges and build 0 to n crossings
     681              :      * @param[in] candidates The candidate vector of edges to be crossed
     682              :      * @param[in] checkOnly Whether only checking (of user supplied) crossings shall be performed
     683              :      * @return The number of crossings built
     684              :      * */
     685              :     int checkCrossing(EdgeVector candidates, bool checkOnly = false);
     686              : 
     687              :     /// @brief return true if there already exist a crossing with the same edges as the input
     688              :     bool checkCrossingDuplicated(EdgeVector edges);
     689              : 
     690              :     /// @brief build internal lanes, pedestrian crossings and walking areas
     691              :     double buildInnerEdges();
     692              : 
     693              :     /**@brief build pedestrian crossings
     694              :      * @return The next index for creating internal lanes
     695              :      **/
     696              :     int buildCrossings();
     697              : 
     698              :     /**@brief build pedestrian walking areas and set connections from/to walkingAreas
     699              :      * @param[in] cornerDetail The detail level when generating the inner curve
     700              :      */
     701              :     void buildWalkingAreas(int cornerDetail, double joinMinDist);
     702              : 
     703              :     /// @brief build crossing outlines after walkingareas are finished
     704              :     void buildCrossingOutlines();
     705              : 
     706              :     /// @brief build crossings, and walkingareas. Also removes invalid loaded crossings if wished
     707              :     void buildCrossingsAndWalkingAreas();
     708              : 
     709              :     /// @brief return all edges that lie clockwise between the given edges
     710              :     EdgeVector edgesBetween(const NBEdge* e1, const NBEdge* e2) const;
     711              : 
     712              :     /// @brief return true if the given edges are connected by a crossing
     713              :     bool crossingBetween(const NBEdge* e1, const NBEdge* e2) const;
     714              : 
     715              :     /// @brief return true if the given pedestrian paths are connected at another junction within dist
     716              :     bool alreadyConnectedPaths(const NBEdge* e1, const NBEdge* e2, double dist) const;
     717              : 
     718              :     /// @brief return true if the given sidewalks are separated by a fringe road
     719              :     bool crossesFringe(const NBEdge* e1, const NBEdge* e2) const;
     720              : 
     721              :     /// @brief get prohibitions (BLocked connections)
     722              :     const NBConnectionProhibits& getProhibitions() {
     723        56971 :         return myBlockedConnections;
     724              :     }
     725              : 
     726              :     /// @brief whether this is structurally similar to a geometry node
     727              :     bool geometryLike() const;
     728              :     static bool geometryLike(const EdgeVector& incoming, const EdgeVector& outgoing);
     729              : 
     730              :     /// @brief update the type of this node as a roundabout
     731              :     void setRoundabout();
     732              : 
     733              :     /// @brief return whether this node is part of a roundabout
     734              :     bool isRoundabout() const;
     735              : 
     736              :     /// @brief add a pedestrian crossing to this node
     737              :     NBNode::Crossing* addCrossing(EdgeVector edges, double width, bool priority, int tlIndex = -1, int tlIndex2 = -1,
     738              :                                   const PositionVector& customShape = PositionVector::EMPTY, bool fromSumoNet = false, const Parameterised* params = nullptr);
     739              : 
     740              :     /// @brief add custom shape for walkingArea
     741              :     void addWalkingAreaShape(EdgeVector edges, const PositionVector& shape, double width);
     742              : 
     743              :     /// @brief remove a pedestrian crossing from this node (identified by its edges)
     744              :     void removeCrossing(const EdgeVector& edges);
     745              : 
     746              :     /// @brief discard all current (and optionally future) crossings
     747              :     void discardAllCrossings(bool rejectAll);
     748              : 
     749              :     /// @brief discard previously built walkingareas (required for repeated computation by netedit)
     750              :     void discardWalkingareas();
     751              : 
     752              :     /// @brief get num of crossings from sumo net
     753              :     int numCrossingsFromSumoNet() const {
     754         1071 :         return myCrossingsLoadedFromSumoNet;
     755              :     }
     756              : 
     757              :     /// @brief return this junctions pedestrian crossings
     758              :     std::vector<Crossing*> getCrossings() const;
     759              :     inline const std::vector<std::unique_ptr<Crossing> >& getCrossingsIncludingInvalid() const {
     760              :         return myCrossings;
     761              :     }
     762              : 
     763              :     /// @brief return this junctions pedestrian walking areas
     764              :     inline const std::vector<WalkingArea>& getWalkingAreas() const {
     765              :         return myWalkingAreas;
     766              :     }
     767              : 
     768              :     const std::vector<WalkingAreaCustomShape>& getWalkingAreaCustomShapes() const {
     769              :         return myWalkingAreaCustomShapes;
     770              :     }
     771              : 
     772              :     /// @brief return the crossing with the given id
     773              :     Crossing* getCrossing(const std::string& id) const;
     774              : 
     775              :     /// @brief return the crossing with the given Edges
     776              :     Crossing* getCrossing(const EdgeVector& edges, bool hardFail = true) const;
     777              : 
     778              :     /// @brief return the walkingArea with the given ID
     779              :     WalkingArea& getWalkingArea(const std::string& id);
     780              : 
     781              :     /* @brief set tl indices of this nodes crossing starting at the given index
     782              :      * @return Whether a custom index was used
     783              :      */
     784              :     bool setCrossingTLIndices(const std::string& tlID, int startIndex, bool ignoreCustom = false);
     785              : 
     786              :     /// @brief return the number of lane-to-lane connections at this junction (excluding crossings)
     787              :     int numNormalConnections() const;
     788              : 
     789              :     /// @brief fix overlap
     790              :     void avoidOverlap();
     791              : 
     792              :     /// @brief whether the given index must yield to the foeIndex while turing right on a red light
     793              :     bool extraConflict(int index, int foeIndex) const;
     794              : 
     795              :     /// @brief sort all edge containers for this node
     796              :     void sortEdges(bool useNodeShape);
     797              : 
     798              :     /// @brief return the index of the given connection
     799              :     int getConnectionIndex(const NBEdge* from, const NBEdge::Connection& con) const;
     800              : 
     801              :     /**
     802              :      * @class nodes_by_id_sorter
     803              :      * @brief Used for sorting the cells by the begin time they describe
     804              :      */
     805              :     class nodes_by_id_sorter {
     806              :     public:
     807              :         /// @brief Constructor
     808              :         explicit nodes_by_id_sorter() { }
     809              : 
     810              :         /// @brief Comparing operator
     811              :         int operator()(NBNode* n1, NBNode* n2) const {
     812              :             return n1->getID() < n2->getID();
     813              :         }
     814              :     };
     815              : 
     816              :     /** @class edge_by_direction_sorter
     817              :      * @brief Sorts outgoing before incoming edges
     818              :      */
     819              :     class edge_by_direction_sorter {
     820              :     public:
     821              :         /// @brief constructor
     822              :         explicit edge_by_direction_sorter(NBNode* n) : myNode(n) {}
     823              : 
     824              :         /// @brief operator of selection
     825              :         int operator()(NBEdge* e1, NBEdge* e2) const {
     826              :             UNUSED_PARAMETER(e2);
     827              :             return e1->getFromNode() == myNode;
     828              :         }
     829              : 
     830              :     private:
     831              :         /// @brief The node to compute the relative angle of
     832              :         NBNode* myNode;
     833              : 
     834              :     };
     835              : 
     836              :     /// @brief return whether the given type is a traffic light
     837              :     static bool isTrafficLight(SumoXMLNodeType type);
     838              : 
     839              :     inline bool isTrafficLight() const {
     840         9495 :         return isTrafficLight(myType);
     841              :     }
     842              : 
     843              :     /// @brief check if node is a simple continuation
     844              :     bool isSimpleContinuation(bool checkLaneNumbers = true, bool checkWidth = false) const;
     845              : 
     846              :     /// @brief mark whether a priority road turns at this node
     847              :     void markBentPriority(bool isBent) {
     848        72897 :         myIsBentPriority = isBent;
     849        11397 :     }
     850              : 
     851              :     /// @brief return whether a priority road turns at this node
     852              :     bool isBentPriority() const {
     853        69383 :         return myIsBentPriority;
     854              :     }
     855              : 
     856              :     /// @brief return whether a priority road turns at this node
     857              :     bool typeWasGuessed() const {
     858         1419 :         return myTypeWasGuessed;
     859              :     }
     860              : 
     861              :     /// @brief detects whether a given junction splits or merges lanes while keeping constant road width
     862              :     bool isConstantWidthTransition() const;
     863              : 
     864              :     /// @brief return list of unique endpoint coordinates of all edges at this node
     865              :     std::vector<std::pair<Position, std::string> > getEndPoints() const;
     866              : 
     867              :     /// @brief ensure connectivity for all vClasses
     868              :     void recheckVClassConnections(NBEdge* currentOutgoing);
     869              : 
     870              :     /// @brief initialize signalized rail classes
     871              :     static void initRailSignalClasses(const NBNodeCont& nc);
     872              : 
     873              : private:
     874              :     /// @brief sets the priorites in case of a priority junction
     875              :     void setPriorityJunctionPriorities();
     876              : 
     877              :     /// @brief returns a list of edges which are connected to the given outgoing edge
     878              :     void getEdgesThatApproach(NBEdge* currentOutgoing, EdgeVector& approaching);
     879              : 
     880              :     /// @brief replace incoming connections prohibitions
     881              :     void replaceInConnectionProhibitions(NBEdge* which, NBEdge* by, int whichLaneOff, int byLaneOff);
     882              : 
     883              :     /// @brief remap removed
     884              :     void remapRemoved(NBTrafficLightLogicCont& tc, NBEdge* removed, const EdgeVector& incoming, const EdgeVector& outgoing);
     885              : 
     886              :     /// @brief return whether there is a non-sidewalk lane after the given index;
     887              :     bool forbidsPedestriansAfter(std::vector<std::pair<NBEdge*, bool> > normalizedLanes, int startIndex);
     888              : 
     889              :     /// @brief returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
     890              :     EdgeVector getEdgesSortedByAngleAtNodeCenter() const;
     891              : 
     892              :     /// @brief check if is long enough
     893              :     static bool isLongEnough(NBEdge* out, double minLength);
     894              : 
     895              :     /// @brief remove all traffic light definitions that are part of a joined tls
     896              :     void removeJoinedTrafficLights();
     897              : 
     898              :     /// @brief displace lane shapes to account for change in lane width at this node
     899              :     void displaceShapeAtWidthChange(const NBEdge* from, const NBEdge::Connection& con, PositionVector& fromShape, PositionVector& toShape) const;
     900              : 
     901              :     /// @brief returns whether sub is a subset of super
     902              :     static bool includes(const std::set<const NBEdge*, ComparatorIdLess>& super,
     903              :                          const std::set<const NBEdge*, ComparatorIdLess>& sub);
     904              : 
     905              :     NBEdge* getNextCompatibleOutgoing(const NBEdge* incoming, SVCPermissions vehPerm, EdgeVector::const_iterator start, bool clockwise) const;
     906              : 
     907              :     /// @brief get the reduction in driving lanes at this junction
     908              :     void getReduction(const NBEdge* in, const NBEdge* out, int& inOffset, int& inEnd, int& outOffset, int& outEnd, int& reduction) const;
     909              : 
     910              :     /// @brief helper function to add connections for unsatisfied modes
     911              :     SVCPermissions findToLaneForPermissions(NBEdge* currentOutgoing, int fromLane, NBEdge* incoming, SVCPermissions unsatisfied);
     912              : 
     913              :     /// @brief check whether this edge has extra lanes on the right side
     914              :     int addedLanesRight(NBEdge* out, int addedLanes) const;
     915              : 
     916              :     /// @brief check whether the candidate edge is more likely to be the straight continuation
     917              :     bool isStraighter(const NBEdge* const incoming, const double angle, const SVCPermissions vehPerm, const int modeLanes, const NBEdge* const candidate) const;
     918              : 
     919              :     /// @brief return edges that permit passengers (either incoming or outgoing)
     920              :     EdgeVector getPassengerEdges(bool incoming) const;
     921              : 
     922              :     /// @brief detect explict rail turns with potential geometry problem
     923              :     static bool isExplicitRailNoBidi(const NBEdge* incoming, const NBEdge* outgoing);
     924              : 
     925              :     /// @brief geometry helper that cuts the first shape where bordered by the other two
     926              :     PositionVector cutAtShapes(const PositionVector& cut, const PositionVector& border1, const PositionVector& border2, const PositionVector& def);
     927              : 
     928              :     /// @brief compute offset for centering path-across-street crossings
     929              :     void patchOffset_pathAcrossStreet(double& offset);
     930              : 
     931              :     /// @brief whether the given rail connections at this node may run in unsignalized (right-of-way) mode
     932              :     bool unsignalizedOperation() const;
     933              : 
     934              :     /// @brief ensure connectivity for all special vClass
     935              :     void recheckSpecialConnections(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial);
     936              : 
     937              :     /// @brief helper function for recheckSpecialConnections
     938              :     bool avoidConfict(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial, LinkDirection dir, int i);
     939              : 
     940              : private:
     941              :     /// @brief The position the node lies at
     942              :     Position myPosition;
     943              : 
     944              :     /// @brief Vector of incoming edges
     945              :     EdgeVector myIncomingEdges;
     946              : 
     947              :     /// @brief Vector of outgoing edges
     948              :     EdgeVector myOutgoingEdges;
     949              : 
     950              :     /// @brief Vector of incoming and outgoing edges
     951              :     EdgeVector myAllEdges;
     952              : 
     953              :     /// @brief Vector of crossings
     954              :     std::vector<std::unique_ptr<Crossing> > myCrossings;
     955              : 
     956              :     /// @brief Vector of walking areas
     957              :     std::vector<WalkingArea> myWalkingAreas;
     958              : 
     959              :     /// @brief Vector of custom walking areas shapes
     960              :     std::vector<WalkingAreaCustomShape> myWalkingAreaCustomShapes;
     961              : 
     962              :     /// @brief The type of the junction
     963              :     SumoXMLNodeType myType;
     964              : 
     965              :     /// @brief The container for connection block dependencies
     966              :     NBConnectionProhibits myBlockedConnections;
     967              : 
     968              :     /// @brief The district the node is the centre of
     969              :     NBDistrict* myDistrict;
     970              : 
     971              :     /// @brief the (outer) shape of the junction
     972              :     PositionVector myPoly;
     973              : 
     974              :     /// @brief whether this nodes shape was set by the user
     975              :     bool myHaveCustomPoly;
     976              : 
     977              :     /// @brief Node requests
     978              :     NBRequest* myRequest;
     979              : 
     980              :     /// @brief traffic lights of node
     981              :     std::set<NBTrafficLightDefinition*> myTrafficLights;
     982              : 
     983              :     /// @brief the turning radius (for all corners) at this node in m.
     984              :     double myRadius;
     985              : 
     986              :     /// @brief whether the junction area must be kept clear
     987              :     bool myKeepClear;
     988              : 
     989              :     /// @brief how to compute right of way for this node
     990              :     RightOfWay myRightOfWay;
     991              : 
     992              :     /// @brief fringe type of this node
     993              :     FringeType myFringeType;
     994              : 
     995              :     /// @brief roundabout type of this node
     996              :     RoundaboutType myRoundaboutType;
     997              : 
     998              :     /// @brief The intersection name (or whatever arbitrary string you wish to attach)
     999              :     std::string myName;
    1000              : 
    1001              :     /// @brief whether to discard all pedestrian crossings
    1002              :     bool myDiscardAllCrossings;
    1003              : 
    1004              :     /// @brief number of crossings loaded from a sumo net
    1005              :     int myCrossingsLoadedFromSumoNet;
    1006              : 
    1007              :     /// @brief geometry error after computation of internal lane shapes
    1008              :     double myDisplacementError;
    1009              : 
    1010              :     /* @brief whether this junction is a bent priority junction (main direction turns)
    1011              :      * @note see NBEdgePriorityComputer
    1012              :      */
    1013              :     bool myIsBentPriority;
    1014              : 
    1015              :     /// @brief whether the node type was guessed rather than loaded
    1016              :     bool myTypeWasGuessed;
    1017              : 
    1018              :     /// @brief all vehicle classes for which rail signals exist
    1019              :     static SVCPermissions myHaveRailSignalClasses;
    1020              : 
    1021              :     /// @brief all rail classes for which operation without rail signals is permitted
    1022              :     static SVCPermissions myPermitUnsignalizedClasses;
    1023              : 
    1024              : private:
    1025              :     /// @brief invalidated copy constructor
    1026              :     NBNode(const NBNode& s);
    1027              : 
    1028              :     /// @brief invalidated assignment operator
    1029              :     NBNode& operator=(const NBNode& s);
    1030              : };
        

Generated by: LCOV version 2.0-1