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

Generated by: LCOV version 2.0-1