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

Generated by: LCOV version 2.0-1