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

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

Generated by: LCOV version 1.14