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

Generated by: LCOV version 2.0-1