LCOV - code coverage report
Current view: top level - src/netbuild - NBEdge.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.7 % 97 88
Test Date: 2024-12-21 15:45:41 Functions: 64.7 % 17 11

            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    NBEdge.h
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Tue, 20 Nov 2001
      19              : ///
      20              : // The representation of a single edge during network building
      21              : /****************************************************************************/
      22              : #pragma once
      23              : #include <config.h>
      24              : 
      25              : #include <map>
      26              : #include <vector>
      27              : #include <string>
      28              : #include <set>
      29              : #include <cassert>
      30              : #include <utils/common/Named.h>
      31              : #include <utils/common/Parameterised.h>
      32              : #include <utils/common/UtilExceptions.h>
      33              : #include <utils/common/VectorHelper.h>
      34              : #include <utils/geom/Bresenham.h>
      35              : #include <utils/geom/PositionVector.h>
      36              : #include <utils/common/SUMOVehicleClass.h>
      37              : #include <utils/xml/SUMOXMLDefinitions.h>
      38              : #include "NBCont.h"
      39              : #include "NBHelpers.h"
      40              : #include "NBSign.h"
      41              : 
      42              : 
      43              : // ===========================================================================
      44              : // class declarations
      45              : // ===========================================================================
      46              : class NBNode;
      47              : class NBConnection;
      48              : class NBNodeCont;
      49              : class NBEdgeCont;
      50              : class OutputDevice;
      51              : class GNELane;
      52              : class NBVehicle;
      53              : 
      54              : 
      55              : // ===========================================================================
      56              : // class definitions
      57              : // ===========================================================================
      58              : /**
      59              :  * @class NBRouterEdge
      60              :  * @brief Superclass for NBEdge and NBEdge::Connection to initialize Router
      61              :  */
      62              : class NBRouterEdge {
      63              : public:
      64       109696 :     virtual ~NBRouterEdge() {}
      65              :     virtual const std::string& getID() const = 0;
      66              :     virtual double getSpeed() const = 0;
      67              :     virtual double getLength() const = 0;
      68              :     virtual const NBRouterEdge* getBidiEdge() const = 0;
      69              :     virtual int getNumericalID() const = 0;
      70              :     virtual const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const = 0;
      71            0 :     virtual bool isInternal() const {
      72            0 :         return false;
      73              :     }
      74              :     inline bool prohibits(const NBVehicle* const /*veh*/) const {
      75              :         return false;
      76              :     }
      77              :     inline bool restricts(const NBVehicle* const /*veh*/) const {
      78              :         return false;
      79              :     }
      80              : 
      81              : 
      82        59425 :     static inline double getTravelTimeStatic(const NBRouterEdge* const edge, const NBVehicle* const /*veh*/, double /*time*/) {
      83        59425 :         return edge->getLength() / edge->getSpeed();
      84              :     }
      85              : };
      86              : 
      87              : 
      88              : /**
      89              :  * @class NBEdge
      90              :  * @brief The representation of a single edge during network building
      91              :  */
      92              : class NBEdge : public Named, public Parameterised, public NBRouterEdge {
      93              :     friend class NBEdgeCont;
      94              : 
      95              :     /** used for visualization (netedit) */
      96              :     friend class GNELane;
      97              :     friend class GNEEdge;
      98              :     friend class GNEJunction;
      99              : 
     100              : public:
     101              : 
     102              :     /** @enum EdgeBuildingStep
     103              :      * @brief Current state of the edge within the building process
     104              :      *
     105              :      * As the network is build in a cascaded way, considering loaded
     106              :      *  information, a counter holding the current step is needed. This is done
     107              :      *  by using this enumeration.
     108              :      */
     109              :     enum class EdgeBuildingStep {
     110              :         /// @brief The edge has been loaded and connections shall not be added
     111              :         INIT_REJECT_CONNECTIONS,
     112              :         /// @brief The edge has been loaded, nothing is computed yet
     113              :         INIT,
     114              :         /// @brief The relationships between edges are computed/loaded
     115              :         EDGE2EDGES,
     116              :         /// @brief Lanes to edges - relationships are computed/loaded
     117              :         LANES2EDGES,
     118              :         /// @brief Lanes to lanes - relationships are computed; should be rechecked
     119              :         LANES2LANES_RECHECK,
     120              :         /// @brief Lanes to lanes - relationships are computed; no recheck is necessary/wished
     121              :         LANES2LANES_DONE,
     122              :         /// @brief Lanes to lanes - relationships are loaded; no recheck is necessary/wished
     123              :         LANES2LANES_USER
     124              :     };
     125              : 
     126              : 
     127              :     /** @enum Lane2LaneInfoType
     128              :     * @brief Modes of setting connections between lanes
     129              :     */
     130              :     enum class Lane2LaneInfoType {
     131              :         /// @brief The connection was computed
     132              :         COMPUTED,
     133              :         /// @brief The connection was given by the user
     134              :         USER,
     135              :         /// @brief The connection was computed and validated
     136              :         VALIDATED
     137              :     };
     138              : 
     139              : 
     140              :     /** @struct Lane
     141              :      * @brief An (internal) definition of a single lane of an edge
     142              :      */
     143              :     struct Lane final : public Parameterised {
     144              :         /// @brief constructor
     145              :         Lane(NBEdge* e, const std::string& _origID);
     146              : 
     147              :         /// @brief The lane's shape
     148              :         PositionVector shape;
     149              : 
     150              :         /// @brief The speed allowed on this lane
     151              :         double speed;
     152              : 
     153              :         /// @brief The friction on this lane
     154              :         double friction;
     155              : 
     156              :         /// @brief List of vehicle types that are allowed on this lane
     157              :         SVCPermissions permissions;
     158              : 
     159              :         /// @brief List of vehicle types that are preferred on this lane
     160              :         SVCPermissions preferred;
     161              : 
     162              :         /// @brief List of vehicle types that are allowed to change Left from this lane
     163              :         SVCPermissions changeLeft;
     164              : 
     165              :         /// @brief List of vehicle types that are allowed to change right from this lane
     166              :         SVCPermissions changeRight;
     167              : 
     168              :         /// @brief This lane's offset to the intersection begin
     169              :         double endOffset;
     170              : 
     171              :         /// @brief stopOffsets.second - The stop offset for vehicles stopping at the lane's end.
     172              :         ///        Applies if vClass is in in stopOffset.first bitset
     173              :         StopOffset laneStopOffset;
     174              : 
     175              :         /// @brief This lane's width
     176              :         double width;
     177              : 
     178              :         /// @brief An opposite lane ID, if given
     179              :         std::string oppositeID;
     180              : 
     181              :         /// @brief Whether this lane is an acceleration lane
     182              :         bool accelRamp;
     183              : 
     184              :         /// @brief Whether connection information for this lane is already completed
     185              :         // @note (see NIImporter_DlrNavteq::ConnectedLanesHandler)
     186              :         bool connectionsDone;
     187              : 
     188              :         /// @brief A custom shape for this lane set by the user
     189              :         PositionVector customShape;
     190              : 
     191              :         /// @brief the type of this lane
     192              :         std::string type;
     193              : 
     194              :         /// @brief turning signs printed on the road, bitset of LinkDirection (imported from OSM)
     195              :         int turnSigns = 0;
     196              :     };
     197              : 
     198              :     /** @struct Connection
     199              :      * @brief A structure which describes a connection between edges or lanes
     200              :      */
     201              :     struct Connection final : public Parameterised, public NBRouterEdge {
     202              :         /** @brief Constructor
     203              :          * @param[in] fromLane_ The lane the connections starts at
     204              :          * @param[in] toEdge_ The edge the connections yields in
     205              :          * @param[in] toLane_ The lane the connections yields in
     206              :          */
     207              :         Connection(int fromLane_, NBEdge* toEdge_, int toLane_, const bool mayDefinitelyPass_ = false);
     208              : 
     209              :         /// @brief The lane the connections starts at
     210              :         int fromLane;
     211              : 
     212              :         /// @brief The edge the connections yields in
     213              :         NBEdge* toEdge;
     214              : 
     215              :         /// @brief The lane the connections yields in
     216              :         int toLane;
     217              : 
     218              :         /// @brief The id of the traffic light that controls this connection
     219              :         std::string tlID;
     220              : 
     221              :         /// @brief The index of this connection within the controlling traffic light
     222              :         int tlLinkIndex = -1;
     223              : 
     224              :         /// @brief The index of the internal junction within the controlling traffic light (optional)
     225              :         int tlLinkIndex2 = -1;
     226              : 
     227              :         /// @brief Information about being definitely free to drive (on-ramps)
     228              :         bool mayDefinitelyPass;
     229              : 
     230              :         /// @brief whether the junction must be kept clear when using this connection
     231              :         KeepClear keepClear = KEEPCLEAR_UNSPECIFIED;
     232              : 
     233              :         /// @brief custom position for internal junction on this connection
     234              :         double contPos = UNSPECIFIED_CONTPOS;
     235              : 
     236              :         /// @brief custom foe visiblity for connection
     237              :         double visibility = UNSPECIFIED_VISIBILITY_DISTANCE;
     238              : 
     239              :         /// @brief custom speed for connection
     240              :         double speed = UNSPECIFIED_SPEED;
     241              : 
     242              :         // @brief custom friction for connection
     243              :         double friction = UNSPECIFIED_FRICTION;
     244              : 
     245              :         /// @brief custom length for connection
     246              :         double customLength;
     247              : 
     248              :         /// @brief custom shape for connection
     249              :         PositionVector customShape;
     250              : 
     251              :         /// @brief List of vehicle types that are allowed on this connection
     252              :         SVCPermissions permissions = SVC_UNSPECIFIED;
     253              : 
     254              :         /// @brief List of vehicle types that are allowed to change Left from this connections internal lane(s)
     255              :         SVCPermissions changeLeft = SVC_UNSPECIFIED;
     256              : 
     257              :         /// @brief List of vehicle types that are allowed to change right from this connections internal lane(s)
     258              :         SVCPermissions changeRight = SVC_UNSPECIFIED;
     259              : 
     260              :         /// @brief Whether this connection is an indirect left turn
     261              :         bool indirectLeft = false;
     262              : 
     263              :         /// @brief optional type of Connection
     264              :         std::string edgeType;
     265              : 
     266              :         /// @brief id of Connection
     267              :         std::string id;
     268              : 
     269              :         /// @brief shape of Connection
     270              :         PositionVector shape;
     271              : 
     272              :         /// @brief maximum velocity
     273              :         double vmax = UNSPECIFIED_SPEED;
     274              : 
     275              :         /// @brief check if Connection have a Via
     276              :         bool haveVia = false;
     277              : 
     278              :         /// @brief if Connection have a via, ID of it
     279              :         std::string viaID;
     280              : 
     281              :         /// @brief shape of via
     282              :         PositionVector viaShape;
     283              : 
     284              :         /// @brief the length of the via shape (maybe customized)
     285              :         double viaLength = 0.;
     286              : 
     287              :         /// @brief FOE Internal links
     288              :         std::vector<int> foeInternalLinks;
     289              : 
     290              :         /// @brief FOE Incomings lanes
     291              :         std::vector<std::string> foeIncomingLanes;
     292              : 
     293              :         /// @brief The lane index of this internal lane within the internal edge
     294              :         int internalLaneIndex = UNSPECIFIED_INTERNAL_LANE_INDEX;
     295              :         int internalViaLaneIndex = 0;
     296              : 
     297              :         /// @brief check if Connection is uncontrolled
     298              :         bool uncontrolled = false;
     299              : 
     300              :         /// @brief get ID of internal lane
     301              :         std::string getInternalLaneID() const;
     302              : 
     303              :         /// @brief get ID of internal lane (second part)
     304              :         std::string getInternalViaLaneID() const;
     305              : 
     306              :         /// @brief get string describing this connection
     307              :         std::string getDescription(const NBEdge* parent) const;
     308              : 
     309              :         /// @brief computed length (average of all internal lane shape lengths that share an internal edge)
     310              :         double length = UNSPECIFIED_LOADED_LENGTH;
     311              : 
     312              :         /// @name NBRouterEdge interface
     313              :         /// @{
     314              :         static ConstRouterEdgePairVector myViaSuccessors; // always empty
     315            0 :         const std::string& getID() const {
     316            0 :             return id;
     317              :         }
     318        17716 :         double getSpeed() const {
     319        17716 :             return vmax;
     320              :         }
     321              :         // @brief needed for NBRouterEdge
     322        35432 :         double getLength() const {
     323        78533 :             return shape.length() + viaShape.length();
     324              :         }
     325            0 :         int getNumericalID() const {
     326            0 :             throw ProcessError("NBEdge::Connection does not implement getNumericalID()");
     327              :         }
     328            0 :         const Connection* getBidiEdge() const {
     329            0 :             return nullptr;
     330              :         }
     331        17716 :         bool isInternal() const {
     332        17716 :             return true;
     333              :         }
     334        17716 :         const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const {
     335              :             UNUSED_PARAMETER(vClass);
     336              :             UNUSED_PARAMETER(ignoreTransientPermissions);
     337        17716 :             return myViaSuccessors;
     338              :         }
     339              :         /// }@
     340              :     };
     341              : 
     342              :     /// @brief Dummy edge to use when a reference must be supplied in the no-arguments constructor (FOX technicality)
     343              :     static NBEdge DummyEdge;
     344              : 
     345              :     /// @brief unspecified lane width
     346              :     static const double UNSPECIFIED_WIDTH;
     347              : 
     348              :     /// @brief unspecified lane offset
     349              :     static const double UNSPECIFIED_OFFSET;
     350              : 
     351              :     /// @brief unspecified lane speed
     352              :     static const double UNSPECIFIED_SPEED;
     353              : 
     354              :     /// @brief unspecified lane friction
     355              :     static const double UNSPECIFIED_FRICTION;
     356              : 
     357              :     /// @brief unspecified internal junction position
     358              :     static const double UNSPECIFIED_CONTPOS;
     359              : 
     360              :     /// @brief unspecified foe visibility for connections
     361              :     static const double UNSPECIFIED_VISIBILITY_DISTANCE;
     362              : 
     363              :     /// @brief no length override given
     364              :     static const double UNSPECIFIED_LOADED_LENGTH;
     365              : 
     366              :     /// @brief unspecified signal offset
     367              :     static const double UNSPECIFIED_SIGNAL_OFFSET;
     368              : 
     369              :     /// @brief the distance at which to take the default angle
     370              :     static const double ANGLE_LOOKAHEAD;
     371              : 
     372              :     /// @brief internal lane computation not yet done
     373              :     static const int UNSPECIFIED_INTERNAL_LANE_INDEX;
     374              : 
     375              :     /// @brief TLS-controlled despite its node controlled not specified.
     376              :     static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED;
     377              : 
     378              :     /// @brief shift values for decoding turn signs
     379              :     static const int TURN_SIGN_SHIFT_BUS = 8;
     380              :     static const int TURN_SIGN_SHIFT_TAXI = 16;
     381              :     static const int TURN_SIGN_SHIFT_BICYCLE = 24;
     382              : 
     383              :     /// @brief junction priority values set by setJunctionPriority
     384              :     enum JunctionPriority {
     385              :         MINOR_ROAD = 0,
     386              :         PRIORITY_ROAD = 1,
     387              :         ROUNDABOUT = 1000
     388              :     };
     389              : 
     390              :     static void setDefaultConnectionLength(double length) {
     391         1992 :         myDefaultConnectionLength = length;
     392              :     }
     393              : 
     394              : public:
     395              :     /** @brief Constructor
     396              :      *
     397              :      * Use this if no edge geometry is given.
     398              :      *
     399              :      * @param[in] id The id of the edge
     400              :      * @param[in] from The node the edge starts at
     401              :      * @param[in] to The node the edge ends at
     402              :      * @param[in] type The type of the edge (my be =="")
     403              :      * @param[in] speed The maximum velocity allowed on this edge
     404              :      * @param[in] friction The current friction coefficient on this edge
     405              :      * @param[in] nolanes The number of lanes this edge has
     406              :      * @param[in] priority This edge's priority
     407              :      * @param[in] width This edge's lane width
     408              :      * @param[in] endOffset Additional offset to the destination node
     409              :      * @param[in] spread How the lateral offset of the lanes shall be computed
     410              :      * @param[in] streetName The street name (need not be unique)
     411              :      * @see init
     412              :      * @see LaneSpreadFunction
     413              :      */
     414              :     NBEdge(const std::string& id,
     415              :            NBNode* from, NBNode* to, std::string type,
     416              :            double speed, double friction, int nolanes, int priority,
     417              :            double width, double endOffset,
     418              :            LaneSpreadFunction spread,
     419              :            const std::string& streetName = "");
     420              : 
     421              :     /** @brief Constructor
     422              :      *
     423              :      * Use this if the edge's geometry is given.
     424              :      *
     425              :      * @param[in] id The id of the edge
     426              :      * @param[in] from The node the edge starts at
     427              :      * @param[in] to The node the edge ends at
     428              :      * @param[in] type The type of the edge (may be =="")
     429              :      * @param[in] speed The maximum velocity allowed on this edge
     430              :      * @param[in] friction The current friction coefficient on this edge
     431              :      * @param[in] nolanes The number of lanes this edge has
     432              :      * @param[in] priority This edge's priority
     433              :      * @param[in] width This edge's lane width
     434              :      * @param[in] endOffset Additional offset to the destination node
     435              :      * @param[in] geom The edge's geomatry
     436              :      * @param[in] spread How the lateral offset of the lanes shall be computed
     437              :      * @param[in] streetName The street name (need not be unique)
     438              :      * @param[in] origID The original ID in the source network (need not be unique)
     439              :      * @param[in] spread How the lateral offset of the lanes shall be computed
     440              :      * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2
     441              :      * @see init
     442              :      */
     443              :     NBEdge(const std::string& id,
     444              :            NBNode* from, NBNode* to, std::string type,
     445              :            double speed, double friction, int nolanes, int priority,
     446              :            double width, double endOffset,
     447              :            PositionVector geom,
     448              :            LaneSpreadFunction spread,
     449              :            const std::string& streetName = "",
     450              :            const std::string& origID = "",
     451              :            bool tryIgnoreNodePositions = false);
     452              : 
     453              :     /** @brief Constructor
     454              :      *
     455              :      * Use this to copy attributes from another edge
     456              :      *
     457              :      * @param[in] id The id of the edge
     458              :      * @param[in] from The node the edge starts at
     459              :      * @param[in] to The node the edge ends at
     460              :      * @param[in] tpl The template edge to copy attributes from
     461              :      * @param[in] geom The geometry to use (may be empty)
     462              :      * @param[in] numLanes The number of lanes of the new edge (copy from tpl by default)
     463              :      */
     464              :     NBEdge(const std::string& id,
     465              :            NBNode* from, NBNode* to,
     466              :            const NBEdge* tpl,
     467              :            const PositionVector& geom = PositionVector(),
     468              :            int numLanes = -1);
     469              : 
     470              :     /// @brief Destructor
     471              :     ~NBEdge();
     472              : 
     473              : 
     474              :     /** @brief Resets initial values
     475              :      *
     476              :      * @param[in] from The node the edge starts at
     477              :      * @param[in] to The node the edge ends at
     478              :      * @param[in] type The type of the edge (may be =="")
     479              :      * @param[in] speed The maximum velocity allowed on this edge
     480              :      * @param[in] nolanes The number of lanes this edge has
     481              :      * @param[in] priority This edge's priority
     482              :      * @param[in] geom The edge's geomatry
     483              :      * @param[in] width This edge's lane width
     484              :      * @param[in] endOffset Additional offset to the destination node
     485              :      * @param[in] streetName The street name (need not be unique)
     486              :      * @param[in] spread How the lateral offset of the lanes shall be computed
     487              :      * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2
     488              :      */
     489              :     void reinit(NBNode* from, NBNode* to, const std::string& type,
     490              :                 double speed, double friction, int nolanes, int priority,
     491              :                 PositionVector geom, double width, double endOffset,
     492              :                 const std::string& streetName,
     493              :                 LaneSpreadFunction spread,
     494              :                 bool tryIgnoreNodePositions = false);
     495              : 
     496              :     /** @brief Resets nodes but keeps all other values the same (used when joining)
     497              :      * @param[in] from The node the edge starts at
     498              :      * @param[in] to The node the edge ends at
     499              :      */
     500              :     void reinitNodes(NBNode* from, NBNode* to);
     501              : 
     502              :     /// @name Applying offset
     503              :     /// @{
     504              :     /** @brief Applies an offset to the edge
     505              :      * @param[in] xoff The x-offset to apply
     506              :      * @param[in] yoff The y-offset to apply
     507              :      */
     508              :     void reshiftPosition(double xoff, double yoff);
     509              : 
     510              :     /// @brief mirror coordinates along the x-axis
     511              :     void mirrorX();
     512              :     /// @}
     513              : 
     514              :     /// @name Atomar getter methods
     515              :     //@{
     516              : 
     517              :     /** @brief Returns the number of lanes
     518              :      * @returns This edge's number of lanes
     519              :      */
     520              :     int getNumLanes() const {
     521      4891414 :         return (int)myLanes.size();
     522              :     }
     523              : 
     524              :     /** @brief Returns the priority of the edge
     525              :      * @return This edge's priority
     526              :      */
     527              :     int getPriority() const {
     528       666543 :         return myPriority;
     529              :     }
     530              : 
     531              :     /// @brief Sets the priority of the edge
     532              :     void setPriority(int priority) {
     533           14 :         myPriority = priority;
     534          126 :     }
     535              : 
     536              :     /** @brief Returns the origin node of the edge
     537              :      * @return The node this edge starts at
     538              :      */
     539              :     inline NBNode* getFromNode() const {
     540      7886745 :         return myFrom;
     541              :     }
     542              : 
     543              :     /** @brief Returns the destination node of the edge
     544              :      * @return The node this edge ends at
     545              :      */
     546              :     inline NBNode* getToNode() const {
     547      7978476 :         return myTo;
     548              :     }
     549              : 
     550              :     /** @brief Returns the angle at the start of the edge
     551              :      * (relative to the node shape center)
     552              :      * The angle is computed in computeAngle()
     553              :      * @return This edge's start angle
     554              :      */
     555              :     inline double getStartAngle() const {
     556      1000330 :         return myStartAngle;
     557              :     }
     558              : 
     559              :     /** @brief Returns the angle at the end of the edge
     560              :      * (relative to the node shape center)
     561              :      * The angle is computed in computeAngle()
     562              :      * @return This edge's end angle
     563              :      */
     564              :     inline double getEndAngle() const {
     565       193834 :         return myEndAngle;
     566              :     }
     567              : 
     568              :     /** @brief Returns the angle at the start of the edge
     569              :      * @note only using edge shape
     570              :      * @return This edge's start angle
     571              :      */
     572              :     double getShapeStartAngle() const;
     573              : 
     574              : 
     575              :     /** @brief Returns the angle at the end of the edge
     576              :      * @note only using edge shape
     577              :      * @note The angle is computed in computeAngle()
     578              :      * @return This edge's end angle
     579              :      */
     580              :     double getShapeEndAngle() const;
     581              : 
     582              :     /** @brief Returns the angle at the start of the edge
     583              :      * @note The angle is computed in computeAngle()
     584              :      * @return This edge's angle
     585              :      */
     586              :     inline double getTotalAngle() const {
     587          314 :         return myTotalAngle;
     588              :     }
     589              : 
     590              :     /** @brief Returns the computed length of the edge
     591              :      * @return The edge's computed length
     592              :      */
     593       193822 :     double getLength() const {
     594       193822 :         return myLength;
     595              :     }
     596              : 
     597              : 
     598              :     /** @brief Returns the length was set explicitly or the computed length if it wasn't set
     599              :      * @todo consolidate use of myLength and myLoaded length
     600              :      * @return The edge's specified length
     601              :      */
     602              :     double getLoadedLength() const {
     603       236106 :         return myLoadedLength > 0 ? myLoadedLength : myLength;
     604              :     }
     605              : 
     606              :     /// @brief get length that will be assigned to the lanes in the final network
     607              :     double getFinalLength() const;
     608              : 
     609              :     /** @brief Returns whether a length was set explicitly
     610              :      * @return Wether the edge's length was specified
     611              :      */
     612              :     bool hasLoadedLength() const {
     613       142163 :         return myLoadedLength > 0;
     614              :     }
     615              : 
     616              :     /** @brief Returns the speed allowed on this edge
     617              :      * @return The maximum speed allowed on this edge
     618              :      */
     619       798888 :     double getSpeed() const {
     620       798888 :         return mySpeed;
     621              :     }
     622              : 
     623              :     /** @brief Returns the friction on this edge
     624              :     * @return The friction on this edge
     625              :     */
     626              :     double getFriction() const {
     627       146227 :         return myFriction;
     628              :     }
     629              : 
     630              :     /** @brief The building step of this edge
     631              :      * @return The current building step for this edge
     632              :      * @todo Recheck usage!
     633              :      * @see EdgeBuildingStep
     634              :      */
     635              :     EdgeBuildingStep getStep() const {
     636      1736314 :         return myStep;
     637              :     }
     638              : 
     639              :     /** @brief Returns the default width of lanes of this edge
     640              :      * @return The width of lanes of this edge
     641              :      */
     642              :     double getLaneWidth() const {
     643      3041710 :         return myLaneWidth;
     644              :     }
     645              : 
     646              :     /** @brief Returns the width of the lane of this edge
     647              :      * @return The width of the lane of this edge
     648              :      */
     649              :     double getLaneWidth(int lane) const;
     650              : 
     651              :     /** @brief Returns the width of the internal lane associated with the connection
     652              :      * @param[in] node The node for which this edge is an incoming one
     653              :      * @param[in] connection The connection from this edge to the successor lane
     654              :      * @param[in] successor The outgoing lane of the connection
     655              :      * @param[in] isVia Whether it is computing the Via stage
     656              :      * @return The width of the internal lane
     657              :      * @todo validity checks
     658              :      */
     659              :     double getInternalLaneWidth(
     660              :         const NBNode& node,
     661              :         const NBEdge::Connection& connection,
     662              :         const NBEdge::Lane& successor,
     663              :         bool isVia) const;
     664              : 
     665              :     /// @brief Returns the combined width of all lanes of this edge
     666              :     double getTotalWidth() const;
     667              : 
     668              :     /// @brief Returns the street name of this edge
     669              :     const std::string& getStreetName() const {
     670        45594 :         return myStreetName;
     671              :     }
     672              : 
     673              :     /// @brief sets the street name of this edge
     674              :     void setStreetName(const std::string& name) {
     675              :         myStreetName = name;
     676              :     }
     677              : 
     678              :     /// @brief get distance
     679              :     double getDistance() const {
     680       109150 :         return myDistance;
     681              :     }
     682              : 
     683              :     /// @brief get distance at the given offset
     684              :     double getDistancAt(double pos) const;
     685              : 
     686              :     /** @brief Returns the offset to the destination node
     687              :      * @return The offset to the destination node
     688              :      */
     689              :     double getEndOffset() const {
     690       187337 :         return myEndOffset;
     691              :     }
     692              : 
     693              :     /** @brief Returns the offset to the destination node a the specified lane
     694              :      * @return The offset to the destination node
     695              :      */
     696              :     double getEndOffset(int lane) const;
     697              : 
     698              :     /** @brief Returns the stopOffset to the end of the edge
     699              :      * @return The offset to the end of the edge
     700              :      */
     701              :     const StopOffset& getEdgeStopOffset() const;
     702              : 
     703              :     /** @brief Returns the stop offset to the specified lane's end
     704              :      * @return The stop offset to the specified lane's end
     705              :      */
     706              :     const StopOffset& getLaneStopOffset(int lane) const;
     707              : 
     708              :     /// @brief Returns the offset of a traffic signal from the end of this edge
     709              :     double getSignalOffset() const;
     710              : 
     711              :     /// @brief Returns the position of a traffic signal on this edge
     712              :     const Position& getSignalPosition() const {
     713              :         return mySignalPosition;
     714              :     }
     715              : 
     716              :     /// @brief Returns the node that (possibly) represents a traffic signal controlling at the end of this edge
     717              :     const NBNode* getSignalNode() const {
     718          172 :         return mySignalNode;
     719              :     }
     720              : 
     721              :     /// @brief sets the offset of a traffic signal from the end of this edge
     722              :     void setSignalPosition(const Position& pos, const NBNode* signalNode) {
     723         1427 :         mySignalPosition = pos;
     724         1338 :         mySignalNode = signalNode;
     725           89 :     }
     726              : 
     727              :     /** @brief Returns the lane definitions
     728              :      * @return The stored lane definitions
     729              :      */
     730              :     const std::vector<NBEdge::Lane>& getLanes() const {
     731              :         return myLanes;
     732              :     }
     733              :     //@}
     734              : 
     735              :     /** @brief return the first lane with permissions other than SVC_PEDESTRIAN and 0
     736              :      * @param[in] direction The direction in which the lanes shall be checked
     737              :      * @param[in] exclusive Whether lanes that allow pedestrians along with other classes shall be counted as non-pedestrian
     738              :      */
     739              :     int getFirstNonPedestrianLaneIndex(int direction, bool exclusive = false) const;
     740              : 
     741              :     /** @brief return the first lane with permissions other than SVC_PEDESTRIAN, SVC_BICYCLE and 0
     742              :      * @param[in] direction The direction in which the lanes shall be checked
     743              :      * @param[in] exclusive Whether lanes that allow pedestrians along with other classes shall be counted as non-pedestrian
     744              :      */
     745              :     int getFirstNonPedestrianNonBicycleLaneIndex(int direction, bool exclusive = false) const;
     746              : 
     747              :     /// @brief return index of the first lane that allows the given permissions
     748              :     int getSpecialLane(SVCPermissions permissions) const;
     749              : 
     750              :     /** @brief return the first lane that permits at least 1 vClass or the last lane if search direction of there is no such lane
     751              :      * @param[in] direction The direction in which the lanes shall be checked
     752              :      */
     753              :     int getFirstAllowedLaneIndex(int direction) const;
     754              : 
     755              :     /// @brif get first non-pedestrian lane
     756              :     NBEdge::Lane getFirstNonPedestrianLane(int direction) const;
     757              : 
     758              :     /// @brief return all permission variants within the specified lane range [iStart, iEnd[
     759              :     std::set<SVCPermissions> getPermissionVariants(int iStart, int iEnd) const;
     760              : 
     761              :     /* @brief get lane indices that allow the given permissions
     762              :      * @param[in] allPermissions: whether all the given permissions must be allowed (or just some of them)
     763              :      */
     764              :     int getNumLanesThatAllow(SVCPermissions permissions, bool allPermissions = true) const;
     765              : 
     766              :     /** @brief Returns whether the given vehicle class may change left from this lane */
     767              :     bool allowsChangingLeft(int lane, SUMOVehicleClass vclass) const;
     768              : 
     769              :     /** @brief Returns whether the given vehicle class may change left from this lane */
     770              :     bool allowsChangingRight(int lane, SUMOVehicleClass vclass) const;
     771              : 
     772              :     /// @brief return the angle for computing pedestrian crossings at the given node
     773              :     double getCrossingAngle(NBNode* node);
     774              : 
     775              :     /// @brief get the lane id for the canonical sidewalk lane
     776              :     std::string getSidewalkID();
     777              : 
     778              :     /// @name Edge geometry access and computation
     779              :     //@{
     780              :     /** @brief Returns the geometry of the edge
     781              :      * @return The edge's geometry
     782              :      */
     783              :     const PositionVector& getGeometry() const {
     784      1703308 :         return myGeom;
     785              :     }
     786              : 
     787              :     /// @brief Returns the geometry of the edge without the endpoints
     788              :     const PositionVector getInnerGeometry() const;
     789              : 
     790              :     /// @brief Returns whether the geometry consists only of the node positions
     791              :     bool hasDefaultGeometry() const;
     792              : 
     793              :     /** @brief Returns whether the geometry is terminated by the node positions
     794              :      * This default may be violated by initializing with
     795              :      * tryIgnoreNodePositions=true' or with setGeometry()
     796              :      * non-default endpoints are useful to control the generated node shape
     797              :      */
     798              :     bool hasDefaultGeometryEndpoints() const;
     799              : 
     800              :     /** @brief Returns whether the geometry is terminated by the node positions
     801              :      * This default may be violated by initializing with
     802              :      * tryIgnoreNodePositions=true' or with setGeometry()
     803              :      * non-default endpoints are useful to control the generated node shape
     804              :      */
     805              :     bool hasDefaultGeometryEndpointAtNode(const NBNode* node) const;
     806              : 
     807              :     Position getEndpointAtNode(const NBNode* node) const;
     808              : 
     809              :     void resetEndpointAtNode(const NBNode* node);
     810              : 
     811              :     /** @brief (Re)sets the edge's geometry
     812              :      *
     813              :      * Replaces the edge's prior geometry by the given. Then, computes
     814              :      *  the geometries of all lanes using computeLaneShapes.
     815              :      * Definitely not the best way to have it accessable from outside...
     816              :      * @param[in] g The edge's new geometry
     817              :      * @param[in] inner whether g should be interpreted as inner points
     818              :      * @todo Recheck usage, disallow access
     819              :      * @see computeLaneShapes
     820              :      */
     821              :     void setGeometry(const PositionVector& g, bool inner = false);
     822              : 
     823              :     /** @brief Adds a further geometry point
     824              :      *
     825              :      * Some importer do not know an edge's geometry when it is initialised.
     826              :      *  This method allows to insert further geometry points after the edge
     827              :      *  has been built.
     828              :      *
     829              :      * @param[in] index The position at which the point shall be added
     830              :      * @param[in] p The point to add
     831              :      */
     832              :     void addGeometryPoint(int index, const Position& p);
     833              : 
     834              :     /// @brief linearly extend the geometry at the given node
     835              :     void extendGeometryAtNode(const NBNode* node, double maxExtent);
     836              : 
     837              :     /// @brief linearly extend the geometry at the given node
     838              :     void shortenGeometryAtNode(const NBNode* node, double reduction);
     839              : 
     840              :     /// @brief shift geometry at the given node to avoid overlap
     841              :     void shiftPositionAtNode(NBNode* node, NBEdge* opposite);
     842              : 
     843              :     /// @brief return position taking into account loaded length
     844              :     Position geometryPositionAtOffset(double offset) const;
     845              : 
     846              :     /** @brief Recomputeds the lane shapes to terminate at the node shape
     847              :      * For every lane the intersection with the fromNode and toNode is
     848              :      * calculated and the lane shorted accordingly. The edge length is then set
     849              :      * to the average of all lane lengths (which may differ). This average length is used as the lane
     850              :      * length when writing the network.
     851              :      * @note All lanes of an edge in a sumo net must have the same nominal length
     852              :      *  but may differ in actual geomtric length.
     853              :      * @note Depends on previous call to NBNodeCont::computeNodeShapes
     854              :      */
     855              :     void computeEdgeShape(double smoothElevationThreshold = -1);
     856              : 
     857              :     /** @brief Returns the shape of the nth lane
     858              :      * @return The shape of the lane given by its index (counter from right)
     859              :      */
     860              :     const PositionVector& getLaneShape(int i) const;
     861              : 
     862              :     /** @brief (Re)sets how the lanes lateral offset shall be computed
     863              :      * @param[in] spread The type of lateral offset to apply
     864              :      * @see LaneSpreadFunction
     865              :      */
     866              :     void setLaneSpreadFunction(LaneSpreadFunction spread);
     867              : 
     868              :     /** @brief Returns how this edge's lanes' lateral offset is computed
     869              :      * @return The type of lateral offset that is applied on this edge
     870              :      * @see LaneSpreadFunction
     871              :      */
     872              :     LaneSpreadFunction getLaneSpreadFunction() const;
     873              : 
     874              :     /** @brief Removes points with a distance lesser than the given
     875              :      * @param[in] minDist The minimum distance between two position to keep the second
     876              :      */
     877              :     void reduceGeometry(const double minDist);
     878              : 
     879              :     /** @brief Check the angles of successive geometry segments
     880              :      * @param[in] maxAngle The maximum angle allowed
     881              :      * @param[in] minRadius The minimum turning radius allowed at the start and end
     882              :      * @param[in] fix Whether to prune geometry points to avoid sharp turns at start and end
     883              :      */
     884              :     void checkGeometry(const double maxAngle, bool fixAngle, const double minRadius, bool fix, bool silent);
     885              :     //@}
     886              : 
     887              :     /// @name Setting and getting connections
     888              :     /// @{
     889              :     /** @brief Adds a connection to another edge
     890              :      *
     891              :      * If the given edge does not start at the node this edge ends on, false is returned.
     892              :      *
     893              :      * All other cases return true. Though, a connection may not been added if this edge
     894              :      *  is in step "INIT_REJECT_CONNECTIONS". Also, this method assures that a connection
     895              :      *  to an edge is set only once, no multiple connections to next edge are stored.
     896              :      *
     897              :      * After a first connection to an edge was set, the process step is set to "EDGE2EDGES".
     898              :      * @note Passing 0 implicitly removes all existing connections
     899              :      *
     900              :      * @param[in] dest The connection's destination edge
     901              :      * @return Whether the connection was valid
     902              :      */
     903              :     bool addEdge2EdgeConnection(NBEdge* dest, bool overrideRemoval = false, SVCPermissions permission = SVC_UNSPECIFIED);
     904              : 
     905              :     /** @brief Adds a connection between the specified this edge's lane and an approached one
     906              :      *
     907              :      * If the given edge does not start at the node this edge ends on, false is returned.
     908              :      *
     909              :      * All other cases return true. Though, a connection may not been added if this edge
     910              :      *  is in step "INIT_REJECT_CONNECTIONS". Before the lane-to-lane connection is set,
     911              :      *  a connection between edges is established using "addEdge2EdgeConnection". Then,
     912              :      *  "setConnection" is called for inserting the lane-to-lane connection.
     913              :      *
     914              :      * @param[in] fromLane The connection's starting lane (of this edge)
     915              :      * @param[in] dest The connection's destination edge
     916              :      * @param[in] toLane The connection's destination lane
     917              :      * @param[in] type The connections's type
     918              :      * @param[in] mayUseSameDestination Whether this connection may be set though connecting an already connected lane
     919              :      * @param[in] mayDefinitelyPass Whether this connection is definitely undistrubed (special case for on-ramps)
     920              :      * @return Whether the connection was added / exists
     921              :      * @see addEdge2EdgeConnection
     922              :      * @see setConnection
     923              :      * @todo Check difference between "setConnection" and "addLane2LaneConnection"
     924              :      */
     925              :     bool addLane2LaneConnection(int fromLane, NBEdge* dest,
     926              :                                 int toLane, Lane2LaneInfoType type,
     927              :                                 bool mayUseSameDestination = false,
     928              :                                 bool mayDefinitelyPass = false,
     929              :                                 KeepClear keepClear = KEEPCLEAR_UNSPECIFIED,
     930              :                                 double contPos = UNSPECIFIED_CONTPOS,
     931              :                                 double visibility = UNSPECIFIED_VISIBILITY_DISTANCE,
     932              :                                 double speed = UNSPECIFIED_SPEED,
     933              :                                 double friction = UNSPECIFIED_FRICTION,
     934              :                                 double length = myDefaultConnectionLength,
     935              :                                 const PositionVector& customShape = PositionVector::EMPTY,
     936              :                                 const bool uncontrolled = UNSPECIFIED_CONNECTION_UNCONTROLLED,
     937              :                                 SVCPermissions permissions = SVC_UNSPECIFIED,
     938              :                                 const bool indirectLeft = false,
     939              :                                 const std::string& edgeType = "",
     940              :                                 SVCPermissions changeLeft = SVC_UNSPECIFIED,
     941              :                                 SVCPermissions changeRight = SVC_UNSPECIFIED,
     942              :                                 bool postProcess = false);
     943              : 
     944              :     /** @brief Builds no connections starting at the given lanes
     945              :      *
     946              :      * If "invalidatePrevious" is true, a call to "invalidateConnections(true)" is done.
     947              :      * This method loops through the given connections to set, calling "addLane2LaneConnection"
     948              :      *  for each.
     949              :      *
     950              :      * @param[in] fromLane The first of the connections' starting lanes (of this edge)
     951              :      * @param[in] dest The connections' destination edge
     952              :      * @param[in] toLane The first of the connections' destination lanes
     953              :      * @param[in] no The number of connections to set
     954              :      * @param[in] type The connections' type
     955              :      * @param[in] invalidatePrevious Whether previously set connection shall be deleted
     956              :      * @param[in] mayDefinitelyPass Whether these connections are definitely undistrubed (special case for on-ramps)
     957              :      * @return Whether the connections were added / existed
     958              :      * @see addLane2LaneConnection
     959              :      * @see invalidateConnections
     960              :      */
     961              :     bool addLane2LaneConnections(int fromLane,
     962              :                                  NBEdge* dest, int toLane, int no,
     963              :                                  Lane2LaneInfoType type, bool invalidatePrevious = false,
     964              :                                  bool mayDefinitelyPass = false);
     965              : 
     966              :     /** @brief Adds a connection to a certain lane of a certain edge
     967              :      *
     968              :      * @param[in] lane The connection's starting lane (of this edge)
     969              :      * @param[in] destEdge The connection's destination edge
     970              :      * @param[in] destLane The connection's destination lane
     971              :      * @param[in] type The connections's type
     972              :      * @param[in] mayUseSameDestination Whether this connection may be set though connecting an already connected lane
     973              :      * @param[in] mayDefinitelyPass Whether this connection is definitely undistrubed (special case for on-ramps)
     974              :      * @todo Check difference between "setConnection" and "addLane2LaneConnection"
     975              :      */
     976              :     bool setConnection(int lane, NBEdge* destEdge,
     977              :                        int destLane,
     978              :                        Lane2LaneInfoType type,
     979              :                        bool mayUseSameDestination = false,
     980              :                        bool mayDefinitelyPass = false,
     981              :                        KeepClear keepClear = KEEPCLEAR_UNSPECIFIED,
     982              :                        double contPos = UNSPECIFIED_CONTPOS,
     983              :                        double visibility = UNSPECIFIED_VISIBILITY_DISTANCE,
     984              :                        double speed = UNSPECIFIED_SPEED,
     985              :                        double friction = UNSPECIFIED_FRICTION,
     986              :                        double length = myDefaultConnectionLength,
     987              :                        const PositionVector& customShape = PositionVector::EMPTY,
     988              :                        const bool uncontrolled = UNSPECIFIED_CONNECTION_UNCONTROLLED,
     989              :                        SVCPermissions permissions = SVC_UNSPECIFIED,
     990              :                        bool indirectLeft = false,
     991              :                        const std::string& edgeType = "",
     992              :                        SVCPermissions changeLeft = SVC_UNSPECIFIED,
     993              :                        SVCPermissions changeRight = SVC_UNSPECIFIED,
     994              :                        bool postProcess = false);
     995              : 
     996              :     /** @brief Returns connections from a given lane
     997              :      *
     998              :      * This method goes through "myConnections" and copies those which are
     999              :      *  starting at the given lane.
    1000              :      * @param[in] lane The lane which connections shall be returned
    1001              :      * @param[in] to The target Edge (ignore nullptr)
    1002              :      * @param[in] toLane The target lane (ignore if > 0)
    1003              :      * @return The connections from the given lane
    1004              :      * @see NBEdge::Connection
    1005              :      */
    1006              :     std::vector<Connection> getConnectionsFromLane(int lane, const NBEdge* to = nullptr, int toLane = -1) const;
    1007              : 
    1008              :     /** @brief Returns the specified connection (unmodifiable)
    1009              :      * This method goes through "myConnections" and returns the specified one
    1010              :      * @see NBEdge::Connection
    1011              :      */
    1012              :     const Connection& getConnection(int fromLane, const NBEdge* to, int toLane) const;
    1013              : 
    1014              :     /** @brief Returns reference to the specified connection
    1015              :      * This method goes through "myConnections" and returns the specified one
    1016              :      * @see NBEdge::Connection
    1017              :      */
    1018              :     Connection& getConnectionRef(int fromLane, const NBEdge* to, int toLane);
    1019              : 
    1020              :     /** @brief Retrieves info about a connection to a certain lane of a certain edge
    1021              :      *
    1022              :      * Turnaround edge is ignored!
    1023              :      * @param[in] destEdge The connection's destination edge
    1024              :      * @param[in] destLane The connection's destination lane
    1025              :      * @param[in] fromLane If a value >= 0 is given, only return true if a connection from the given lane exists
    1026              :      * @return whether a connection to the specified lane exists
    1027              :      */
    1028              :     bool hasConnectionTo(const NBEdge* destEdge, int destLane, int fromLane = -1) const;
    1029              : 
    1030              :     /** @brief Returns the information whethe a connection to the given edge has been added (or computed)
    1031              :      *
    1032              :      * @param[in] e The destination edge
    1033              :      * @param[in] ignoreTurnaround flag to ignore or not Turnaround
    1034              :      * @return Whether a connection to the specified edge exists
    1035              :      */
    1036              :     bool isConnectedTo(const NBEdge* e, const bool ignoreTurnaround = false) const;
    1037              : 
    1038              :     /** @brief Returns the connections
    1039              :      * @return This edge's connections to following edges
    1040              :      */
    1041              :     const std::vector<Connection>& getConnections() const {
    1042              :         return myConnections;
    1043              :     }
    1044              : 
    1045              :     /** @brief Returns the connections
    1046              :      * @return This edge's connections to following edges
    1047              :      */
    1048              :     std::vector<Connection>& getConnections() {
    1049       147443 :         return myConnections;
    1050              :     }
    1051              : 
    1052              :     /** @brief Returns the list of outgoing edges without the turnaround sorted in clockwise direction
    1053              :      * @return Connected edges, sorted clockwise
    1054              :      */
    1055              :     const EdgeVector* getConnectedSorted();
    1056              : 
    1057              :     /** @brief Returns the list of outgoing edges unsorted
    1058              :      * @return Connected edges
    1059              :      */
    1060              :     EdgeVector getConnectedEdges() const;
    1061              : 
    1062              :     /** @brief Returns the list of incoming edges unsorted
    1063              :      * @return Connected predecessor edges
    1064              :      */
    1065              :     EdgeVector getIncomingEdges() const;
    1066              : 
    1067              :     /** @brief Returns the list of lanes that may be used to reach the given edge
    1068              :      * @return Lanes approaching the given edge
    1069              :      */
    1070              :     std::vector<int> getConnectionLanes(NBEdge* currentOutgoing, bool withBikes = true) const;
    1071              : 
    1072              :     /// @brief sorts the outgoing connections by their angle relative to their junction
    1073              :     void sortOutgoingConnectionsByAngle();
    1074              : 
    1075              :     /// @brief sorts the outgoing connections by their from-lane-index and their to-lane-index
    1076              :     void sortOutgoingConnectionsByIndex();
    1077              : 
    1078              :     /** @brief Remaps the connection in a way that allows the removal of it
    1079              :      *
    1080              :      * This edge (which is a self loop edge, in fact) connections are spread over the valid incoming edges
    1081              :      * @todo recheck!
    1082              :      */
    1083              :     void remapConnections(const EdgeVector& incoming);
    1084              : 
    1085              :     /** @brief Removes the specified connection(s)
    1086              :      * @param[in] toEdge The destination edge
    1087              :      * @param[in] fromLane The lane from which connections shall be removed; -1 means remove all
    1088              :      * @param[in] toLane   The lane to which connections shall be removed; -1 means remove all
    1089              :      * @param[in] tryLater If the connection does not exist, try again during recheckLanes()
    1090              :      * @param[in] adaptToLaneRemoval we are in the process of removing a complete lane, adapt all connections accordingly
    1091              :      */
    1092              :     void removeFromConnections(NBEdge* toEdge, int fromLane = -1, int toLane = -1, bool tryLater = false, const bool adaptToLaneRemoval = false, const bool keepPossibleTurns = false);
    1093              : 
    1094              :     /// @brief remove an existent connection of edge
    1095              :     bool removeFromConnections(const NBEdge::Connection& connectionToRemove);
    1096              : 
    1097              :     /// @brief invalidate current connections of edge
    1098              :     void invalidateConnections(bool reallowSetting = false);
    1099              : 
    1100              :     /// @brief replace in current connections of edge
    1101              :     void replaceInConnections(NBEdge* which, NBEdge* by, int laneOff);
    1102              : 
    1103              :     /// @brief replace in current connections of edge
    1104              :     void replaceInConnections(NBEdge* which, const std::vector<NBEdge::Connection>& origConns);
    1105              : 
    1106              :     /// @brief copy connections from antoher edge
    1107              :     void copyConnectionsFrom(NBEdge* src);
    1108              : 
    1109              :     /// @brief modifify the toLane for all connections to the given edge
    1110              :     void shiftToLanesToEdge(NBEdge* to, int laneOff);
    1111              :     /// @}
    1112              : 
    1113              :     /** @brief Returns whether the given edge is the opposite direction to this edge
    1114              :      * @param[in] edge The edge which may be the turnaround direction
    1115              :      * @return Whether the given edge is this edge's turnaround direction
    1116              :      * (regardless of whether a connection exists)
    1117              :      */
    1118              :     bool isTurningDirectionAt(const NBEdge* const edge) const;
    1119              : 
    1120              :     /** @brief Sets the turing destination at the given edge
    1121              :      * @param[in] e The turn destination
    1122              :      * @param[in] onlyPossible If true, only sets myPossibleTurnDestination
    1123              :      */
    1124              :     void setTurningDestination(NBEdge* e, bool onlyPossible = false);
    1125              : 
    1126              :     /// @name Setting/getting special types
    1127              :     /// @{
    1128              :     /// @brief Marks this edge as a macroscopic connector
    1129              :     void setAsMacroscopicConnector() {
    1130            0 :         myAmMacroscopicConnector = true;
    1131              :     }
    1132              : 
    1133              :     /** @brief Returns whether this edge was marked as a macroscopic connector
    1134              :      * @return Whether this edge was marked as a macroscopic connector
    1135              :      */
    1136              :     bool isMacroscopicConnector() const {
    1137        89892 :         return myAmMacroscopicConnector;
    1138              :     }
    1139              : 
    1140              :     /// @brief Marks this edge being within an intersection
    1141              :     void setInsideTLS(bool inside) {
    1142        14761 :         myAmInTLS = inside;
    1143              :     }
    1144              : 
    1145              :     /** @brief Returns whether this edge was marked as being within an intersection
    1146              :      * @return Whether this edge was marked as being within an intersection
    1147              :      */
    1148              :     bool isInsideTLS() const {
    1149        76589 :         return myAmInTLS;
    1150              :     }
    1151              :     /// @}
    1152              : 
    1153              :     /** @brief Sets the junction priority of the edge
    1154              :      * @param[in] node The node for which the edge's priority is given
    1155              :      * @param[in] prio The edge's new priority at this node
    1156              :      * @todo Maybe the edge priority whould be stored in the node
    1157              :      */
    1158              :     void setJunctionPriority(const NBNode* const node, int prio);
    1159              : 
    1160              :     /** @brief Returns the junction priority (normalised for the node currently build)
    1161              :      *
    1162              :      * If the given node is neither the edge's start nor the edge's ending node, the behaviour
    1163              :      *  is undefined.
    1164              :      *
    1165              :      * @param[in] node The node for which the edge's priority shall be returned
    1166              :      * @return The edge's priority at the given node
    1167              :      * @todo Maybe the edge priority whould be stored in the node
    1168              :      */
    1169              :     int getJunctionPriority(const NBNode* const node) const;
    1170              : 
    1171              :     /// @brief set loaded length
    1172              :     void setLoadedLength(double val);
    1173              : 
    1174              :     /// @brief patch average lane length in regard to the opposite edge
    1175              :     void setAverageLengthWithOpposite(double val);
    1176              : 
    1177              :     /// @brief dimiss vehicle class information
    1178              :     void dismissVehicleClassInformation();
    1179              : 
    1180              :     /// @brief get ID of type
    1181              :     const std::string& getTypeID() const {
    1182       309112 :         return myType;
    1183              :     }
    1184              : 
    1185              :     /// @brief whether at least one lane has values differing from the edges values
    1186              :     bool needsLaneSpecificOutput() const;
    1187              : 
    1188              :     /// @brief whether at least one lane has restrictions
    1189              :     bool hasPermissions() const;
    1190              : 
    1191              :     /// @brief whether lanes differ in allowed vehicle classes
    1192              :     bool hasLaneSpecificPermissions() const;
    1193              : 
    1194              :     /// @brief whether lanes differ in speed
    1195              :     bool hasLaneSpecificSpeed() const;
    1196              : 
    1197              :     /// @brief whether lanes differ in friction
    1198              :     bool hasLaneSpecificFriction() const;
    1199              : 
    1200              :     /// @brief whether lanes differ in width
    1201              :     bool hasLaneSpecificWidth() const;
    1202              : 
    1203              :     /// @brief whether lanes differ in type
    1204              :     bool hasLaneSpecificType() const;
    1205              : 
    1206              :     /// @brief whether lanes differ in offset
    1207              :     bool hasLaneSpecificEndOffset() const;
    1208              : 
    1209              :     /// @brief whether lanes differ in stopOffsets
    1210              :     bool hasLaneSpecificStopOffsets() const;
    1211              : 
    1212              :     /// @brief whether one of the lanes is an acceleration lane
    1213              :     bool hasAccelLane() const;
    1214              : 
    1215              :     /// @brief whether one of the lanes has a custom shape
    1216              :     bool hasCustomLaneShape() const;
    1217              : 
    1218              :     /// @brief whether one of the lanes has parameters set
    1219              :     bool hasLaneParams() const;
    1220              : 
    1221              :     /// @brief whether one of the lanes prohibits lane changing
    1222              :     bool prohibitsChanging() const;
    1223              : 
    1224              :     /// @brief computes the edge (step1: computation of approached edges)
    1225              :     bool computeEdge2Edges(bool noLeftMovers);
    1226              : 
    1227              :     /// @brief computes the edge, step2: computation of which lanes approach the edges)
    1228              :     bool computeLanes2Edges();
    1229              : 
    1230              :     /// @brief recheck whether all lanes within the edge are all right and optimises the connections once again
    1231              :     bool recheckLanes();
    1232              : 
    1233              :     /** @brief Add a connection to the previously computed turnaround, if wished
    1234              :      * and a turning direction exists (myTurnDestination!=0)
    1235              :      * @param[in] noTLSControlled Whether the turnaround shall not be connected if the edge is controlled by a tls
    1236              :      * @param[in] noFringe Whether the turnaround shall not be connected if the junction is at the (outer) fringe
    1237              :      * @param[in] onlyDeadends Whether the turnaround shall only be built at deadends
    1238              :      * @param[in] onlyTurnlane Whether the turnaround shall only be built when there is an exclusive (left) turn lane
    1239              :      * @param[in] noGeometryLike Whether the turnaround shall be built at geometry-like nodes
    1240              :      */
    1241              :     void appendTurnaround(bool noTLSControlled, bool noFringe, bool onlyDeadends, bool onlyTurnlane, bool noGeometryLike, bool checkPermissions);
    1242              : 
    1243              :     /** @brief Returns the node at the given edges length (using an epsilon)
    1244              :         @note When no node is existing at the given position, 0 is returned
    1245              :         The epsilon is a static member of NBEdge, should be setable via program options */
    1246              :     NBNode* tryGetNodeAtPosition(double pos, double tolerance = 5.0) const;
    1247              : 
    1248              :     /// @brief get max lane offset
    1249              :     double getMaxLaneOffset();
    1250              : 
    1251              :     /// @brief Check if lanes were assigned
    1252              :     bool lanesWereAssigned() const;
    1253              : 
    1254              :     /// @brief return true if certain connection must be controlled by TLS
    1255              :     bool mayBeTLSControlled(int fromLane, NBEdge* toEdge, int toLane) const;
    1256              : 
    1257              :     /// @brief Returns if the link could be set as to be controlled
    1258              :     bool setControllingTLInformation(const NBConnection& c, const std::string& tlID);
    1259              : 
    1260              :     /// @brief clears tlID for all connections
    1261              :     void clearControllingTLInformation();
    1262              : 
    1263              :     /// @brief get the outer boundary of this edge when going clock-wise around the given node
    1264              :     PositionVector getCWBoundaryLine(const NBNode& n) const;
    1265              : 
    1266              :     /// @brief get the outer boundary of this edge when going counter-clock-wise around the given node
    1267              :     PositionVector getCCWBoundaryLine(const NBNode& n) const;
    1268              : 
    1269              :     /// @brief Check if Node is expandable
    1270              :     bool expandableBy(NBEdge* possContinuation, std::string& reason) const;
    1271              : 
    1272              :     /// @brief append another edge
    1273              :     void append(NBEdge* continuation);
    1274              : 
    1275              :     /// @brief Check if edge has signalised connections
    1276              :     bool hasSignalisedConnectionTo(const NBEdge* const e) const;
    1277              : 
    1278              :     /// @brief move outgoing connection
    1279              :     void moveOutgoingConnectionsFrom(NBEdge* e, int laneOff);
    1280              : 
    1281              :     /* @brief return the turn destination if it exists
    1282              :      * @param[in] possibleDestination Wether myPossibleTurnDestination should be returned if no turnaround connection
    1283              :      * exists
    1284              :      */
    1285              :     NBEdge* getTurnDestination(bool possibleDestination = false) const;
    1286              : 
    1287              :     /// @brief get lane ID
    1288              :     std::string getLaneID(int lane) const;
    1289              : 
    1290              :     /// @brief get lane speed
    1291              :     double getLaneSpeed(int lane) const;
    1292              : 
    1293              :     /// @brief get lane friction of specified lane
    1294              :     double getLaneFriction(int lane) const;
    1295              : 
    1296              :     /// @brief Check if edge is near enought to be joined to another edge
    1297              :     bool isNearEnough2BeJoined2(NBEdge* e, double threshold) const;
    1298              : 
    1299              :     /** @brief Returns the angle of the edge's geometry at the given node
    1300              :      *
    1301              :      * The angle is in degrees between -180 and 180.
    1302              :      * @param[in] node The node for which the edge's angle shall be returned
    1303              :      * @return This edge's angle at the given node
    1304              :      */
    1305              :     double getAngleAtNode(const NBNode* const node) const;
    1306              : 
    1307              :     /** @brief Returns the angle of the edge's geometry at the given node
    1308              :      * and disregards edge direction
    1309              :      * @param[in] node The node for which the edge's angle shall be returned
    1310              :      * @return This edge's angle at the given node (normalized to point towards the node)
    1311              :      */
    1312              :     double getAngleAtNodeNormalized(const NBNode* const node) const;
    1313              : 
    1314              :     /** @brief Returns the angle of from the node shape center to where the edge meets
    1315              :      * the node shape
    1316              :      *
    1317              :      * The angle is signed, disregards direction, and starts at 12 o'clock
    1318              :      *  (north->south), proceeds positive clockwise.
    1319              :      * @param[in] node The node for which the edge's angle shall be returned
    1320              :      * @return This edge's angle at the given node shape
    1321              :      */
    1322              :     double getAngleAtNodeToCenter(const NBNode* const node) const;
    1323              : 
    1324              :     /// @brief increment lane
    1325              :     void incLaneNo(int by);
    1326              : 
    1327              :     /// @brief decrement lane
    1328              :     void decLaneNo(int by);
    1329              : 
    1330              :     /// @brief delete lane
    1331              :     void deleteLane(int index, bool recompute, bool shiftIndices);
    1332              : 
    1333              :     /// @brief add lane
    1334              :     void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices);
    1335              : 
    1336              :     /// @brief mark edge as in lane to state lane
    1337              :     void markAsInLane2LaneState();
    1338              : 
    1339              :     /// @brief add a pedestrian sidewalk of the given width and shift existing connctions
    1340              :     void addSidewalk(double width);
    1341              : 
    1342              :     /// @brief restore an previously added sidewalk
    1343              :     void restoreSidewalk(std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections);
    1344              : 
    1345              :     /// add a bicycle lane of the given width and shift existing connctions
    1346              :     void addBikeLane(double width);
    1347              : 
    1348              :     /// @brief restore an previously added BikeLane
    1349              :     void restoreBikelane(std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections);
    1350              : 
    1351              :     /// @brief add a lane of the given width, restricted to the given class and shift existing connections
    1352              :     void addRestrictedLane(double width, SUMOVehicleClass vclass);
    1353              : 
    1354              :     /// @brief set allowed/disallowed classes for the given lane or for all lanes if -1 is given
    1355              :     void setPermissions(SVCPermissions permissions, int lane = -1);
    1356              : 
    1357              :     /// @brief set preferred Vehicle Class
    1358              :     void setPreferredVehicleClass(SVCPermissions permissions, int lane = -1);
    1359              : 
    1360              :     /// @brief set allowed classes for changing to the left and right from the given lane
    1361              :     void setPermittedChanging(int lane, SVCPermissions changeLeft, SVCPermissions changeRight);
    1362              : 
    1363              :     /// @brief set allowed class for the given lane or for all lanes if -1 is given
    1364              :     void allowVehicleClass(int lane, SUMOVehicleClass vclass);
    1365              : 
    1366              :     /// @brief set disallowed class for the given lane or for all lanes if -1 is given
    1367              :     void disallowVehicleClass(int lane, SUMOVehicleClass vclass);
    1368              : 
    1369              :     /// @brief prefer certain vehicle classes for the given lane or for all lanes if -1 is given (ensures also permissions)
    1370              :     void preferVehicleClass(int lane, SVCPermissions vclasses);
    1371              : 
    1372              :     /// @brief set lane specific width (negative lane implies set for all lanes)
    1373              :     void setLaneWidth(int lane, double width);
    1374              : 
    1375              :     /// @brief set lane specific type (negative lane implies set for all lanes)
    1376              :     void setLaneType(int lane, const std::string& type);
    1377              : 
    1378              :     /// @brief set lane specific end-offset (negative lane implies set for all lanes)
    1379              :     void setEndOffset(int lane, double offset);
    1380              : 
    1381              :     /// @brief set lane specific speed (negative lane implies set for all lanes)
    1382              :     void setSpeed(int lane, double speed);
    1383              : 
    1384              :     /// @brief set lane specific friction (negative lane implies set for all lanes)
    1385              :     void setFriction(int lane, double friction);
    1386              : 
    1387              :     /// @brief set lane and vehicle class specific stopOffset (negative lane implies set for all lanes)
    1388              :     /// @return Whether given stop offset was applied.
    1389              :     bool setEdgeStopOffset(int lane, const StopOffset& offset, bool overwrite = false);
    1390              : 
    1391              :     /// @brief marks one lane as acceleration lane
    1392              :     void setAcceleration(int lane, bool accelRamp);
    1393              : 
    1394              :     /// @brief marks this edge has being an offRamp or leading to one (used for connection computation)
    1395              :     void markOffRamp(bool isOffRamp) {
    1396        75716 :         myIsOffRamp = isOffRamp;
    1397              :     }
    1398              : 
    1399              :     bool isOffRamp() const {
    1400          547 :         return myIsOffRamp;
    1401              :     }
    1402              : 
    1403              :     /// @brief sets a custom lane shape
    1404              :     void setLaneShape(int lane, const PositionVector& shape);
    1405              : 
    1406              :     /// @brief get the union of allowed classes over all lanes or for a specific lane
    1407              :     SVCPermissions getPermissions(int lane = -1) const;
    1408              : 
    1409              :     /// @brief set origID for all lanes or for a specific lane
    1410              :     void setOrigID(const std::string origID, const bool append, const int laneIdx = -1);
    1411              : 
    1412              :     /// @brief set kilometrage at start of edge (negative value implies couting down along the edge)
    1413              :     void setDistance(double distance) {
    1414        89407 :         myDistance = distance;
    1415            3 :     }
    1416              : 
    1417              :     /// @brief mark this edge as a bidi edge
    1418              :     void setBidi(bool isBidi) {
    1419        41351 :         myIsBidi = isBidi;
    1420        22973 :     }
    1421              : 
    1422              :     /// @brief return whether this edge should be a bidi edge
    1423              :     bool isBidi() {
    1424          153 :         return myIsBidi;
    1425              :     }
    1426              : 
    1427              :     // @brief returns a reference to the internal structure for the convenience of netedit
    1428              :     Lane& getLaneStruct(int lane) {
    1429              :         assert(lane >= 0);
    1430              :         assert(lane < (int)myLanes.size());
    1431         9819 :         return myLanes[lane];
    1432              :     }
    1433              : 
    1434              :     // @brief returns a reference to the internal structure for the convenience of netedit
    1435              :     const Lane& getLaneStruct(int lane) const {
    1436              :         assert(lane >= 0);
    1437              :         assert(lane < (int)myLanes.size());
    1438       149648 :         return myLanes[lane];
    1439              :     }
    1440              : 
    1441              :     /// @brief declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has no connections intentionally.
    1442              :     void declareConnectionsAsLoaded(EdgeBuildingStep step = EdgeBuildingStep::LANES2LANES_USER) {
    1443        23655 :         myStep = step;
    1444           32 :     }
    1445              : 
    1446              :     /* @brief fill connection attributes shape, viaShape, ...
    1447              :      *
    1448              :      * @param[in,out] edgeIndex The number of connections already handled
    1449              :      * @param[in,out] splitIndex The number of via edges already built
    1450              :      * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2
    1451              :      */
    1452              :     double buildInnerEdges(const NBNode& n, int noInternalNoSplits, int& linkIndex, int& splitIndex);
    1453              : 
    1454              :     /// @brief get Signs
    1455              :     inline const std::vector<NBSign>& getSigns() const {
    1456              :         return mySigns;
    1457              :     }
    1458              : 
    1459              :     /// @brief add Sign
    1460              :     inline void addSign(NBSign sign) {
    1461            8 :         mySigns.push_back(sign);
    1462            8 :     }
    1463              : 
    1464              :     /// @brief cut shape at the intersection shapes
    1465              :     PositionVector cutAtIntersection(const PositionVector& old) const;
    1466              : 
    1467              :     /// @brief Set Node border
    1468              :     void setNodeBorder(const NBNode* node, const Position& p, const Position& p2, bool rectangularCut);
    1469              :     const PositionVector& getNodeBorder(const NBNode* node) const;
    1470              :     void resetNodeBorder(const NBNode* node);
    1471              : 
    1472              :     /// @brief whether this edge is part of a bidirectional railway
    1473              :     bool isBidiRail(bool ignoreSpread = false) const;
    1474              : 
    1475              :     /// @brief whether this edge is part of a bidirectional edge pair
    1476              :     bool isBidiEdge(bool checkPotential = false) const;
    1477              : 
    1478              :     /// @brief whether this edge is a railway edge that does not continue
    1479              :     bool isRailDeadEnd() const;
    1480              : 
    1481              :     /// @brief debugging helper to print all connections
    1482              :     void debugPrintConnections(bool outgoing = true, bool incoming = false) const;
    1483              : 
    1484              :     /// @brief compute the first intersection point between the given lane geometries considering their rspective widths
    1485              :     static double firstIntersection(const PositionVector& v1, const PositionVector& v2, double width1, double width2, const std::string& error = "", bool secondIntersection = false);
    1486              : 
    1487              :     /** returns a modified version of laneShape which starts at the outside of startNode. laneShape may be shorted or extended
    1488              :      * @note see [wiki:Developer/Network_Building_Process]
    1489              :      */
    1490              :     static PositionVector startShapeAt(const PositionVector& laneShape, const NBNode* startNode, PositionVector nodeShape);
    1491              : 
    1492              :     /// @name functions for router usage
    1493              :     //@{
    1494              : 
    1495              :     static inline double getTravelTimeStatic(const NBEdge* const edge, const NBVehicle* const /*veh*/, double /*time*/) {
    1496        14505 :         return edge->getLength() / edge->getSpeed();
    1497              :     }
    1498              : 
    1499              :     static int getLaneIndexFromLaneID(const std::string laneID);
    1500              : 
    1501              :     /// @brief sets the index of the edge in the list of all network edges
    1502              :     void setNumericalID(int index) {
    1503        52587 :         myIndex = index;
    1504              :     }
    1505              : 
    1506              :     /** @brief Returns the index (numeric id) of the edge
    1507              :      * @note This is only used in the context of routing
    1508              :      * @return This edge's numerical id
    1509              :      */
    1510       365824 :     int getNumericalID() const {
    1511       365824 :         return myIndex;
    1512              :     }
    1513              : 
    1514      4296337 :     const NBEdge* getBidiEdge() const {
    1515      4296337 :         return isBidiRail() || isBidiEdge() ? myPossibleTurnDestination : nullptr;
    1516              :     }
    1517              : 
    1518              :     /** @brief Returns the following edges for the given vClass
    1519              :      */
    1520              :     const EdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
    1521              : 
    1522              : 
    1523              :     /** @brief Returns the following edges for the given vClass
    1524              :      */
    1525              :     const ConstRouterEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
    1526              : 
    1527              :     //@}
    1528      3068641 :     const std::string& getID() const {
    1529      3068641 :         return Named::getID();
    1530              :     }
    1531              : 
    1532              :     /// @brief join adjacent lanes with the given permissions
    1533              :     bool joinLanes(SVCPermissions perms);
    1534              : 
    1535              :     /// @brief reset lane shapes to what they would be before cutting with the junction shapes
    1536              :     void resetLaneShapes();
    1537              : 
    1538              :     /// @brief modify all existing restrictions on lane changing
    1539              :     void updateChangeRestrictions(SVCPermissions ignoring);
    1540              : 
    1541              :     /// @brief return the straightest follower edge for the given permissions or nullptr (never returns turn-arounds)
    1542              :     /// @note: this method is called before connections are built and simply goes by node graph topology
    1543              :     NBEdge* getStraightContinuation(SVCPermissions permissions) const;
    1544              : 
    1545              :     /// @brief return the straightest predecessor edge for the given permissions or nullptr (never returns turn-arounds)
    1546              :     /// @note: this method is called before connections are built and simply goes by node graph topology
    1547              :     NBEdge* getStraightPredecessor(SVCPermissions permissions) const;
    1548              : 
    1549              :     /// @brief set oppositeID and return opposite edge if found
    1550              :     NBEdge* guessOpposite(bool reguess = false);
    1551              : 
    1552              : 
    1553              :     const std::string& getTurnSignTarget() const {
    1554         6110 :         return myTurnSignTarget;
    1555              :     }
    1556              : 
    1557              :     void setTurnSignTarget(const std::string& target) {
    1558        47883 :         myTurnSignTarget = target;
    1559        49405 :     }
    1560              : 
    1561              :     /// @brief return only those edges that permit at least one of the give permissions
    1562              :     static EdgeVector filterByPermissions(const EdgeVector& edges, SVCPermissions permissions);
    1563              : 
    1564              : private:
    1565              :     /** @class ToEdgeConnectionsAdder
    1566              :      * @brief A class that being a bresenham-callback assigns the incoming lanes to the edges
    1567              :      */
    1568              :     class ToEdgeConnectionsAdder : public Bresenham::BresenhamCallBack {
    1569              :     private:
    1570              :         /// @brief map of edges to this edge's lanes that reach them
    1571              :         std::map<NBEdge*, std::vector<int> > myConnections;
    1572              : 
    1573              :         /// @brief the transition from the virtual lane to the edge it belongs to
    1574              :         const EdgeVector& myTransitions;
    1575              : 
    1576              :     public:
    1577              :         /// @brief constructor
    1578              :         ToEdgeConnectionsAdder(const EdgeVector& transitions)
    1579        45882 :             : myTransitions(transitions) { }
    1580              : 
    1581              :         /// @brief destructor
    1582        45882 :         ~ToEdgeConnectionsAdder() { }
    1583              : 
    1584              :         /// @brief executes a bresenham - step
    1585              :         void execute(const int lane, const int virtEdge);
    1586              : 
    1587              :         /// @brief get built connections
    1588              :         const std::map<NBEdge*, std::vector<int> >& getBuiltConnections() const {
    1589              :             return myConnections;
    1590              :         }
    1591              : 
    1592              :     private:
    1593              :         /// @brief Invalidated copy constructor.
    1594              :         ToEdgeConnectionsAdder(const ToEdgeConnectionsAdder&) = delete;
    1595              : 
    1596              :         /// @brief Invalidated assignment operator.
    1597              :         ToEdgeConnectionsAdder& operator=(const ToEdgeConnectionsAdder&) = delete;
    1598              :     };
    1599              : 
    1600              : 
    1601              :     /**
    1602              :      * @class MainDirections
    1603              :      * @brief Holds (- relative to the edge it is build from -!!!) the list of
    1604              :      * main directions a vehicle that drives on this street may take on
    1605              :      * the junction the edge ends in
    1606              :      * The back direction is not regarded
    1607              :      */
    1608              :     class MainDirections {
    1609              :     public:
    1610              :         /// @brief enum of possible directions
    1611              :         enum class Direction {
    1612              :             RIGHTMOST,
    1613              :             LEFTMOST,
    1614              :             FORWARD
    1615              :         };
    1616              : 
    1617              :     public:
    1618              :         /// @brief constructor
    1619              :         MainDirections(const EdgeVector& outgoing, NBEdge* parent, NBNode* to, const std::vector<int>& availableLanes);
    1620              : 
    1621              :         /// @brief destructor
    1622              :         ~MainDirections();
    1623              : 
    1624              :         /// @brief returns the index of the straightmost among the given outgoing edges
    1625              :         int getStraightest() const {
    1626        45930 :             return myStraightest;
    1627              :         }
    1628              : 
    1629              :         /// @brief returns the information whether no following street has a higher priority
    1630              :         bool empty() const;
    1631              : 
    1632              :         /// @brief returns the information whether the street in the given direction has a higher priority
    1633              :         bool includes(Direction d) const;
    1634              : 
    1635              :     private:
    1636              :         /// @brief the index of the straightmost among the given outgoing edges
    1637              :         int myStraightest;
    1638              : 
    1639              :         /// @brief list of the main direction within the following junction relative to the edge
    1640              :         std::vector<Direction> myDirs;
    1641              : 
    1642              :         /// @brief Invalidated copy constructor.
    1643              :         MainDirections(const MainDirections&) = delete;
    1644              : 
    1645              :         /// @brief Invalidated assignment operator.
    1646              :         MainDirections& operator=(const MainDirections&) = delete;
    1647              :     };
    1648              : 
    1649              :     /// @brief Computes the shape for the given lane
    1650              :     PositionVector computeLaneShape(int lane, double offset) const;
    1651              : 
    1652              :     /// @brief compute lane shapes
    1653              :     void computeLaneShapes();
    1654              : 
    1655              : private:
    1656              :     /** @brief Initialization routines common to all constructors
    1657              :      *
    1658              :      * Checks whether the number of lanes>0, whether the junction's from-
    1659              :      *  and to-nodes are given (!=0) and whether they are distict. Throws
    1660              :      *  a ProcessError if any of these checks fails.
    1661              :      *
    1662              :      * Adds the nodes positions to geometry if it shall not be ignored or
    1663              :      *  if the geometry is empty.
    1664              :      *
    1665              :      * Computes the angle and length, and adds this edge to its node as
    1666              :      *  outgoing/incoming. Builds lane informations.
    1667              :      *
    1668              :      * @param[in] noLanes The number of lanes this edge has
    1669              :      * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2
    1670              :      * @param[in] origID The original ID this edge had
    1671              :      */
    1672              :     void init(int noLanes, bool tryIgnoreNodePositions, const std::string& origID);
    1673              : 
    1674              :     /// @brief divides the lanes on the outgoing edges
    1675              :     void divideOnEdges(const EdgeVector* outgoing);
    1676              : 
    1677              :     /// @brief divide selected lanes on edges
    1678              :     void divideSelectedLanesOnEdges(const EdgeVector* outgoing, const std::vector<int>& availableLanes);
    1679              : 
    1680              :     /// @brief add some straight connections
    1681              :     void addStraightConnections(const EdgeVector* outgoing, const std::vector<int>& availableLanes, const std::vector<int>& priorities);
    1682              : 
    1683              :     /// @brief recomputes the edge priorities and manipulates them for a distribution of lanes on edges which is more like in real-life
    1684              :     const std::vector<int> prepareEdgePriorities(const EdgeVector* outgoing, const std::vector<int>& availableLanes);
    1685              : 
    1686              :     /// @name Setting and getting connections
    1687              :     /// @{
    1688              :     /** @briefmoves a connection one place to the left;
    1689              :      * @note Attention! no checking for field validity
    1690              :      */
    1691              :     void moveConnectionToLeft(int lane);
    1692              : 
    1693              :     /** @briefmoves a connection one place to the right;
    1694              :      * @noteAttention! no checking for field validity
    1695              :      */
    1696              :     void moveConnectionToRight(int lane);
    1697              : 
    1698              :     /// @brief whether the connection can originate on newFromLane
    1699              :     bool canMoveConnection(const Connection& con, int newFromLane) const;
    1700              :     /// @}
    1701              : 
    1702              :     /// @brief computes the angle of this edge and stores it in myAngle
    1703              :     void computeAngle();
    1704              : 
    1705              :     /// @brief determine conflict between opposite left turns
    1706              :     bool bothLeftTurns(LinkDirection dir, const NBEdge* otherFrom, LinkDirection dir2) const;
    1707              :     bool haveIntersection(const NBNode& n, const PositionVector& shape, const NBEdge* otherFrom, const NBEdge::Connection& otherCon,
    1708              :                           int numPoints, double width1, double width2, int shapeFlag = 0) const;
    1709              : 
    1710              :     /// @brief returns whether any lane already allows the given vclass exclusively
    1711              :     bool hasRestrictedLane(SUMOVehicleClass vclass) const;
    1712              : 
    1713              :     /// @brief restore a restricted lane
    1714              :     void restoreRestrictedLane(SUMOVehicleClass vclass, std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections);
    1715              : 
    1716              :     /// @brief assign length to all lanes of an internal edge
    1717              :     double assignInternalLaneLength(std::vector<Connection>::iterator i, int numLanes, double lengthSum, bool averageLength);
    1718              : 
    1719              :     /// @brief decode bitset
    1720              :     static std::vector<LinkDirection> decodeTurnSigns(int turnSigns, int shift = 0);
    1721              :     static void updateTurnPermissions(SVCPermissions& perm, LinkDirection dir, SVCPermissions spec, std::vector<LinkDirection> dirs);
    1722              : 
    1723              :     /// @brief apply loaded turn sign information
    1724              :     bool applyTurnSigns();
    1725              : 
    1726              :     /* @brief remove connections with incompatible permissions (should only be
    1727              :      * called for guessed connections) */
    1728              :     void removeInvalidConnections();
    1729              : 
    1730              : private:
    1731              :     /** @brief The building step
    1732              :      * @see EdgeBuildingStep
    1733              :      */
    1734              :     EdgeBuildingStep myStep;
    1735              : 
    1736              :     /// @brief The type of the edge
    1737              :     std::string myType;
    1738              : 
    1739              :     /// @brief The source and the destination node
    1740              :     NBNode* myFrom, *myTo;
    1741              : 
    1742              :     /// @brief node for which turnSign information applies
    1743              :     std::string myTurnSignTarget;
    1744              : 
    1745              :     /// @brief The length of the edge
    1746              :     double myLength;
    1747              : 
    1748              :     /// @brief The angles of the edge
    1749              :     /// @{
    1750              :     double myStartAngle;
    1751              :     double myEndAngle;
    1752              :     double myTotalAngle;
    1753              :     /// @}
    1754              : 
    1755              :     /// @brief The priority of the edge
    1756              :     int myPriority;
    1757              : 
    1758              :     /// @brief The maximal speed
    1759              :     double mySpeed;
    1760              : 
    1761              :     /// @brief The current friction
    1762              :     double myFriction;
    1763              : 
    1764              :     /// @brief The mileage/kilometrage at the start of this edge in a linear coordination system
    1765              :     double myDistance;
    1766              : 
    1767              :     /** @brief List of connections to following edges
    1768              :      * @see Connection
    1769              :      */
    1770              :     std::vector<Connection> myConnections;
    1771              : 
    1772              :     /// @brief List of connections marked for delayed removal
    1773              :     std::vector<Connection> myConnectionsToDelete;
    1774              : 
    1775              :     /// @brief The turn destination edge (if a connection exists)
    1776              :     NBEdge* myTurnDestination;
    1777              : 
    1778              :     /// @brief The edge that would be the turn destination if there was one
    1779              :     NBEdge* myPossibleTurnDestination;
    1780              : 
    1781              :     /// @brief The priority normalised for the node the edge is outgoing of
    1782              :     int myFromJunctionPriority;
    1783              : 
    1784              :     /// @brief The priority normalised for the node the edge is incoming in
    1785              :     int myToJunctionPriority;
    1786              : 
    1787              :     /// @brief The geometry for the edge
    1788              :     PositionVector myGeom;
    1789              : 
    1790              :     /// @brief The information about how to spread the lanes
    1791              :     LaneSpreadFunction myLaneSpreadFunction;
    1792              : 
    1793              :     /// @brief This edges's offset to the intersection begin (will be applied to all lanes)
    1794              :     double myEndOffset;
    1795              : 
    1796              :     /// @brief A vClass specific stop offset - assumed of length 0 (unspecified) or 1.
    1797              :     ///        For the latter case the int is a bit set specifying the vClasses,
    1798              :     ///        the offset applies to (see SUMOVehicleClass.h), and the double is the
    1799              :     ///        stopping offset in meters from the lane end
    1800              :     StopOffset myEdgeStopOffset;
    1801              : 
    1802              :     /// @brief This width of this edge's lanes
    1803              :     double myLaneWidth;
    1804              : 
    1805              :     /** @brief Lane information
    1806              :      * @see Lane
    1807              :      */
    1808              :     std::vector<Lane> myLanes;
    1809              : 
    1810              :     /// @brief An optional length to use (-1 if not valid)
    1811              :     double myLoadedLength;
    1812              : 
    1813              :     /// @brief Information whether this is lies within a joined tls
    1814              :     bool myAmInTLS;
    1815              : 
    1816              :     /// @brief Information whether this edge is a (macroscopic) connector
    1817              :     bool myAmMacroscopicConnector;
    1818              : 
    1819              :     /// @brief The street name (or whatever arbitrary string you wish to attach)
    1820              :     std::string myStreetName;
    1821              : 
    1822              :     /// @brief the street signs along this edge
    1823              :     std::vector<NBSign> mySigns;
    1824              : 
    1825              :     /// @brief the position of a traffic light signal on this edge
    1826              :     Position mySignalPosition;
    1827              :     const NBNode* mySignalNode;
    1828              : 
    1829              :     /// @brief intersection borders (because the node shape might be invalid)
    1830              :     /// @{
    1831              :     PositionVector myFromBorder;
    1832              :     PositionVector myToBorder;
    1833              :     /// @}
    1834              : 
    1835              :     /// @brief whether this edge is an Off-Ramp or leads to one
    1836              :     bool myIsOffRamp;
    1837              : 
    1838              :     /// @brief whether this edge is part of a non-rail bidi edge pair
    1839              :     bool myIsBidi;
    1840              : 
    1841              :     /// @brief the index of the edge in the list of all edges. Set by NBEdgeCont and requires re-set whenever the list of edges changes
    1842              :     int myIndex;
    1843              : 
    1844              :     // @brief a static list of successor edges. Set by NBEdgeCont and requires reset when the network changes
    1845              :     mutable EdgeVector mySuccessors;
    1846              : 
    1847              :     // @brief a static list of successor edges. Set by NBEdgeCont and requires reset when the network changes
    1848              :     mutable ConstRouterEdgePairVector myViaSuccessors;
    1849              : 
    1850              :     // @brief default length for overriding connection lengths
    1851              :     static double myDefaultConnectionLength;
    1852              : 
    1853              : public:
    1854              : 
    1855              :     /// @class connections_toedge_finder
    1856              :     class connections_toedge_finder {
    1857              :     public:
    1858              :         /// @brief constructor
    1859       848145 :         connections_toedge_finder(const NBEdge* const edge2find, bool hasFromLane = false) :
    1860       848145 :             myHasFromLane(hasFromLane),
    1861       848145 :             myEdge2Find(edge2find) { }
    1862              : 
    1863              :         /// @brief operator ()
    1864              :         bool operator()(const Connection& c) const {
    1865      1509212 :             return c.toEdge == myEdge2Find && (!myHasFromLane || c.fromLane != -1);
    1866              :         }
    1867              : 
    1868              :     private:
    1869              :         /// @brief check if has from lane
    1870              :         const bool myHasFromLane;
    1871              : 
    1872              :         /// @brief edge to find
    1873              :         const NBEdge* const myEdge2Find;
    1874              :     };
    1875              : 
    1876              :     /// @class connections_toedgelane_finder
    1877              :     class connections_toedgelane_finder {
    1878              :     public:
    1879              :         /// @brief constructor
    1880       243274 :         connections_toedgelane_finder(const NBEdge* const edge2find, int lane2find, int fromLane2find) :
    1881       243274 :             myEdge2Find(edge2find),
    1882       243274 :             myLane2Find(lane2find),
    1883       243274 :             myFromLane2Find(fromLane2find) { }
    1884              : 
    1885              :         /// @brief operator ()
    1886              :         bool operator()(const Connection& c) const {
    1887       436759 :             return c.toEdge == myEdge2Find && c.toLane == myLane2Find && (myFromLane2Find < 0 || c.fromLane == myFromLane2Find);
    1888              :         }
    1889              : 
    1890              :     private:
    1891              :         /// @brief edge to find
    1892              :         const NBEdge* const myEdge2Find;
    1893              : 
    1894              :         /// @brief lane to find
    1895              :         int myLane2Find;
    1896              : 
    1897              :         /// @brief from lane to find
    1898              :         int myFromLane2Find;
    1899              :     };
    1900              : 
    1901              :     /// @class connections_finder
    1902              :     class connections_finder {
    1903              :     public:
    1904              :         /// @brief constructor
    1905       220636 :         connections_finder(int fromLane, NBEdge* const edge2find, int lane2find, bool invertEdge2find = false) :
    1906       220636 :             myFromLane(fromLane), myEdge2Find(edge2find), myLane2Find(lane2find), myInvertEdge2find(invertEdge2find) { }
    1907              : 
    1908              :         /// @brief operator ()
    1909       508635 :         bool operator()(const Connection& c) const {
    1910       163579 :             return ((c.fromLane == myFromLane || myFromLane == -1)
    1911       345056 :                     && ((!myInvertEdge2find && c.toEdge == myEdge2Find) || (myInvertEdge2find && c.toEdge != myEdge2Find))
    1912       632260 :                     && (c.toLane == myLane2Find || myLane2Find == -1));
    1913              :         }
    1914              : 
    1915              :     private:
    1916              :         /// @brief index of from lane
    1917              :         int myFromLane;
    1918              : 
    1919              :         /// @brief edge to find
    1920              :         NBEdge* const myEdge2Find;
    1921              : 
    1922              :         /// @brief lane to find
    1923              :         int myLane2Find;
    1924              : 
    1925              :         /// @brief invert edge to find
    1926              :         bool myInvertEdge2find;
    1927              :     };
    1928              : 
    1929              :     /// @class connections_conflict_finder
    1930              :     class connections_conflict_finder {
    1931              :     public:
    1932              :         /// @brief constructor
    1933              :         connections_conflict_finder(int fromLane, NBEdge* const edge2find, bool checkRight) :
    1934              :             myFromLane(fromLane), myEdge2Find(edge2find), myCheckRight(checkRight) { }
    1935              : 
    1936              :         /// @brief operator ()
    1937              :         bool operator()(const Connection& c) const {
    1938         4337 :             return (((myCheckRight && c.fromLane < myFromLane) || (!myCheckRight && c.fromLane > myFromLane))
    1939         2617 :                     && c.fromLane >= 0 // already assigned
    1940         1622 :                     && c.toEdge == myEdge2Find);
    1941              :         }
    1942              : 
    1943              :     private:
    1944              :         /// @brief index of from lane
    1945              :         int myFromLane;
    1946              : 
    1947              :         /// @brief edge to find
    1948              :         NBEdge* const myEdge2Find;
    1949              : 
    1950              :         /// @brief check if is right
    1951              :         bool myCheckRight;
    1952              :     };
    1953              : 
    1954              :     /// @class connections_fromlane_finder
    1955              :     class connections_fromlane_finder {
    1956              :     public:
    1957              :         /// @briefconstructor
    1958              :         connections_fromlane_finder(int lane2find) : myLane2Find(lane2find) { }
    1959              : 
    1960              :         /// @brief operator ()
    1961              :         bool operator()(const Connection& c) const {
    1962              :             return c.fromLane == myLane2Find;
    1963              :         }
    1964              : 
    1965              :     private:
    1966              :         /// @brief index of lane to find
    1967              :         int myLane2Find;
    1968              : 
    1969              :     private:
    1970              :         /// @brief invalidated assignment operator
    1971              :         connections_fromlane_finder& operator=(const connections_fromlane_finder& s) = delete;
    1972              :     };
    1973              : 
    1974              :     /// @brief connections_sorter sort by fromLane, toEdge and toLane
    1975              :     static bool connections_sorter(const Connection& c1, const Connection& c2);
    1976              : 
    1977              :     /**
    1978              :      * @class connections_relative_edgelane_sorter
    1979              :      * @brief Class to sort edges by their angle
    1980              :      */
    1981              :     class connections_relative_edgelane_sorter {
    1982              :     public:
    1983              :         /// @brief constructor
    1984              :         explicit connections_relative_edgelane_sorter(NBEdge* e) : myEdge(e) {}
    1985              : 
    1986              :     public:
    1987              :         /// @brief comparing operation
    1988              :         int operator()(const Connection& c1, const Connection& c2) const;
    1989              : 
    1990              :     private:
    1991              :         /// @brief the edge to compute the relative angle of
    1992              :         NBEdge* myEdge;
    1993              :     };
    1994              : 
    1995              : private:
    1996              :     /// @brief invalidated copy constructor
    1997              :     NBEdge(const NBEdge& s) = delete;
    1998              : 
    1999              :     /// @brief invalidated assignment operator
    2000              :     NBEdge& operator=(const NBEdge& s) = delete;
    2001              : 
    2002              :     /// @brief constructor for dummy edge
    2003              :     NBEdge();
    2004              : };
        

Generated by: LCOV version 2.0-1