LCOV - code coverage report
Current view: top level - src/microsim - MSEdge.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 85.1 % 67 57
Test Date: 2026-03-02 16:00:03 Functions: 66.7 % 9 6

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
       4              : // This program and the accompanying materials are made available under the
       5              : // terms of the Eclipse Public License 2.0 which is available at
       6              : // https://www.eclipse.org/legal/epl-2.0/
       7              : // This Source Code may also be made available under the following Secondary
       8              : // Licenses when the conditions for such availability set forth in the Eclipse
       9              : // Public License 2.0 are satisfied: GNU General Public License, version 2
      10              : // or later which is available at
      11              : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
      12              : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
      13              : /****************************************************************************/
      14              : /// @file    MSEdge.h
      15              : /// @author  Christian Roessel
      16              : /// @author  Daniel Krajzewicz
      17              : /// @author  Jakob Erdmann
      18              : /// @author  Sascha Krieg
      19              : /// @author  Michael Behrisch
      20              : /// @date    Mon, 12 Mar 2001
      21              : ///
      22              : // A road/street connecting two junctions
      23              : /****************************************************************************/
      24              : #pragma once
      25              : #include <config.h>
      26              : 
      27              : #include <vector>
      28              : #include <map>
      29              : #include <string>
      30              : #include <iostream>
      31              : #ifdef HAVE_FOX
      32              : #include <utils/foxtools/fxheader.h>
      33              : #endif
      34              : #include <utils/common/Named.h>
      35              : #include <utils/common/Parameterised.h>
      36              : #include <utils/common/SUMOTime.h>
      37              : #include <utils/common/SUMOVehicleClass.h>
      38              : #include <utils/geom/Boundary.h>
      39              : #include <utils/router/ReversedEdge.h>
      40              : #include <utils/router/RailEdge.h>
      41              : #include <utils/vehicle/SUMOVehicle.h>
      42              : #include <utils/vehicle/SUMOTrafficObject.h>
      43              : #include "MSNet.h"
      44              : 
      45              : 
      46              : // ===========================================================================
      47              : // class declarations
      48              : // ===========================================================================
      49              : class Boundary;
      50              : class OutputDevice;
      51              : class SUMOVehicle;
      52              : class SUMOVehicleParameter;
      53              : class MSVehicle;
      54              : class MSLane;
      55              : class MSLaneChanger;
      56              : class MSPerson;
      57              : class MSJunction;
      58              : class MSEdge;
      59              : class MSTransportable;
      60              : 
      61              : 
      62              : // ===========================================================================
      63              : // class definitions
      64              : // ===========================================================================
      65              : /**
      66              :  * @class MSEdge
      67              :  * @brief A road/street connecting two junctions
      68              :  *
      69              :  * A single connection between two junctions.
      70              :  * Holds lanes which are reponsible for vehicle movements.
      71              :  */
      72              : 
      73              : typedef std::vector<MSEdge*> MSEdgeVector;
      74              : typedef std::vector<const MSEdge*> ConstMSEdgeVector;
      75              : typedef std::vector<std::pair<const MSEdge*, const MSEdge*> > MSConstEdgePairVector;
      76              : 
      77              : class MSEdge : public Named, public Parameterised {
      78              : private:
      79              :     /** @brief "Map" from vehicle class to allowed lanes */
      80              :     typedef std::vector<std::pair<SVCPermissions, std::shared_ptr<const std::vector<MSLane*> > > > AllowedLanesCont;
      81              : 
      82              :     /** @brief Succeeding edges (keys) and allowed lanes to reach these edges (values). */
      83              :     typedef std::map<const MSEdge*, AllowedLanesCont> AllowedLanesByTarget;
      84              : 
      85              : 
      86              : public:
      87              :     friend class MSLaneChangerSublane; // needs access to myLaneChanger
      88              : 
      89              :     /** @brief Constructor.
      90              :      *
      91              :      * After calling this constructor, the edge is not yet initialised
      92              :      *  completely. A call to "initialize" with proper values is needed
      93              :      *  for this.
      94              :      *
      95              :      * @param[in] id The id of the edge
      96              :      * @param[in] numericalID The numerical id (index) of the edge
      97              :      * @param[in] function A basic type of the edge
      98              :      * @param[in] streetName The street name for that edge
      99              :      */
     100              :     MSEdge(const std::string& id, int numericalID, const SumoXMLEdgeFunc function,
     101              :            const std::string& streetName, const std::string& edgeType,
     102              :            const std::string& routingType, int priority, double distance);
     103              : 
     104              : 
     105              :     /// @brief Destructor.
     106              :     virtual ~MSEdge();
     107              : 
     108              : 
     109              :     /** @brief Initialize the edge.
     110              :      *
     111              :      * @param[in] allowed Information which edges may be reached from which lanes
     112              :      * @param[in] lanes List of this edge's lanes
     113              :      */
     114              :     void initialize(const std::vector<MSLane*>* lanes);
     115              : 
     116              : 
     117              :     /** @brief Recalculates the cached values
     118              :      */
     119              :     void recalcCache();
     120              : 
     121              : 
     122              :     /// @todo Has to be called after all edges were built and all connections were set...; Still, is not very nice
     123              :     virtual void closeBuilding();
     124              : 
     125              :     /// Has to be called after all sucessors and predecessors have been set (after closeBuilding())
     126              :     void buildLaneChanger();
     127              : 
     128              :     /* @brief returns whether initizliaing a lane change is permitted on this edge
     129              :      * @note Has to be called after all sucessors and predecessors have been set (after closeBuilding())
     130              :      */
     131              :     bool allowsLaneChanging() const;
     132              : 
     133              :     /// @name Access to the edge's lanes
     134              :     /// @{
     135              : 
     136              :     /** @brief Returns the lane left to the one given, 0 if the given lane is leftmost
     137              :      *
     138              :      * @param[in] lane The lane right to the one to be returned
     139              :      * @return The lane left to the given, 0 if no such lane exists
     140              :      * @todo This method searches for the given in the container; probably, this could be done faster
     141              :      */
     142              :     MSLane* leftLane(const MSLane* const lane) const;
     143              : 
     144              : 
     145              :     /** @brief Returns the lane right to the one given, 0 if the given lane is rightmost
     146              :      *
     147              :      * @param[in] lane The lane left to the one to be returned
     148              :      * @return The lane right to the given, 0 if no such lane exists
     149              :      * @todo This method searches for the given in the container; probably, this could be done faster
     150              :      */
     151              :     MSLane* rightLane(const MSLane* const lane) const;
     152              : 
     153              : 
     154              :     /** @brief Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist
     155              :      *
     156              :      * @param[in] lane The base lane
     157              :      * @param[in] offset The offset of the result lane
     158              :      * @param[in] includeOpposte Whether an opposite direction lane may be returned
     159              :      * @todo This method searches for the given in the container; probably, this could be done faster
     160              :      */
     161              :     MSLane* parallelLane(const MSLane* const lane, int offset, bool includeOpposite = true) const;
     162              : 
     163              : 
     164              :     /** @brief Returns this edge's lanes
     165              :      *
     166              :      * @return This edge's lanes
     167              :      */
     168              :     inline const std::vector<MSLane*>& getLanes() const {
     169              :         return *myLanes;
     170              :     }
     171              : 
     172              :     inline int getNumLanes() const {
     173    795091949 :         return (int)myLanes->size();
     174              :     }
     175              : 
     176              :     /// @brief return the number of lanes that permit non-weak modes if the edge allows non weak modes and the number of lanes otherwise
     177              :     int getNumDrivingLanes() const;
     178              : 
     179              :     /// @brief return total number of vehicles on this edges lanes or segments
     180              :     int getVehicleNumber() const;
     181              : 
     182              :     /// @brief whether this edge has no vehicles
     183              :     bool isEmpty() const;
     184              : 
     185              :     /// @brief return vehicles on this edges lanes or segments
     186              :     std::vector<const SUMOVehicle*> getVehicles() const;
     187              : 
     188              :     double getBruttoOccupancy() const;
     189              : 
     190              :     /// @brief return flow based on meanSpead @note: may produced incorrect results when jammed
     191              :     double getFlow() const;
     192              : 
     193              :     /// @brief return accumated waiting time for all vehicles on this edges lanes or segments
     194              :     double getWaitingSeconds() const;
     195              : 
     196              :     /// @brief return mean occupancy on this edges lanes or segments
     197              :     double getOccupancy() const;
     198              : 
     199              :     /** @brief Returns this edge's persons set.
     200              :      *  @brief Avoids the creation of new vector as in getSortedPersons
     201              :      *
     202              :      * @return This edge's persons.
     203              :      */
     204              :     inline const std::set<MSTransportable*, ComparatorNumericalIdLess>& getPersons() const {
     205              :         return myPersons;
     206              :     }
     207              : 
     208              :     /** @brief Returns this edge's persons sorted by pos
     209              :      *
     210              :      * @return This edge's persons sorted by pos
     211              :      */
     212              :     std::vector<MSTransportable*> getSortedPersons(SUMOTime timestep, bool includeRiding = false) const;
     213              : 
     214              : 
     215              :     /** @brief Returns this edge's containers sorted by pos
     216              :      *
     217              :      * @return This edge's containers sorted by pos
     218              :      */
     219              :     std::vector<MSTransportable*> getSortedContainers(SUMOTime timestep, bool includeRiding = false) const;
     220              : 
     221              :     /** @brief Get the allowed lanes to reach the destination-edge.
     222              :      *
     223              :      * If there is no such edge, return nullptr. Then you are on the wrong edge.
     224              :      *
     225              :      * @param[in] destination The edge to reach
     226              :      * @param[in] vclass The vehicle class for which this information shall be returned
     227              :      * @return The lanes that may be used to reach the given edge, nullptr if no such lanes exist
     228              :      */
     229              :     const std::vector<MSLane*>* allowedLanes(const MSEdge& destination,
     230              :             SUMOVehicleClass vclass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
     231              : 
     232              : 
     233              : 
     234              :     /** @brief Get the allowed lanes for the given vehicle class.
     235              :      *
     236              :      * If there is no such edge, return nullptr. Then you are on the wrong edge.
     237              :      *
     238              :      * @param[in] vclass The vehicle class for which this information shall be returned
     239              :      * @return The lanes that may be used by the given vclass
     240              :      */
     241              :     const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass = SVC_IGNORING) const;
     242              :     const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass, bool ignoreTransientPermissions) const;
     243              : 
     244              :     inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {
     245       402667 :         const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);
     246       509722 :         return lanes != nullptr && !lanes->empty();
     247              :     }
     248              :     /// @}
     249              : 
     250              : 
     251              : 
     252              :     /// @name Access to other edge attributes
     253              :     /// @{
     254              : 
     255              :     /** @brief Returns the edge type (SumoXMLEdgeFunc)
     256              :      * @return This edge's SumoXMLEdgeFunc
     257              :      * @see SumoXMLEdgeFunc
     258              :      */
     259              :     inline SumoXMLEdgeFunc getFunction() const {
     260      3976044 :         return myFunction;
     261              :     }
     262              : 
     263              :     /// @brief return whether this edge is an internal edge
     264              :     inline bool isNormal() const {
     265     55759254 :         return myFunction == SumoXMLEdgeFunc::NORMAL;
     266              :     }
     267              : 
     268              :     /// @brief return whether this edge is an internal edge
     269              :     inline bool isInternal() const {
     270   3251688122 :         return myFunction == SumoXMLEdgeFunc::INTERNAL;
     271              :     }
     272              : 
     273              :     /// @brief return whether this edge is a pedestrian crossing
     274              :     inline bool isCrossing() const {
     275    202951566 :         return myFunction == SumoXMLEdgeFunc::CROSSING;
     276              :     }
     277              : 
     278              : 
     279              :     /// @brief check and register the opposite superposable edge if any
     280              :     void checkAndRegisterBiDirEdge(const std::string& bidiID = "");
     281              : 
     282              :     /// @brief return opposite superposable/congruent edge, if it exist and 0 else
     283              :     inline const MSEdge* getBidiEdge() const {
     284    149724658 :         return myBidiEdge;
     285              :     }
     286              : 
     287              :     /// @brief return whether this edge is walking area
     288              :     inline bool isWalkingArea() const {
     289    186655893 :         return myFunction == SumoXMLEdgeFunc::WALKINGAREA;
     290              :     }
     291              : 
     292              :     inline bool isTazConnector() const {
     293  15262960378 :         return myFunction == SumoXMLEdgeFunc::CONNECTOR;
     294              :     }
     295              : 
     296              :     void setOtherTazConnector(const MSEdge* edge) {
     297        30634 :         myOtherTazConnector = edge;
     298              :     }
     299              : 
     300              :     const MSEdge* getOtherTazConnector() const {
     301        36612 :         return myOtherTazConnector;
     302              :     }
     303              : 
     304              :     /** @brief Returns the numerical id of the edge
     305              :      * @return This edge's numerical id
     306              :      */
     307              :     inline int getNumericalID() const {
     308    666328790 :         return myNumericalID;
     309              :     }
     310              : 
     311              : 
     312              :     /** @brief Returns the street name of the edge
     313              :      */
     314              :     const std::string& getStreetName() const {
     315            0 :         return myStreetName;
     316              :     }
     317              : 
     318              :     /** @brief Returns the type of the edge
     319              :      */
     320              :     const std::string& getEdgeType() const {
     321      2846488 :         return myEdgeType;
     322              :     }
     323              : 
     324              :     /** @brief Returns the type of the edge
     325              :      */
     326              :     const std::string& getRoutingType() const {
     327         3311 :         return myRoutingType.empty() ? myEdgeType : myRoutingType;
     328              :     }
     329              : 
     330              :     double getPreference(const SUMOVTypeParameter& pars) const;
     331              : 
     332              :     // @brief try to infer edge type for internal edges
     333              :     void inferEdgeType();
     334              : 
     335              :     /** @brief Returns the priority of the edge
     336              :      */
     337              :     int getPriority() const {
     338       748031 :         return myPriority;
     339              :     }
     340              : 
     341              :     /** @brief Returns the kilometrage/mileage encoding at the start of the edge
     342              :      * (negative values encode descending direction)
     343              :     */
     344              :     double getDistance() const {
     345            0 :         return myDistance;
     346              :     }
     347              : 
     348              :     /** @brief Returns the kilometrage/mileage at the given offset along the edge
     349              :      */
     350              :     double getDistanceAt(double pos) const;
     351              : 
     352              :     bool hasDistance() const {
     353            0 :         return myDistance != 0;
     354              :     }
     355              :     /// @}
     356              : 
     357              :     /**@brief Sets the crossed edge ids for a crossing edge
     358              :      *
     359              :      */
     360        17726 :     void setCrossingEdges(const std::vector<std::string>& crossingEdges)        {
     361              :         myCrossingEdges.clear();
     362        17726 :         myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());
     363        17726 :     }
     364              : 
     365              :     /**@brief Gets the crossed edge ids
     366              :      *@return The list of crossed edge ids in a crossing edge or an empty vector
     367              :      */
     368              :     const std::vector<std::string>& getCrossingEdges() const {
     369              :         return myCrossingEdges;
     370              :     }
     371              : 
     372              : 
     373              :     /// @name Access to succeeding/predecessing edges
     374              :     /// @{
     375              : 
     376              :     /** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge
     377              :      *
     378              :      * This is mainly used by the taz (district) parsing
     379              :      * @param[in] edge The edge to add
     380              :      */
     381              :     void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);
     382              : 
     383              :     void resetTAZ(MSJunction* junction);
     384              : 
     385              :     /** @brief Returns the number of edges that may be reached from this edge
     386              :      * @return The number of following edges
     387              :      */
     388              :     int getNumSuccessors() const {
     389      1229501 :         return (int) mySuccessors.size();
     390              :     }
     391              : 
     392              : 
     393              :     /** @brief Returns the following edges, restricted by vClass
     394              :      * @param[in] vClass The vClass for which to restrict the successors
     395              :      * @return The eligible following edges
     396              :      */
     397              :     const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
     398              : 
     399              :     /** @brief Returns the following edges with internal vias, restricted by vClass
     400              :      * @param[in] vClass The vClass for which to restrict the successors
     401              :      * @return The eligible following edges
     402              :      */
     403              :     const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
     404              : 
     405              : 
     406              :     /** @brief Returns the number of edges this edge is connected to
     407              :      *
     408              :      * @return The number of edges following this edge
     409              :      */
     410              :     int getNumPredecessors() const {
     411       742003 :         return (int) myPredecessors.size();
     412              :     }
     413              : 
     414              : 
     415              :     /** @brief
     416              :      * @return
     417              :      */
     418              :     const MSEdgeVector& getPredecessors() const {
     419      5294404 :         return myPredecessors;
     420              :     }
     421              : 
     422              : 
     423              :     const MSJunction* getFromJunction() const {
     424     20762377 :         return myFromJunction;
     425              :     }
     426              : 
     427              :     const MSJunction* getToJunction() const {
     428    678827665 :         return myToJunction;
     429              :     }
     430              : 
     431              : 
     432              :     void setJunctions(MSJunction* from, MSJunction* to);
     433              :     /// @}
     434              : 
     435              : 
     436              : 
     437              :     /// @name Access to vaporizing interface
     438              :     /// @{
     439              : 
     440              :     /** @brief Returns whether vehicles on this edge shall be vaporized
     441              :      * @return Whether no vehicle shall be on this edge
     442              :      */
     443              :     bool isVaporizing() const {
     444  13536759191 :         return myVaporizationRequests > 0;
     445              :     }
     446              : 
     447              : 
     448              :     /** @brief Enables vaporization
     449              :      *
     450              :      * The internal vaporization counter is increased enabling the
     451              :      *  vaporization.
     452              :      * Called from the event handler.
     453              :      * @param[in] t The current time (unused)
     454              :      * @return Time to next call (always 0)
     455              :      * @exception ProcessError not thrown by this method, just derived
     456              :      */
     457              :     SUMOTime incVaporization(SUMOTime t);
     458              : 
     459              : 
     460              :     /** @brief Disables vaporization
     461              :      *
     462              :      * The internal vaporization counter is decreased what disables
     463              :      *  the vaporization if it was only once enabled.
     464              :      * Called from the event handler.
     465              :      * @param[in] t The current time (unused)
     466              :      * @return Time to next call (always 0)
     467              :      * @exception ProcessError not thrown by this method, just derived
     468              :      */
     469              :     SUMOTime decVaporization(SUMOTime t);
     470              :     /// @}
     471              : 
     472              : 
     473              :     /** @brief Computes and returns the current travel time for this edge
     474              :      *
     475              :      * The mean speed of all lanes is used to compute the travel time.
     476              :      * To avoid infinite travel times, the given minimum speed is used.
     477              :      *
     478              :      * @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped
     479              :      * @return The current effort (travel time) to pass the edge
     480              :      */
     481              :     double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;
     482              : 
     483              : 
     484              :     /// @brief returns the minimum travel time for the given vehicle
     485    186379610 :     inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {
     486    186385793 :         if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {
     487              :             return 0;
     488    177065898 :         } else if (veh != 0) {
     489    176932871 :             return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;
     490              :         } else {
     491       139156 :             return myEmptyTraveltime;
     492              :         }
     493              :     }
     494              : 
     495            0 :     double getTimePenalty() const {
     496      3699813 :         return myTimePenalty;
     497              :     }
     498              : 
     499              :     /** @brief Returns the travel time for the given edge
     500              :      *
     501              :      * @param[in] edge The edge for which the travel time shall be retrieved
     502              :      * @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
     503              :      * @param[in] time The time for which the travel time shall be returned [s]
     504              :      * @return The traveltime needed by the given vehicle to pass the edge at the given time
     505              :      */
     506              :     static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {
     507        59658 :         return MSNet::getInstance()->getTravelTime(edge, veh, time);
     508              :     }
     509              : 
     510              :     static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);
     511              : 
     512              :     /** @brief Returns the averaged speed used by the routing device
     513              :      */
     514              :     double getRoutingSpeed() const;
     515              : 
     516              : 
     517              :     /// @name Methods releated to vehicle insertion
     518              :     /// @{
     519              : 
     520              :     /** @brief Tries to insert the given vehicle into the network
     521              :      *
     522              :      * The procedure for choosing the proper lane is determined, first.
     523              :      *  In dependence to this, the proper lane is chosen.
     524              :      *
     525              :      * Insertion itself is done by calling the chose lane's "insertVehicle"
     526              :      *  method but only if the checkOnly argument is false. The check needs
     527              :      *  to be certain only in the negative case (if false is returned, there
     528              :      *  is no way this vehicle would be inserted).
     529              :      *
     530              :      * @param[in] v The vehicle to insert
     531              :      * @param[in] time The current simulation time
     532              :      * @param[in] checkOnly Whether we perform only the check without actually inserting
     533              :      * @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle
     534              :      *            or whether insertion on lanes for which an insertion has already a failed should be ignored
     535              :      *            in the current time step.
     536              :      * @return Whether the vehicle could be inserted
     537              :      * @see MSLane::insertVehicle
     538              :      */
     539              :     bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;
     540              : 
     541              :     /// @brief check whether the given departSpeed is valid for this edge
     542              :     bool validateDepartSpeed(SUMOVehicle& v) const;
     543              : 
     544              :     /** @brief Finds the emptiest lane allowing the vehicle class
     545              :      *
     546              :      * The emptiest lane is the one which vehicle insertion is most likely to succeed.
     547              :      *
     548              :      * If there are no vehicles before departPos, then the lane with the largest
     549              :      * gap between departPos and the last vehicle is
     550              :      * Otheriwise the lane with lowes occupancy is selected
     551              :      * If there is more than one, the first according to its
     552              :      *  index in the lane container is chosen.
     553              :      *
     554              :      * If allowed==0, the lanes allowed for the given vehicle class
     555              :      *  will be used.
     556              :      *
     557              :      * @param[in] allowed The lanes to choose from
     558              :      * @param[in] vclass The vehicle class to look for
     559              :      * @param[in] departPos An upper bound on vehicle depart position
     560              :      * @return the least occupied lane
     561              :      * @see allowedLanes
     562              :      */
     563              :     MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;
     564              : 
     565              :     /** @brief Finds the most probable lane allowing the vehicle class
     566              :      *
     567              :      * The most probable lane is the one which best corresponds to the desired speed of the vehicle
     568              :      * Vehicles with lower speeds will use lanes to the right while
     569              :      * vehicles with higher speeds will use lanes to the left
     570              :      *
     571              :      * @param[in] allowed The lanes to choose from
     572              :      * @param[in] vclass The vehicle class to look for
     573              :      * @param[in] departPos An upper bound on vehicle depart position
     574              :      * @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)
     575              :      * @return the least occupied lane
     576              :      * @see allowedLanes
     577              :      */
     578              :     MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;
     579              : 
     580              : 
     581              :     /** @brief Finds a depart lane for the given vehicle parameters
     582              :      *
     583              :      * Depending on the depart lane procedure a depart lane is chosen.
     584              :      *  Repeated calls with the same vehicle may return different results
     585              :      *  if the procedure is "random" or "free". In case no appropriate
     586              :      *  lane was found, 0 is returned.
     587              :      *
     588              :      * @param[in] veh The vehicle to get the depart lane for
     589              :      * @return a possible/chosen depart lane, 0 if no lane can be used
     590              :      */
     591              :     MSLane* getDepartLane(MSVehicle& veh) const;
     592              : 
     593              :     /* @brief get the rightmost lane that allows the given vClass or nullptr
     594              :      * @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden
     595              :      */
     596              :     MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;
     597              : 
     598              :     /// @brief consider given departLane parameter (only for validating speeds)
     599              :     MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;
     600              : 
     601              :     /** @brief Returns the last time a vehicle could not be inserted
     602              :      * @return The current value
     603              :      */
     604              :     inline SUMOTime getLastFailedInsertionTime() const {
     605              :         return myLastFailedInsertionTime;
     606              :     }
     607              : 
     608              : 
     609              :     /** @brief Sets the last time a vehicle could not be inserted
     610              :      * @param[in] time the new value
     611              :      */
     612              :     inline void setLastFailedInsertionTime(SUMOTime time) const {
     613   5216059641 :         myLastFailedInsertionTime = time;
     614              :     }
     615              :     /// @}
     616              : 
     617              : 
     618              :     /** @brief Performs lane changing on this edge */
     619              :     void changeLanes(SUMOTime t) const;
     620              : 
     621              : 
     622              :     /// @todo extension: inner junctions are not filled
     623              :     const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
     624              : 
     625              : 
     626              :     /// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.
     627              :     double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
     628              : 
     629              :     /// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
     630              :     const MSEdge* getNormalBefore() const;
     631              : 
     632              :     /// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself
     633              :     const MSEdge* getNormalSuccessor() const;
     634              : 
     635              :     /// @brief Returns whether the vehicle (class) is not allowed on the edge
     636    652802430 :     inline bool prohibits(const SUMOVehicle* const vehicle) const {
     637    652802430 :         if (vehicle == nullptr) {
     638              :             return false;
     639              :         }
     640    652801658 :         const SUMOVehicleClass svc = vehicle->getVClass();
     641    652801658 :         return (vehicle->ignoreTransientPermissions()
     642    652801658 :                 ? (myOriginalCombinedPermissions & svc) != svc
     643    652732390 :                 : (myCombinedPermissions & svc) != svc);
     644              :     }
     645              : 
     646              :     bool hasTransientPermissions() const;
     647              : 
     648              :     /** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it
     649              :      * The restriction mechanism is not implemented yet for the microsim, so it always returns false.
     650              :      * @param[in] vehicle The vehicle for which the information has to be returned
     651              :      * @return Whether the vehicle must not enter this edge
     652              :      */
     653              :     inline bool restricts(const SUMOVehicle* const /* vehicle */) const {
     654              :         return false;
     655              :     }
     656              : 
     657              :     /// @brief Returns the combined permissions of all lanes of this edge
     658              :     inline SVCPermissions getPermissions() const {
     659   2850763686 :         return myCombinedPermissions;
     660              :     }
     661              : 
     662              :     /** @brief Returns the edges's width (sum over all lanes)
     663              :      * @return This edges's width
     664              :      */
     665              :     double getWidth() const {
     666    681447981 :         return myWidth;
     667              :     }
     668              : 
     669              :     /// @brief Returns the right side offsets of this edge's sublanes
     670              :     const std::vector<double> getSubLaneSides() const {
     671    274906959 :         return mySublaneSides;
     672              :     }
     673              : 
     674              :     void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);
     675              : 
     676              :     void rebuildAllowedTargets(const bool updateVehicles = true);
     677              : 
     678              : 
     679              :     /** @brief optimistic air distance heuristic for use in routing
     680              :      * @param[in] other The edge to which the distance shall be returned
     681              :      * @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes
     682              :      * @return The distance to the other edge
     683              :      */
     684              :     double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;
     685              : 
     686              : 
     687              :     /// @brief return the coordinates of the center of the given stop
     688              :     static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
     689              : 
     690              : 
     691              :     /** @brief return the length of the edge
     692              :      * @return The edge's length
     693              :      */
     694              :     inline double getLength() const {
     695   1200199360 :         return myLength;
     696              :     }
     697              : 
     698              : 
     699              :     /** @brief Returns the speed limit of the edge
     700              :      * @caution The speed limit of the first lane is retured; should probably be the fastest edge
     701              :      * @return The maximum speed allowed on this edge
     702              :      */
     703              :     double getSpeedLimit() const;
     704              : 
     705              :     /// @brief return shape.length() / myLength
     706              :     double getLengthGeometryFactor() const;
     707              : 
     708              :     /** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
     709              :      * @param[in] val the new speed in m/s
     710              :      * @param[in] modified whether this modifies the original speed
     711              :      * @param[in] jamThreshold also set a new jamThreshold
     712              :      */
     713              :     void setMaxSpeed(const double val, const bool modified = true, const double jamThreshold = -1);
     714              : 
     715              :     /** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]
     716              :     * @param[in] val the new coefficient in [0..1]
     717              :     */
     718              :     void setFrictionCoefficient(double val) const;
     719              : 
     720              :     /** @brief Returns the maximum speed the vehicle may use on this edge
     721              :      *
     722              :      * @caution Only the first lane is considered
     723              :      * @return The maximum velocity on this edge for the given vehicle
     724              :      */
     725              :     double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;
     726              : 
     727              : 
     728              :     virtual void addTransportable(MSTransportable* t) const;
     729              : 
     730              :     virtual void removeTransportable(MSTransportable* t) const;
     731              : 
     732              :     inline bool isRoundabout() const {
     733   2031582871 :         return myAmRoundabout;
     734              :     }
     735              : 
     736              :     void markAsRoundabout() {
     737         6495 :         myAmRoundabout = true;
     738         6495 :     }
     739              : 
     740              :     void markDelayed() const {
     741     74194863 :         myAmDelayed = true;
     742     52738535 :     }
     743              : 
     744              :     // return whether there have been vehicles on this or the bidi edge (if there is any) at least once
     745              :     inline bool isDelayed() const {
     746    673393705 :         return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);
     747              :     }
     748              : 
     749              :     bool hasLaneChanger() const {
     750   1745344674 :         return myLaneChanger != nullptr;
     751              :     }
     752              : 
     753              :     /// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
     754              :     std::pair<double, SUMOTime> getLastBlocked(int index) const;
     755              : 
     756              :     /// @brief whether this edge allows changing to the opposite direction edge
     757              :     bool canChangeToOpposite() const;
     758              : 
     759              :     /// @brief Returns the opposite direction edge if on exists else a nullptr
     760              :     const MSEdge* getOppositeEdge() const;
     761              : 
     762              :     /// @brief get the mean speed
     763              :     double getMeanSpeed() const;
     764              : 
     765              :     /// @brief get the mean friction over the lanes
     766              :     double getMeanFriction() const;
     767              : 
     768              :     /// @brief get the mean speed of all bicycles on this edge
     769              :     double getMeanSpeedBike() const;
     770              : 
     771              :     /// @brief whether any lane has a minor link
     772              :     bool hasMinorLink() const;
     773              : 
     774              :     /// @brief return whether this edge is at the fringe of the network
     775              :     bool isFringe() const {
     776              :         return myAmFringe;
     777              :     }
     778              : 
     779              :     /// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index
     780              :     bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;
     781              : 
     782              :     /// @brief whether this lane is selected in the GUI
     783            0 :     virtual bool isSelected() const {
     784            0 :         return false;
     785              :     }
     786              : 
     787              :     /// @brief grant exclusive access to the mesoscopic state
     788     34376079 :     virtual void lock() const {}
     789              : 
     790              :     /// @brief release exclusive access to the mesoscopic state
     791     34376079 :     virtual void unlock() const {};
     792              : 
     793              :     /// @brief Adds a vehicle to the list of waiting vehicles
     794              :     void addWaiting(SUMOVehicle* vehicle) const;
     795              : 
     796              :     /// @brief Removes a vehicle from the list of waiting vehicles
     797              :     void removeWaiting(const SUMOVehicle* vehicle) const;
     798              : 
     799              :     /* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position
     800              :      * @param[in] transportable The person or container that wants to ride
     801              :      * @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance
     802              :      */
     803              :     SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;
     804              : 
     805              :     /** @brief Remove all transportables before quick-loading state */
     806              :     void clearState();
     807              : 
     808              :     void postLoadInitLaneChanger();
     809              : 
     810              :     static DepartLaneDefinition& getDefaultDepartLaneDefinition() {
     811              :         return myDefaultDepartLaneDefinition;
     812              :     }
     813              : 
     814              :     static int& getDefaultDepartLane() {
     815              :         return myDefaultDepartLane;
     816              :     }
     817              : 
     818              :     /** @brief Inserts edge into the static dictionary
     819              :         Returns true if the key id isn't already in the dictionary. Otherwise
     820              :         returns false. */
     821              :     static bool dictionary(const std::string& id, MSEdge* edge);
     822              : 
     823              :     /** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */
     824              :     static MSEdge* dictionary(const std::string& id);
     825              : 
     826              :     /** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */
     827              :     static MSEdge* dictionaryHint(const std::string& id, const int startIdx);
     828              : 
     829              :     /// @brief Returns all edges with a numerical id
     830              :     static const MSEdgeVector& getAllEdges();
     831              : 
     832              :     /** @brief Clears the dictionary */
     833              :     static void clear();
     834              : 
     835              :     /** @brief Inserts IDs of all known edges into the given vector */
     836              :     static void insertIDs(std::vector<std::string>& into);
     837              : 
     838              :     static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);
     839              : 
     840              :     static void setMesoIgnoredVClasses(SVCPermissions ignored) {
     841         5932 :         myMesoIgnoredVClasses = ignored;
     842              :     }
     843              : 
     844              : public:
     845              :     /// @name Static parser helper
     846              :     /// @{
     847              : 
     848              :     /** @brief Parses the given string assuming it contains a list of edge ids divided by spaces
     849              :      *
     850              :      * Splits the string at spaces, uses polymorph method to generate edge vector.
     851              :      * @param[in] desc The string containing space-separated edge ids
     852              :      * @param[out] into The vector to fill
     853              :      * @param[in] rid The id of the route these description belongs to; used for error message generation
     854              :      * @exception ProcessError If one of the strings contained is not a known edge id
     855              :      */
     856              :     static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
     857              :                                const std::string& rid);
     858              : 
     859              : 
     860              :     /** @brief Parses the given string vector assuming it edge ids
     861              :      * @param[in] desc The string vector containing edge ids
     862              :      * @param[out] into The vector to fill
     863              :      * @param[in] rid The id of the route these description belongs to; used for error message generation
     864              :      * @exception ProcessError If one of the strings contained is not a known edge id
     865              :      */
     866              :     static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
     867              :                                const std::string& rid);
     868              :     /// @}
     869              : 
     870              : 
     871            0 :     ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {
     872            0 :         if (myReversedRoutingEdge == nullptr) {
     873            0 :             myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);
     874              :         }
     875            0 :         return myReversedRoutingEdge;
     876              :     }
     877              : 
     878       378537 :     RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {
     879       378537 :         if (myRailwayRoutingEdge == nullptr) {
     880        50034 :             myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);
     881              :         }
     882       378537 :         return myRailwayRoutingEdge;
     883              :     }
     884              : 
     885              : protected:
     886              :     /** @class by_id_sorter
     887              :      * @brief Sorts edges by their ids
     888              :      */
     889              :     class by_id_sorter {
     890              :     public:
     891              :         /// @brief constructor
     892              :         explicit by_id_sorter() { }
     893              : 
     894              :         /// @brief comparing operator
     895              :         int operator()(const MSEdge* const e1, const MSEdge* const e2) const {
     896              :             return e1->getNumericalID() < e2->getNumericalID();
     897              :         }
     898              : 
     899              :     };
     900              : 
     901              :     /** @class transportable_by_position_sorter
     902              :      * @brief Sorts transportables by their positions
     903              :      */
     904              :     class transportable_by_position_sorter {
     905              :     public:
     906              :         /// @brief constructor
     907              :         explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }
     908              : 
     909              :         /// @brief comparing operator
     910              :         int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;
     911              :     private:
     912              :         SUMOTime myTime;
     913              :     };
     914              : 
     915              : 
     916              :     /// @brief return upper bound for the depart position on this edge
     917              :     double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;
     918              : 
     919              : protected:
     920              :     /// @brief This edge's numerical id
     921              :     const int myNumericalID;
     922              : 
     923              :     /// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index
     924              :     std::shared_ptr<const std::vector<MSLane*> > myLanes;
     925              : 
     926              :     /// @brief This member will do the lane-change
     927              :     MSLaneChanger* myLaneChanger;
     928              : 
     929              :     /// @brief the purpose of the edge
     930              :     const SumoXMLEdgeFunc myFunction;
     931              : 
     932              :     /// @brief Vaporizer counter
     933              :     int myVaporizationRequests;
     934              : 
     935              :     /// @brief The time of last insertion failure
     936              :     mutable SUMOTime myLastFailedInsertionTime;
     937              : 
     938              :     /// @brief A cache for the rejected insertion attempts. Used to assure that no
     939              :     ///        further insertion attempts are made on a lane where an attempt has
     940              :     ///        already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.
     941              :     mutable std::set<int> myFailedInsertionMemory;
     942              : 
     943              :     /// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty
     944              :     std::vector<std::string> myCrossingEdges;
     945              : 
     946              :     /// @brief The succeeding edges
     947              :     MSEdgeVector mySuccessors;
     948              : 
     949              :     MSConstEdgePairVector myViaSuccessors;
     950              : 
     951              :     /// @brief The preceeding edges
     952              :     MSEdgeVector myPredecessors;
     953              : 
     954              :     /// @brief the junctions for this edge
     955              :     MSJunction* myFromJunction;
     956              :     MSJunction* myToJunction;
     957              : 
     958              :     /// @brief Persons on the edge for drawing and pushbutton
     959              :     mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;
     960              : 
     961              :     /// @brief Containers on the edge
     962              :     mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;
     963              : 
     964              :     /// @name Storages for allowed lanes (depending on vehicle classes)
     965              :     /// @{
     966              : 
     967              :     /// @brief Associative container from vehicle class to allowed-lanes.
     968              :     AllowedLanesCont myAllowed;
     969              :     AllowedLanesCont myOrigAllowed;
     970              : 
     971              :     /// @brief From target edge to lanes allowed to be used to reach it
     972              :     AllowedLanesByTarget myAllowedTargets;
     973              :     AllowedLanesByTarget myOrigAllowedTargets;
     974              : 
     975              :     /// @brief The intersection of lane permissions for this edge
     976              :     SVCPermissions myMinimumPermissions = SVCAll;
     977              :     /// @brief The union of lane permissions for this edge
     978              :     SVCPermissions myCombinedPermissions = 0;
     979              : 
     980              :     /// @brief The original intersection of lane permissions for this edge (before temporary modifications)
     981              :     SVCPermissions myOriginalMinimumPermissions = SVCAll;
     982              :     /// @brief The original union of lane permissions for this edge (before temporary modifications)
     983              :     SVCPermissions myOriginalCombinedPermissions = SVCAll;
     984              : 
     985              :     /// @brief whether transient permission changes were applied to this edge or a predecessor
     986              :     bool myHaveTransientPermissions;
     987              :     /// @}
     988              : 
     989              :     /// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr
     990              :     const MSEdge* myOtherTazConnector;
     991              : 
     992              :     /// @brief the real-world name of this edge (need not be unique)
     993              :     std::string myStreetName;
     994              : 
     995              :     /// @brief the type of the edge (optionally used during network creation)
     996              :     std::string myEdgeType;
     997              : 
     998              :     /// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)
     999              :     std::string myRoutingType;
    1000              : 
    1001              :     /// @brief the priority of the edge (used during network creation)
    1002              :     const int myPriority;
    1003              : 
    1004              :     /// @brief the kilometrage/mileage at the start of the edge
    1005              :     const double myDistance;
    1006              : 
    1007              :     /// Edge width [m]
    1008              :     double myWidth;
    1009              : 
    1010              :     /// @brief the length of the edge (cached value for speedup)
    1011              :     double myLength;
    1012              : 
    1013              :     /// @brief the traveltime on the empty edge (cached value for speedup)
    1014              :     double myEmptyTraveltime;
    1015              : 
    1016              :     /// @brief flat penalty when computing traveltime
    1017              :     double myTimePenalty;
    1018              : 
    1019              :     /// @brief whether this edge had a vehicle with less than max speed on it
    1020              :     mutable bool myAmDelayed;
    1021              : 
    1022              :     /// @brief whether this edge belongs to a roundabout
    1023              :     bool myAmRoundabout;
    1024              : 
    1025              :     /// @brief whether this edge is at the network fringe
    1026              :     bool myAmFringe;
    1027              : 
    1028              :     /// @brief the right side for each sublane on this edge
    1029              :     std::vector<double> mySublaneSides;
    1030              : 
    1031              :     /// @name Static edge container
    1032              :     /// @{
    1033              : 
    1034              :     /// @brief definition of the static dictionary type
    1035              :     typedef std::map< std::string, MSEdge* > DictType;
    1036              : 
    1037              :     /** @brief Static dictionary to associate string-ids with objects.
    1038              :      * @deprecated Move to MSEdgeControl, make non-static
    1039              :      */
    1040              :     static DictType myDict;
    1041              : 
    1042              :     /** @brief Static list of edges
    1043              :      * @deprecated Move to MSEdgeControl, make non-static
    1044              :      */
    1045              :     static MSEdgeVector myEdges;
    1046              : 
    1047              :     static SVCPermissions myMesoIgnoredVClasses;
    1048              : 
    1049              :     static DepartLaneDefinition myDefaultDepartLaneDefinition;
    1050              :     static int myDefaultDepartLane;
    1051              :     /// @}
    1052              : 
    1053              : 
    1054              :     /// @brief The successors available for a given vClass
    1055              :     mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;
    1056              : 
    1057              :     /// @brief The successors available for a given vClass
    1058              :     mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;
    1059              :     mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;
    1060              : 
    1061              :     /// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges
    1062              :     Boundary myBoundary;
    1063              : 
    1064              :     /// @brief List of waiting vehicles
    1065              :     mutable std::vector<SUMOVehicle*> myWaiting;
    1066              : 
    1067              : #ifdef HAVE_FOX
    1068              :     /// @brief Mutex for accessing waiting vehicles
    1069              :     mutable FXMutex myWaitingMutex;
    1070              : 
    1071              :     /// @brief Mutex for accessing successor edges
    1072              :     mutable FXMutex mySuccessorMutex;
    1073              : #endif
    1074              : 
    1075              : private:
    1076              : 
    1077              :     /// @brief the oppositing superposable edge
    1078              :     const MSEdge* myBidiEdge;
    1079              : 
    1080              :     /// @brief a reversed version for backward routing
    1081              :     mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;
    1082              :     mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;
    1083              : 
    1084              :     /// @brief Invalidated copy constructor.
    1085              :     MSEdge(const MSEdge&);
    1086              : 
    1087              :     /// @brief assignment operator.
    1088              :     MSEdge& operator=(const MSEdge&) = delete;
    1089              : 
    1090              :     void setBidiLanes();
    1091              : 
    1092              :     bool isSuperposable(const MSEdge* other);
    1093              : 
    1094              :     void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;
    1095              : };
        

Generated by: LCOV version 2.0-1