LCOV - code coverage report
Current view: top level - src/microsim - MSEdge.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 85.3 % 68 58
Test Date: 2025-12-06 15:35:27 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-2025 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    768874708 :         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              : 
     243              :     inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {
     244       402591 :         const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);
     245       509765 :         return lanes != nullptr && !lanes->empty();
     246              :     }
     247              :     /// @}
     248              : 
     249              : 
     250              : 
     251              :     /// @name Access to other edge attributes
     252              :     /// @{
     253              : 
     254              :     /** @brief Returns the edge type (SumoXMLEdgeFunc)
     255              :      * @return This edge's SumoXMLEdgeFunc
     256              :      * @see SumoXMLEdgeFunc
     257              :      */
     258              :     inline SumoXMLEdgeFunc getFunction() const {
     259      3904249 :         return myFunction;
     260              :     }
     261              : 
     262              :     /// @brief return whether this edge is an internal edge
     263              :     inline bool isNormal() const {
     264     55716321 :         return myFunction == SumoXMLEdgeFunc::NORMAL;
     265              :     }
     266              : 
     267              :     /// @brief return whether this edge is an internal edge
     268              :     inline bool isInternal() const {
     269   3086117479 :         return myFunction == SumoXMLEdgeFunc::INTERNAL;
     270              :     }
     271              : 
     272              :     /// @brief return whether this edge is a pedestrian crossing
     273              :     inline bool isCrossing() const {
     274    187197565 :         return myFunction == SumoXMLEdgeFunc::CROSSING;
     275              :     }
     276              : 
     277              : 
     278              :     /// @brief check and register the opposite superposable edge if any
     279              :     void checkAndRegisterBiDirEdge(const std::string& bidiID = "");
     280              : 
     281              :     /// @brief return opposite superposable/congruent edge, if it exist and 0 else
     282              :     inline const MSEdge* getBidiEdge() const {
     283    147628799 :         return myBidiEdge;
     284              :     }
     285              : 
     286              :     /// @brief return whether this edge is walking area
     287              :     inline bool isWalkingArea() const {
     288    169935716 :         return myFunction == SumoXMLEdgeFunc::WALKINGAREA;
     289              :     }
     290              : 
     291              :     inline bool isTazConnector() const {
     292   5902715862 :         return myFunction == SumoXMLEdgeFunc::CONNECTOR;
     293              :     }
     294              : 
     295              :     void setOtherTazConnector(const MSEdge* edge) {
     296        91423 :         myOtherTazConnector = edge;
     297              :     }
     298              : 
     299              :     const MSEdge* getOtherTazConnector() const {
     300        90280 :         return myOtherTazConnector;
     301              :     }
     302              : 
     303              :     /** @brief Returns the numerical id of the edge
     304              :      * @return This edge's numerical id
     305              :      */
     306              :     inline int getNumericalID() const {
     307    684339675 :         return myNumericalID;
     308              :     }
     309              : 
     310              : 
     311              :     /** @brief Returns the street name of the edge
     312              :      */
     313              :     const std::string& getStreetName() const {
     314            0 :         return myStreetName;
     315              :     }
     316              : 
     317              :     /** @brief Returns the type of the edge
     318              :      */
     319              :     const std::string& getEdgeType() const {
     320      2588564 :         return myEdgeType;
     321              :     }
     322              : 
     323              :     /** @brief Returns the type of the edge
     324              :      */
     325              :     const std::string& getRoutingType() const {
     326         3311 :         return myRoutingType.empty() ? myEdgeType : myRoutingType;
     327              :     }
     328              : 
     329              :     double getPreference(const SUMOVTypeParameter& pars) const;
     330              : 
     331              :     // @brief try to infer edge type for internal edges
     332              :     void inferEdgeType();
     333              : 
     334              :     /** @brief Returns the priority of the edge
     335              :      */
     336              :     int getPriority() const {
     337       731084 :         return myPriority;
     338              :     }
     339              : 
     340              :     /** @brief Returns the kilometrage/mileage encoding at the start of the edge
     341              :      * (negative values encode descending direction)
     342              :     */
     343              :     double getDistance() const {
     344            0 :         return myDistance;
     345              :     }
     346              : 
     347              :     /** @brief Returns the kilometrage/mileage at the given offset along the edge
     348              :      */
     349              :     double getDistanceAt(double pos) const;
     350              : 
     351              :     bool hasDistance() const {
     352            0 :         return myDistance != 0;
     353              :     }
     354              :     /// @}
     355              : 
     356              :     /**@brief Sets the crossed edge ids for a crossing edge
     357              :      *
     358              :      */
     359        16574 :     void setCrossingEdges(const std::vector<std::string>& crossingEdges)        {
     360              :         myCrossingEdges.clear();
     361        16574 :         myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());
     362        16574 :     }
     363              : 
     364              :     /**@brief Gets the crossed edge ids
     365              :      *@return The list of crossed edge ids in a crossing edge or an empty vector
     366              :      */
     367              :     const std::vector<std::string>& getCrossingEdges() const {
     368              :         return myCrossingEdges;
     369              :     }
     370              : 
     371              : 
     372              :     /// @name Access to succeeding/predecessing edges
     373              :     /// @{
     374              : 
     375              :     /** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge
     376              :      *
     377              :      * This is mainly used by the taz (district) parsing
     378              :      * @param[in] edge The edge to add
     379              :      */
     380              :     void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);
     381              : 
     382              :     void resetTAZ(MSJunction* junction);
     383              : 
     384              :     /** @brief Returns the number of edges that may be reached from this edge
     385              :      * @return The number of following edges
     386              :      */
     387              :     int getNumSuccessors() const {
     388      1192834 :         return (int) mySuccessors.size();
     389              :     }
     390              : 
     391              : 
     392              :     /** @brief Returns the following edges, restricted by vClass
     393              :      * @param[in] vClass The vClass for which to restrict the successors
     394              :      * @return The eligible following edges
     395              :      */
     396              :     const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
     397              : 
     398              :     /** @brief Returns the following edges with internal vias, restricted by vClass
     399              :      * @param[in] vClass The vClass for which to restrict the successors
     400              :      * @return The eligible following edges
     401              :      */
     402              :     const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;
     403              : 
     404              : 
     405              :     /** @brief Returns the number of edges this edge is connected to
     406              :      *
     407              :      * @return The number of edges following this edge
     408              :      */
     409              :     int getNumPredecessors() const {
     410       706017 :         return (int) myPredecessors.size();
     411              :     }
     412              : 
     413              : 
     414              :     /** @brief
     415              :      * @return
     416              :      */
     417              :     const MSEdgeVector& getPredecessors() const {
     418      5230243 :         return myPredecessors;
     419              :     }
     420              : 
     421              : 
     422              :     const MSJunction* getFromJunction() const {
     423     21486094 :         return myFromJunction;
     424              :     }
     425              : 
     426              :     const MSJunction* getToJunction() const {
     427    660034685 :         return myToJunction;
     428              :     }
     429              : 
     430              : 
     431              :     void setJunctions(MSJunction* from, MSJunction* to);
     432              :     /// @}
     433              : 
     434              : 
     435              : 
     436              :     /// @name Access to vaporizing interface
     437              :     /// @{
     438              : 
     439              :     /** @brief Returns whether vehicles on this edge shall be vaporized
     440              :      * @return Whether no vehicle shall be on this edge
     441              :      */
     442              :     bool isVaporizing() const {
     443   5754608856 :         return myVaporizationRequests > 0;
     444              :     }
     445              : 
     446              : 
     447              :     /** @brief Enables vaporization
     448              :      *
     449              :      * The internal vaporization counter is increased enabling the
     450              :      *  vaporization.
     451              :      * Called from the event handler.
     452              :      * @param[in] t The current time (unused)
     453              :      * @return Time to next call (always 0)
     454              :      * @exception ProcessError not thrown by this method, just derived
     455              :      */
     456              :     SUMOTime incVaporization(SUMOTime t);
     457              : 
     458              : 
     459              :     /** @brief Disables vaporization
     460              :      *
     461              :      * The internal vaporization counter is decreased what disables
     462              :      *  the vaporization if it was only once enabled.
     463              :      * Called from the event handler.
     464              :      * @param[in] t The current time (unused)
     465              :      * @return Time to next call (always 0)
     466              :      * @exception ProcessError not thrown by this method, just derived
     467              :      */
     468              :     SUMOTime decVaporization(SUMOTime t);
     469              :     /// @}
     470              : 
     471              : 
     472              :     /** @brief Computes and returns the current travel time for this edge
     473              :      *
     474              :      * The mean speed of all lanes is used to compute the travel time.
     475              :      * To avoid infinite travel times, the given minimum speed is used.
     476              :      *
     477              :      * @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped
     478              :      * @return The current effort (travel time) to pass the edge
     479              :      */
     480              :     double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;
     481              : 
     482              : 
     483              :     /// @brief returns the minimum travel time for the given vehicle
     484    181990078 :     inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {
     485    181996261 :         if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {
     486              :             return 0;
     487    168620267 :         } else if (veh != 0) {
     488    168487229 :             return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;
     489              :         } else {
     490       139167 :             return myEmptyTraveltime;
     491              :         }
     492              :     }
     493              : 
     494            0 :     double getTimePenalty() const {
     495      4088343 :         return myTimePenalty;
     496              :     }
     497              : 
     498              :     /** @brief Returns the travel time for the given edge
     499              :      *
     500              :      * @param[in] edge The edge for which the travel time shall be retrieved
     501              :      * @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
     502              :      * @param[in] time The time for which the travel time shall be returned [s]
     503              :      * @return The traveltime needed by the given vehicle to pass the edge at the given time
     504              :      */
     505              :     static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {
     506        59372 :         return MSNet::getInstance()->getTravelTime(edge, veh, time);
     507              :     }
     508              : 
     509              :     static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);
     510              : 
     511              :     /** @brief Returns the averaged speed used by the routing device
     512              :      */
     513              :     double getRoutingSpeed() const;
     514              : 
     515              : 
     516              :     /// @name Methods releated to vehicle insertion
     517              :     /// @{
     518              : 
     519              :     /** @brief Tries to insert the given vehicle into the network
     520              :      *
     521              :      * The procedure for choosing the proper lane is determined, first.
     522              :      *  In dependence to this, the proper lane is chosen.
     523              :      *
     524              :      * Insertion itself is done by calling the chose lane's "insertVehicle"
     525              :      *  method but only if the checkOnly argument is false. The check needs
     526              :      *  to be certain only in the negative case (if false is returned, there
     527              :      *  is no way this vehicle would be inserted).
     528              :      *
     529              :      * @param[in] v The vehicle to insert
     530              :      * @param[in] time The current simulation time
     531              :      * @param[in] checkOnly Whether we perform only the check without actually inserting
     532              :      * @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle
     533              :      *            or whether insertion on lanes for which an insertion has already a failed should be ignored
     534              :      *            in the current time step.
     535              :      * @return Whether the vehicle could be inserted
     536              :      * @see MSLane::insertVehicle
     537              :      */
     538              :     bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;
     539              : 
     540              :     /// @brief check whether the given departSpeed is valid for this edge
     541              :     bool validateDepartSpeed(SUMOVehicle& v) const;
     542              : 
     543              :     /** @brief Finds the emptiest lane allowing the vehicle class
     544              :      *
     545              :      * The emptiest lane is the one which vehicle insertion is most likely to succeed.
     546              :      *
     547              :      * If there are no vehicles before departPos, then the lane with the largest
     548              :      * gap between departPos and the last vehicle is
     549              :      * Otheriwise the lane with lowes occupancy is selected
     550              :      * If there is more than one, the first according to its
     551              :      *  index in the lane container is chosen.
     552              :      *
     553              :      * If allowed==0, the lanes allowed for the given vehicle class
     554              :      *  will be used.
     555              :      *
     556              :      * @param[in] allowed The lanes to choose from
     557              :      * @param[in] vclass The vehicle class to look for
     558              :      * @param[in] departPos An upper bound on vehicle depart position
     559              :      * @return the least occupied lane
     560              :      * @see allowedLanes
     561              :      */
     562              :     MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;
     563              : 
     564              :     /** @brief Finds the most probable lane allowing the vehicle class
     565              :      *
     566              :      * The most probable lane is the one which best corresponds to the desired speed of the vehicle
     567              :      * Vehicles with lower speeds will use lanes to the right while
     568              :      * vehicles with higher speeds will use lanes to the left
     569              :      *
     570              :      * @param[in] allowed The lanes to choose from
     571              :      * @param[in] vclass The vehicle class to look for
     572              :      * @param[in] departPos An upper bound on vehicle depart position
     573              :      * @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)
     574              :      * @return the least occupied lane
     575              :      * @see allowedLanes
     576              :      */
     577              :     MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;
     578              : 
     579              : 
     580              :     /** @brief Finds a depart lane for the given vehicle parameters
     581              :      *
     582              :      * Depending on the depart lane procedure a depart lane is chosen.
     583              :      *  Repeated calls with the same vehicle may return different results
     584              :      *  if the procedure is "random" or "free". In case no appropriate
     585              :      *  lane was found, 0 is returned.
     586              :      *
     587              :      * @param[in] veh The vehicle to get the depart lane for
     588              :      * @return a possible/chosen depart lane, 0 if no lane can be used
     589              :      */
     590              :     MSLane* getDepartLane(MSVehicle& veh) const;
     591              : 
     592              :     /* @brief get the rightmost lane that allows the given vClass or nullptr
     593              :      * @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden
     594              :      */
     595              :     MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;
     596              : 
     597              :     /// @brief consider given departLane parameter (only for validating speeds)
     598              :     MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;
     599              : 
     600              :     /** @brief Returns the last time a vehicle could not be inserted
     601              :      * @return The current value
     602              :      */
     603              :     inline SUMOTime getLastFailedInsertionTime() const {
     604              :         return myLastFailedInsertionTime;
     605              :     }
     606              : 
     607              : 
     608              :     /** @brief Sets the last time a vehicle could not be inserted
     609              :      * @param[in] time the new value
     610              :      */
     611              :     inline void setLastFailedInsertionTime(SUMOTime time) const {
     612   2137005827 :         myLastFailedInsertionTime = time;
     613              :     }
     614              :     /// @}
     615              : 
     616              : 
     617              :     /** @brief Performs lane changing on this edge */
     618              :     void changeLanes(SUMOTime t) const;
     619              : 
     620              : 
     621              :     /// @todo extension: inner junctions are not filled
     622              :     const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
     623              : 
     624              : 
     625              :     /// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.
     626              :     double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;
     627              : 
     628              :     /// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
     629              :     const MSEdge* getNormalBefore() const;
     630              : 
     631              :     /// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself
     632              :     const MSEdge* getNormalSuccessor() const;
     633              : 
     634              :     /// @brief Returns whether the vehicle (class) is not allowed on the edge
     635    653046107 :     inline bool prohibits(const SUMOVehicle* const vehicle) const {
     636    653046107 :         if (vehicle == nullptr) {
     637              :             return false;
     638              :         }
     639    653045314 :         const SUMOVehicleClass svc = vehicle->getVClass();
     640    653045314 :         return (vehicle->ignoreTransientPermissions()
     641    653045314 :                 ? (myOriginalCombinedPermissions & svc) != svc
     642    652990239 :                 : (myCombinedPermissions & svc) != svc);
     643              :     }
     644              : 
     645              :     bool hasTransientPermissions() const;
     646              : 
     647              :     /** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it
     648              :      * The restriction mechanism is not implemented yet for the microsim, so it always returns false.
     649              :      * @param[in] vehicle The vehicle for which the information has to be returned
     650              :      * @return Whether the vehicle must not enter this edge
     651              :      */
     652              :     inline bool restricts(const SUMOVehicle* const /* vehicle */) const {
     653              :         return false;
     654              :     }
     655              : 
     656              :     /// @brief Returns the combined permissions of all lanes of this edge
     657              :     inline SVCPermissions getPermissions() const {
     658   2732048817 :         return myCombinedPermissions;
     659              :     }
     660              : 
     661              :     /** @brief Returns the edges's width (sum over all lanes)
     662              :      * @return This edges's width
     663              :      */
     664              :     double getWidth() const {
     665    680664057 :         return myWidth;
     666              :     }
     667              : 
     668              :     /// @brief Returns the right side offsets of this edge's sublanes
     669              :     const std::vector<double> getSubLaneSides() const {
     670    275022999 :         return mySublaneSides;
     671              :     }
     672              : 
     673              :     void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);
     674              : 
     675              :     void rebuildAllowedTargets(const bool updateVehicles = true);
     676              : 
     677              : 
     678              :     /** @brief optimistic air distance heuristic for use in routing
     679              :      * @param[in] other The edge to which the distance shall be returned
     680              :      * @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes
     681              :      * @return The distance to the other edge
     682              :      */
     683              :     double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;
     684              : 
     685              : 
     686              :     /// @brief return the coordinates of the center of the given stop
     687              :     static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
     688              : 
     689              : 
     690              :     /** @brief return the length of the edge
     691              :      * @return The edge's length
     692              :      */
     693              :     inline double getLength() const {
     694    690795587 :         return myLength;
     695              :     }
     696              : 
     697              : 
     698              :     /** @brief Returns the speed limit of the edge
     699              :      * @caution The speed limit of the first lane is retured; should probably be the fastest edge
     700              :      * @return The maximum speed allowed on this edge
     701              :      */
     702              :     double getSpeedLimit() const;
     703              : 
     704              :     /// @brief return shape.length() / myLength
     705              :     double getLengthGeometryFactor() const;
     706              : 
     707              :     /** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
     708              :      * @param[in] val the new speed in m/s
     709              :      */
     710              :     void setMaxSpeed(double val, double jamThreshold = -1);
     711              : 
     712              :     /** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]
     713              :     * @param[in] val the new coefficient in [0..1]
     714              :     */
     715              :     void setFrictionCoefficient(double val) const;
     716              : 
     717              :     /** @brief Returns the maximum speed the vehicle may use on this edge
     718              :      *
     719              :      * @caution Only the first lane is considered
     720              :      * @return The maximum velocity on this edge for the given vehicle
     721              :      */
     722              :     double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;
     723              : 
     724              : 
     725              :     virtual void addTransportable(MSTransportable* t) const;
     726              : 
     727              :     virtual void removeTransportable(MSTransportable* t) const;
     728              : 
     729              :     inline bool isRoundabout() const {
     730   1972732431 :         return myAmRoundabout;
     731              :     }
     732              : 
     733              :     void markAsRoundabout() {
     734         6508 :         myAmRoundabout = true;
     735         6508 :     }
     736              : 
     737              :     void markDelayed() const {
     738     69892113 :         myAmDelayed = true;
     739     51625874 :     }
     740              : 
     741              :     // return whether there have been vehicles on this or the bidi edge (if there is any) at least once
     742              :     inline bool isDelayed() const {
     743    746814275 :         return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);
     744              :     }
     745              : 
     746              :     bool hasLaneChanger() const {
     747   1671299067 :         return myLaneChanger != nullptr;
     748              :     }
     749              : 
     750              :     /// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index
     751              :     std::pair<double, SUMOTime> getLastBlocked(int index) const;
     752              : 
     753              :     /// @brief whether this edge allows changing to the opposite direction edge
     754              :     bool canChangeToOpposite() const;
     755              : 
     756              :     /// @brief Returns the opposite direction edge if on exists else a nullptr
     757              :     const MSEdge* getOppositeEdge() const;
     758              : 
     759              :     /// @brief get the mean speed
     760              :     double getMeanSpeed() const;
     761              : 
     762              :     /// @brief get the mean friction over the lanes
     763              :     double getMeanFriction() const;
     764              : 
     765              :     /// @brief get the mean speed of all bicycles on this edge
     766              :     double getMeanSpeedBike() const;
     767              : 
     768              :     /// @brief whether any lane has a minor link
     769              :     bool hasMinorLink() const;
     770              : 
     771              :     /// @brief return whether this edge is at the fringe of the network
     772              :     bool isFringe() const {
     773    319846338 :         return myAmFringe;
     774              :     }
     775              : 
     776              :     /// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index
     777              :     bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;
     778              : 
     779              :     /// @brief whether this lane is selected in the GUI
     780            0 :     virtual bool isSelected() const {
     781            0 :         return false;
     782              :     }
     783              : 
     784              :     /// @brief grant exclusive access to the mesoscopic state
     785     34287854 :     virtual void lock() const {}
     786              : 
     787              :     /// @brief release exclusive access to the mesoscopic state
     788     34287854 :     virtual void unlock() const {};
     789              : 
     790              :     /// @brief Adds a vehicle to the list of waiting vehicles
     791              :     void addWaiting(SUMOVehicle* vehicle) const;
     792              : 
     793              :     /// @brief Removes a vehicle from the list of waiting vehicles
     794              :     void removeWaiting(const SUMOVehicle* vehicle) const;
     795              : 
     796              :     /* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position
     797              :      * @param[in] transportable The person or container that wants to ride
     798              :      * @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance
     799              :      */
     800              :     SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;
     801              : 
     802              :     /** @brief Remove all transportables before quick-loading state */
     803              :     void clearState();
     804              : 
     805              :     /// @brief update meso segment parameters
     806              :     void updateMesoType();
     807              : 
     808              :     static DepartLaneDefinition& getDefaultDepartLaneDefinition() {
     809              :         return myDefaultDepartLaneDefinition;
     810              :     }
     811              : 
     812              :     static int& getDefaultDepartLane() {
     813              :         return myDefaultDepartLane;
     814              :     }
     815              : 
     816              :     /** @brief Inserts edge into the static dictionary
     817              :         Returns true if the key id isn't already in the dictionary. Otherwise
     818              :         returns false. */
     819              :     static bool dictionary(const std::string& id, MSEdge* edge);
     820              : 
     821              :     /** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */
     822              :     static MSEdge* dictionary(const std::string& id);
     823              : 
     824              :     /** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */
     825              :     static MSEdge* dictionaryHint(const std::string& id, const int startIdx);
     826              : 
     827              :     /// @brief Returns all edges with a numerical id
     828              :     static const MSEdgeVector& getAllEdges();
     829              : 
     830              :     /** @brief Clears the dictionary */
     831              :     static void clear();
     832              : 
     833              :     /** @brief Inserts IDs of all known edges into the given vector */
     834              :     static void insertIDs(std::vector<std::string>& into);
     835              : 
     836              :     static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);
     837              : 
     838              :     static void setMesoIgnoredVClasses(SVCPermissions ignored) {
     839         5822 :         myMesoIgnoredVClasses = ignored;
     840              :     }
     841              : 
     842              : public:
     843              :     /// @name Static parser helper
     844              :     /// @{
     845              : 
     846              :     /** @brief Parses the given string assuming it contains a list of edge ids divided by spaces
     847              :      *
     848              :      * Splits the string at spaces, uses polymorph method to generate edge vector.
     849              :      * @param[in] desc The string containing space-separated edge ids
     850              :      * @param[out] into The vector to fill
     851              :      * @param[in] rid The id of the route these description belongs to; used for error message generation
     852              :      * @exception ProcessError If one of the strings contained is not a known edge id
     853              :      */
     854              :     static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
     855              :                                const std::string& rid);
     856              : 
     857              : 
     858              :     /** @brief Parses the given string vector assuming it edge ids
     859              :      * @param[in] desc The string vector containing edge ids
     860              :      * @param[out] into The vector to fill
     861              :      * @param[in] rid The id of the route these description belongs to; used for error message generation
     862              :      * @exception ProcessError If one of the strings contained is not a known edge id
     863              :      */
     864              :     static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
     865              :                                const std::string& rid);
     866              :     /// @}
     867              : 
     868              : 
     869            0 :     ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {
     870            0 :         if (myReversedRoutingEdge == nullptr) {
     871            0 :             myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);
     872              :         }
     873            0 :         return myReversedRoutingEdge;
     874              :     }
     875              : 
     876       377999 :     RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {
     877       377999 :         if (myRailwayRoutingEdge == nullptr) {
     878        49786 :             myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);
     879              :         }
     880       377999 :         return myRailwayRoutingEdge;
     881              :     }
     882              : 
     883              : protected:
     884              :     /** @class by_id_sorter
     885              :      * @brief Sorts edges by their ids
     886              :      */
     887              :     class by_id_sorter {
     888              :     public:
     889              :         /// @brief constructor
     890              :         explicit by_id_sorter() { }
     891              : 
     892              :         /// @brief comparing operator
     893              :         int operator()(const MSEdge* const e1, const MSEdge* const e2) const {
     894              :             return e1->getNumericalID() < e2->getNumericalID();
     895              :         }
     896              : 
     897              :     };
     898              : 
     899              :     /** @class transportable_by_position_sorter
     900              :      * @brief Sorts transportables by their positions
     901              :      */
     902              :     class transportable_by_position_sorter {
     903              :     public:
     904              :         /// @brief constructor
     905              :         explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }
     906              : 
     907              :         /// @brief comparing operator
     908              :         int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;
     909              :     private:
     910              :         SUMOTime myTime;
     911              :     };
     912              : 
     913              : 
     914              :     /// @brief return upper bound for the depart position on this edge
     915              :     double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;
     916              : 
     917              : protected:
     918              :     /// @brief This edge's numerical id
     919              :     const int myNumericalID;
     920              : 
     921              :     /// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index
     922              :     std::shared_ptr<const std::vector<MSLane*> > myLanes;
     923              : 
     924              :     /// @brief This member will do the lane-change
     925              :     MSLaneChanger* myLaneChanger;
     926              : 
     927              :     /// @brief the purpose of the edge
     928              :     const SumoXMLEdgeFunc myFunction;
     929              : 
     930              :     /// @brief Vaporizer counter
     931              :     int myVaporizationRequests;
     932              : 
     933              :     /// @brief The time of last insertion failure
     934              :     mutable SUMOTime myLastFailedInsertionTime;
     935              : 
     936              :     /// @brief A cache for the rejected insertion attempts. Used to assure that no
     937              :     ///        further insertion attempts are made on a lane where an attempt has
     938              :     ///        already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.
     939              :     mutable std::set<int> myFailedInsertionMemory;
     940              : 
     941              :     /// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty
     942              :     std::vector<std::string> myCrossingEdges;
     943              : 
     944              :     /// @brief The succeeding edges
     945              :     MSEdgeVector mySuccessors;
     946              : 
     947              :     MSConstEdgePairVector myViaSuccessors;
     948              : 
     949              :     /// @brief The preceeding edges
     950              :     MSEdgeVector myPredecessors;
     951              : 
     952              :     /// @brief the junctions for this edge
     953              :     MSJunction* myFromJunction;
     954              :     MSJunction* myToJunction;
     955              : 
     956              :     /// @brief Persons on the edge for drawing and pushbutton
     957              :     mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;
     958              : 
     959              :     /// @brief Containers on the edge
     960              :     mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;
     961              : 
     962              :     /// @name Storages for allowed lanes (depending on vehicle classes)
     963              :     /// @{
     964              : 
     965              :     /// @brief Associative container from vehicle class to allowed-lanes.
     966              :     AllowedLanesCont myAllowed;
     967              :     AllowedLanesCont myOrigAllowed;
     968              : 
     969              :     /// @brief From target edge to lanes allowed to be used to reach it
     970              :     AllowedLanesByTarget myAllowedTargets;
     971              :     AllowedLanesByTarget myOrigAllowedTargets;
     972              : 
     973              :     /// @brief The intersection of lane permissions for this edge
     974              :     SVCPermissions myMinimumPermissions = SVCAll;
     975              :     /// @brief The union of lane permissions for this edge
     976              :     SVCPermissions myCombinedPermissions = 0;
     977              : 
     978              :     /// @brief The original intersection of lane permissions for this edge (before temporary modifications)
     979              :     SVCPermissions myOriginalMinimumPermissions = SVCAll;
     980              :     /// @brief The original union of lane permissions for this edge (before temporary modifications)
     981              :     SVCPermissions myOriginalCombinedPermissions;
     982              : 
     983              :     /// @brief whether transient permission changes were applied to this edge or a predecessor
     984              :     bool myHaveTransientPermissions;
     985              :     /// @}
     986              : 
     987              :     /// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr
     988              :     const MSEdge* myOtherTazConnector;
     989              : 
     990              :     /// @brief the real-world name of this edge (need not be unique)
     991              :     std::string myStreetName;
     992              : 
     993              :     /// @brief the type of the edge (optionally used during network creation)
     994              :     std::string myEdgeType;
     995              : 
     996              :     /// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)
     997              :     std::string myRoutingType;
     998              : 
     999              :     /// @brief the priority of the edge (used during network creation)
    1000              :     const int myPriority;
    1001              : 
    1002              :     /// @brief the kilometrage/mileage at the start of the edge
    1003              :     const double myDistance;
    1004              : 
    1005              :     /// Edge width [m]
    1006              :     double myWidth;
    1007              : 
    1008              :     /// @brief the length of the edge (cached value for speedup)
    1009              :     double myLength;
    1010              : 
    1011              :     /// @brief the traveltime on the empty edge (cached value for speedup)
    1012              :     double myEmptyTraveltime;
    1013              : 
    1014              :     /// @brief flat penalty when computing traveltime
    1015              :     double myTimePenalty;
    1016              : 
    1017              :     /// @brief whether this edge had a vehicle with less than max speed on it
    1018              :     mutable bool myAmDelayed;
    1019              : 
    1020              :     /// @brief whether this edge belongs to a roundabout
    1021              :     bool myAmRoundabout;
    1022              : 
    1023              :     /// @brief whether this edge is at the network fringe
    1024              :     bool myAmFringe;
    1025              : 
    1026              :     /// @brief the right side for each sublane on this edge
    1027              :     std::vector<double> mySublaneSides;
    1028              : 
    1029              :     /// @name Static edge container
    1030              :     /// @{
    1031              : 
    1032              :     /// @brief definition of the static dictionary type
    1033              :     typedef std::map< std::string, MSEdge* > DictType;
    1034              : 
    1035              :     /** @brief Static dictionary to associate string-ids with objects.
    1036              :      * @deprecated Move to MSEdgeControl, make non-static
    1037              :      */
    1038              :     static DictType myDict;
    1039              : 
    1040              :     /** @brief Static list of edges
    1041              :      * @deprecated Move to MSEdgeControl, make non-static
    1042              :      */
    1043              :     static MSEdgeVector myEdges;
    1044              : 
    1045              :     static SVCPermissions myMesoIgnoredVClasses;
    1046              : 
    1047              :     static DepartLaneDefinition myDefaultDepartLaneDefinition;
    1048              :     static int myDefaultDepartLane;
    1049              :     /// @}
    1050              : 
    1051              : 
    1052              :     /// @brief The successors available for a given vClass
    1053              :     mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;
    1054              : 
    1055              :     /// @brief The successors available for a given vClass
    1056              :     mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;
    1057              :     mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;
    1058              : 
    1059              :     /// @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
    1060              :     Boundary myBoundary;
    1061              : 
    1062              :     /// @brief List of waiting vehicles
    1063              :     mutable std::vector<SUMOVehicle*> myWaiting;
    1064              : 
    1065              : #ifdef HAVE_FOX
    1066              :     /// @brief Mutex for accessing waiting vehicles
    1067              :     mutable FXMutex myWaitingMutex;
    1068              : 
    1069              :     /// @brief Mutex for accessing successor edges
    1070              :     mutable FXMutex mySuccessorMutex;
    1071              : #endif
    1072              : 
    1073              : private:
    1074              : 
    1075              :     /// @brief the oppositing superposable edge
    1076              :     const MSEdge* myBidiEdge;
    1077              : 
    1078              :     /// @brief a reversed version for backward routing
    1079              :     mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;
    1080              :     mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;
    1081              : 
    1082              :     /// @brief Invalidated copy constructor.
    1083              :     MSEdge(const MSEdge&);
    1084              : 
    1085              :     /// @brief assignment operator.
    1086              :     MSEdge& operator=(const MSEdge&) = delete;
    1087              : 
    1088              :     void setBidiLanes();
    1089              : 
    1090              :     bool isSuperposable(const MSEdge* other);
    1091              : 
    1092              :     void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;
    1093              : };
        

Generated by: LCOV version 2.0-1