/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file MSEdge.h14/// @author Christian Roessel15/// @author Daniel Krajzewicz16/// @author Jakob Erdmann17/// @author Sascha Krieg18/// @author Michael Behrisch19/// @date Mon, 12 Mar 200120///21// A road/street connecting two junctions22/****************************************************************************/23#pragma once24#include <config.h>2526#include <vector>27#include <map>28#include <string>29#include <iostream>30#ifdef HAVE_FOX31#include <utils/foxtools/fxheader.h>32#endif33#include <utils/common/Named.h>34#include <utils/common/Parameterised.h>35#include <utils/common/SUMOTime.h>36#include <utils/common/SUMOVehicleClass.h>37#include <utils/geom/Boundary.h>38#include <utils/router/ReversedEdge.h>39#include <utils/router/RailEdge.h>40#include <utils/vehicle/SUMOVehicle.h>41#include <utils/vehicle/SUMOTrafficObject.h>42#include "MSNet.h"434445// ===========================================================================46// class declarations47// ===========================================================================48class Boundary;49class OutputDevice;50class SUMOVehicle;51class SUMOVehicleParameter;52class MSVehicle;53class MSLane;54class MSLaneChanger;55class MSPerson;56class MSJunction;57class MSEdge;58class MSTransportable;596061// ===========================================================================62// class definitions63// ===========================================================================64/**65* @class MSEdge66* @brief A road/street connecting two junctions67*68* A single connection between two junctions.69* Holds lanes which are reponsible for vehicle movements.70*/7172typedef std::vector<MSEdge*> MSEdgeVector;73typedef std::vector<const MSEdge*> ConstMSEdgeVector;74typedef std::vector<std::pair<const MSEdge*, const MSEdge*> > MSConstEdgePairVector;7576class MSEdge : public Named, public Parameterised {77private:78/** @brief "Map" from vehicle class to allowed lanes */79typedef std::vector<std::pair<SVCPermissions, std::shared_ptr<const std::vector<MSLane*> > > > AllowedLanesCont;8081/** @brief Succeeding edges (keys) and allowed lanes to reach these edges (values). */82typedef std::map<const MSEdge*, AllowedLanesCont> AllowedLanesByTarget;838485public:86friend class MSLaneChangerSublane; // needs access to myLaneChanger8788/** @brief Constructor.89*90* After calling this constructor, the edge is not yet initialised91* completely. A call to "initialize" with proper values is needed92* for this.93*94* @param[in] id The id of the edge95* @param[in] numericalID The numerical id (index) of the edge96* @param[in] function A basic type of the edge97* @param[in] streetName The street name for that edge98*/99MSEdge(const std::string& id, int numericalID, const SumoXMLEdgeFunc function,100const std::string& streetName, const std::string& edgeType,101const std::string& routingType, int priority, double distance);102103104/// @brief Destructor.105virtual ~MSEdge();106107108/** @brief Initialize the edge.109*110* @param[in] allowed Information which edges may be reached from which lanes111* @param[in] lanes List of this edge's lanes112*/113void initialize(const std::vector<MSLane*>* lanes);114115116/** @brief Recalculates the cached values117*/118void recalcCache();119120121/// @todo Has to be called after all edges were built and all connections were set...; Still, is not very nice122virtual void closeBuilding();123124/// Has to be called after all sucessors and predecessors have been set (after closeBuilding())125void buildLaneChanger();126127/* @brief returns whether initizliaing a lane change is permitted on this edge128* @note Has to be called after all sucessors and predecessors have been set (after closeBuilding())129*/130bool allowsLaneChanging() const;131132/// @name Access to the edge's lanes133/// @{134135/** @brief Returns the lane left to the one given, 0 if the given lane is leftmost136*137* @param[in] lane The lane right to the one to be returned138* @return The lane left to the given, 0 if no such lane exists139* @todo This method searches for the given in the container; probably, this could be done faster140*/141MSLane* leftLane(const MSLane* const lane) const;142143144/** @brief Returns the lane right to the one given, 0 if the given lane is rightmost145*146* @param[in] lane The lane left to the one to be returned147* @return The lane right to the given, 0 if no such lane exists148* @todo This method searches for the given in the container; probably, this could be done faster149*/150MSLane* rightLane(const MSLane* const lane) const;151152153/** @brief Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist154*155* @param[in] lane The base lane156* @param[in] offset The offset of the result lane157* @param[in] includeOpposte Whether an opposite direction lane may be returned158* @todo This method searches for the given in the container; probably, this could be done faster159*/160MSLane* parallelLane(const MSLane* const lane, int offset, bool includeOpposite = true) const;161162163/** @brief Returns this edge's lanes164*165* @return This edge's lanes166*/167inline const std::vector<MSLane*>& getLanes() const {168return *myLanes;169}170171inline int getNumLanes() const {172return (int)myLanes->size();173}174175/// @brief return the number of lanes that permit non-weak modes if the edge allows non weak modes and the number of lanes otherwise176int getNumDrivingLanes() const;177178/// @brief return total number of vehicles on this edges lanes or segments179int getVehicleNumber() const;180181/// @brief whether this edge has no vehicles182bool isEmpty() const;183184/// @brief return vehicles on this edges lanes or segments185std::vector<const SUMOVehicle*> getVehicles() const;186187double getBruttoOccupancy() const;188189/// @brief return flow based on meanSpead @note: may produced incorrect results when jammed190double getFlow() const;191192/// @brief return accumated waiting time for all vehicles on this edges lanes or segments193double getWaitingSeconds() const;194195/// @brief return mean occupancy on this edges lanes or segments196double getOccupancy() const;197198/** @brief Returns this edge's persons set.199* @brief Avoids the creation of new vector as in getSortedPersons200*201* @return This edge's persons.202*/203inline const std::set<MSTransportable*, ComparatorNumericalIdLess>& getPersons() const {204return myPersons;205}206207/** @brief Returns this edge's persons sorted by pos208*209* @return This edge's persons sorted by pos210*/211std::vector<MSTransportable*> getSortedPersons(SUMOTime timestep, bool includeRiding = false) const;212213214/** @brief Returns this edge's containers sorted by pos215*216* @return This edge's containers sorted by pos217*/218std::vector<MSTransportable*> getSortedContainers(SUMOTime timestep, bool includeRiding = false) const;219220/** @brief Get the allowed lanes to reach the destination-edge.221*222* If there is no such edge, return nullptr. Then you are on the wrong edge.223*224* @param[in] destination The edge to reach225* @param[in] vclass The vehicle class for which this information shall be returned226* @return The lanes that may be used to reach the given edge, nullptr if no such lanes exist227*/228const std::vector<MSLane*>* allowedLanes(const MSEdge& destination,229SUMOVehicleClass vclass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;230231232233/** @brief Get the allowed lanes for the given vehicle class.234*235* If there is no such edge, return nullptr. Then you are on the wrong edge.236*237* @param[in] vclass The vehicle class for which this information shall be returned238* @return The lanes that may be used by the given vclass239*/240const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass = SVC_IGNORING) const;241242inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {243const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);244return lanes != nullptr && !lanes->empty();245}246/// @}247248249250/// @name Access to other edge attributes251/// @{252253/** @brief Returns the edge type (SumoXMLEdgeFunc)254* @return This edge's SumoXMLEdgeFunc255* @see SumoXMLEdgeFunc256*/257inline SumoXMLEdgeFunc getFunction() const {258return myFunction;259}260261/// @brief return whether this edge is an internal edge262inline bool isNormal() const {263return myFunction == SumoXMLEdgeFunc::NORMAL;264}265266/// @brief return whether this edge is an internal edge267inline bool isInternal() const {268return myFunction == SumoXMLEdgeFunc::INTERNAL;269}270271/// @brief return whether this edge is a pedestrian crossing272inline bool isCrossing() const {273return myFunction == SumoXMLEdgeFunc::CROSSING;274}275276277/// @brief check and register the opposite superposable edge if any278void checkAndRegisterBiDirEdge(const std::string& bidiID = "");279280/// @brief return opposite superposable/congruent edge, if it exist and 0 else281inline const MSEdge* getBidiEdge() const {282return myBidiEdge;283}284285/// @brief return whether this edge is walking area286inline bool isWalkingArea() const {287return myFunction == SumoXMLEdgeFunc::WALKINGAREA;288}289290inline bool isTazConnector() const {291return myFunction == SumoXMLEdgeFunc::CONNECTOR;292}293294void setOtherTazConnector(const MSEdge* edge) {295myOtherTazConnector = edge;296}297298const MSEdge* getOtherTazConnector() const {299return myOtherTazConnector;300}301302/** @brief Returns the numerical id of the edge303* @return This edge's numerical id304*/305inline int getNumericalID() const {306return myNumericalID;307}308309310/** @brief Returns the street name of the edge311*/312const std::string& getStreetName() const {313return myStreetName;314}315316/** @brief Returns the type of the edge317*/318const std::string& getEdgeType() const {319return myEdgeType;320}321322/** @brief Returns the type of the edge323*/324const std::string& getRoutingType() const {325return myRoutingType.empty() ? myEdgeType : myRoutingType;326}327328double getPreference(const SUMOVTypeParameter& pars) const;329330// @brief try to infer edge type for internal edges331void inferEdgeType();332333/** @brief Returns the priority of the edge334*/335int getPriority() const {336return myPriority;337}338339/** @brief Returns the kilometrage/mileage encoding at the start of the edge340* (negative values encode descending direction)341*/342double getDistance() const {343return myDistance;344}345346/** @brief Returns the kilometrage/mileage at the given offset along the edge347*/348double getDistanceAt(double pos) const;349350bool hasDistance() const {351return myDistance != 0;352}353/// @}354355/**@brief Sets the crossed edge ids for a crossing edge356*357*/358void setCrossingEdges(const std::vector<std::string>& crossingEdges) {359myCrossingEdges.clear();360myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());361}362363/**@brief Gets the crossed edge ids364*@return The list of crossed edge ids in a crossing edge or an empty vector365*/366const std::vector<std::string>& getCrossingEdges() const {367return myCrossingEdges;368}369370371/// @name Access to succeeding/predecessing edges372/// @{373374/** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge375*376* This is mainly used by the taz (district) parsing377* @param[in] edge The edge to add378*/379void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);380381void resetTAZ(MSJunction* junction);382383/** @brief Returns the number of edges that may be reached from this edge384* @return The number of following edges385*/386int getNumSuccessors() const {387return (int) mySuccessors.size();388}389390391/** @brief Returns the following edges, restricted by vClass392* @param[in] vClass The vClass for which to restrict the successors393* @return The eligible following edges394*/395const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;396397/** @brief Returns the following edges with internal vias, restricted by vClass398* @param[in] vClass The vClass for which to restrict the successors399* @return The eligible following edges400*/401const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;402403404/** @brief Returns the number of edges this edge is connected to405*406* @return The number of edges following this edge407*/408int getNumPredecessors() const {409return (int) myPredecessors.size();410}411412413/** @brief414* @return415*/416const MSEdgeVector& getPredecessors() const {417return myPredecessors;418}419420421const MSJunction* getFromJunction() const {422return myFromJunction;423}424425const MSJunction* getToJunction() const {426return myToJunction;427}428429430void setJunctions(MSJunction* from, MSJunction* to);431/// @}432433434435/// @name Access to vaporizing interface436/// @{437438/** @brief Returns whether vehicles on this edge shall be vaporized439* @return Whether no vehicle shall be on this edge440*/441bool isVaporizing() const {442return myVaporizationRequests > 0;443}444445446/** @brief Enables vaporization447*448* The internal vaporization counter is increased enabling the449* vaporization.450* Called from the event handler.451* @param[in] t The current time (unused)452* @return Time to next call (always 0)453* @exception ProcessError not thrown by this method, just derived454*/455SUMOTime incVaporization(SUMOTime t);456457458/** @brief Disables vaporization459*460* The internal vaporization counter is decreased what disables461* the vaporization if it was only once enabled.462* Called from the event handler.463* @param[in] t The current time (unused)464* @return Time to next call (always 0)465* @exception ProcessError not thrown by this method, just derived466*/467SUMOTime decVaporization(SUMOTime t);468/// @}469470471/** @brief Computes and returns the current travel time for this edge472*473* The mean speed of all lanes is used to compute the travel time.474* To avoid infinite travel times, the given minimum speed is used.475*476* @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped477* @return The current effort (travel time) to pass the edge478*/479double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;480481482/// @brief returns the minimum travel time for the given vehicle483inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {484if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {485return 0;486} else if (veh != 0) {487return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;488} else {489return myEmptyTraveltime;490}491}492493double getTimePenalty() const {494return myTimePenalty;495}496497/** @brief Returns the travel time for the given edge498*499* @param[in] edge The edge for which the travel time shall be retrieved500* @param[in] veh The vehicle for which the travel time on this edge shall be retrieved501* @param[in] time The time for which the travel time shall be returned [s]502* @return The traveltime needed by the given vehicle to pass the edge at the given time503*/504static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {505return MSNet::getInstance()->getTravelTime(edge, veh, time);506}507508static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);509510/** @brief Returns the averaged speed used by the routing device511*/512double getRoutingSpeed() const;513514515/// @name Methods releated to vehicle insertion516/// @{517518/** @brief Tries to insert the given vehicle into the network519*520* The procedure for choosing the proper lane is determined, first.521* In dependence to this, the proper lane is chosen.522*523* Insertion itself is done by calling the chose lane's "insertVehicle"524* method but only if the checkOnly argument is false. The check needs525* to be certain only in the negative case (if false is returned, there526* is no way this vehicle would be inserted).527*528* @param[in] v The vehicle to insert529* @param[in] time The current simulation time530* @param[in] checkOnly Whether we perform only the check without actually inserting531* @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle532* or whether insertion on lanes for which an insertion has already a failed should be ignored533* in the current time step.534* @return Whether the vehicle could be inserted535* @see MSLane::insertVehicle536*/537bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;538539/// @brief check whether the given departSpeed is valid for this edge540bool validateDepartSpeed(SUMOVehicle& v) const;541542/** @brief Finds the emptiest lane allowing the vehicle class543*544* The emptiest lane is the one which vehicle insertion is most likely to succeed.545*546* If there are no vehicles before departPos, then the lane with the largest547* gap between departPos and the last vehicle is548* Otheriwise the lane with lowes occupancy is selected549* If there is more than one, the first according to its550* index in the lane container is chosen.551*552* If allowed==0, the lanes allowed for the given vehicle class553* will be used.554*555* @param[in] allowed The lanes to choose from556* @param[in] vclass The vehicle class to look for557* @param[in] departPos An upper bound on vehicle depart position558* @return the least occupied lane559* @see allowedLanes560*/561MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;562563/** @brief Finds the most probable lane allowing the vehicle class564*565* The most probable lane is the one which best corresponds to the desired speed of the vehicle566* Vehicles with lower speeds will use lanes to the right while567* vehicles with higher speeds will use lanes to the left568*569* @param[in] allowed The lanes to choose from570* @param[in] vclass The vehicle class to look for571* @param[in] departPos An upper bound on vehicle depart position572* @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)573* @return the least occupied lane574* @see allowedLanes575*/576MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;577578579/** @brief Finds a depart lane for the given vehicle parameters580*581* Depending on the depart lane procedure a depart lane is chosen.582* Repeated calls with the same vehicle may return different results583* if the procedure is "random" or "free". In case no appropriate584* lane was found, 0 is returned.585*586* @param[in] veh The vehicle to get the depart lane for587* @return a possible/chosen depart lane, 0 if no lane can be used588*/589MSLane* getDepartLane(MSVehicle& veh) const;590591/* @brief get the rightmost lane that allows the given vClass or nullptr592* @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden593*/594MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;595596/// @brief consider given departLane parameter (only for validating speeds)597MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;598599/** @brief Returns the last time a vehicle could not be inserted600* @return The current value601*/602inline SUMOTime getLastFailedInsertionTime() const {603return myLastFailedInsertionTime;604}605606607/** @brief Sets the last time a vehicle could not be inserted608* @param[in] time the new value609*/610inline void setLastFailedInsertionTime(SUMOTime time) const {611myLastFailedInsertionTime = time;612}613/// @}614615616/** @brief Performs lane changing on this edge */617void changeLanes(SUMOTime t) const;618619620/// @todo extension: inner junctions are not filled621const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;622623624/// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.625double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;626627/// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself628const MSEdge* getNormalBefore() const;629630/// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself631const MSEdge* getNormalSuccessor() const;632633/// @brief Returns whether the vehicle (class) is not allowed on the edge634inline bool prohibits(const SUMOVehicle* const vehicle) const {635if (vehicle == nullptr) {636return false;637}638const SUMOVehicleClass svc = vehicle->getVClass();639return (vehicle->ignoreTransientPermissions()640? (myOriginalCombinedPermissions & svc) != svc641: (myCombinedPermissions & svc) != svc);642}643644bool hasTransientPermissions() const;645646/** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it647* The restriction mechanism is not implemented yet for the microsim, so it always returns false.648* @param[in] vehicle The vehicle for which the information has to be returned649* @return Whether the vehicle must not enter this edge650*/651inline bool restricts(const SUMOVehicle* const /* vehicle */) const {652return false;653}654655/// @brief Returns the combined permissions of all lanes of this edge656inline SVCPermissions getPermissions() const {657return myCombinedPermissions;658}659660/** @brief Returns the edges's width (sum over all lanes)661* @return This edges's width662*/663double getWidth() const {664return myWidth;665}666667/// @brief Returns the right side offsets of this edge's sublanes668const std::vector<double> getSubLaneSides() const {669return mySublaneSides;670}671672void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);673674void rebuildAllowedTargets(const bool updateVehicles = true);675676677/** @brief optimistic air distance heuristic for use in routing678* @param[in] other The edge to which the distance shall be returned679* @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes680* @return The distance to the other edge681*/682double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;683684685/// @brief return the coordinates of the center of the given stop686static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);687688689/** @brief return the length of the edge690* @return The edge's length691*/692inline double getLength() const {693return myLength;694}695696697/** @brief Returns the speed limit of the edge698* @caution The speed limit of the first lane is retured; should probably be the fastest edge699* @return The maximum speed allowed on this edge700*/701double getSpeedLimit() const;702703/// @brief return shape.length() / myLength704double getLengthGeometryFactor() const;705706/** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)707* @param[in] val the new speed in m/s708*/709void setMaxSpeed(double val, double jamThreshold = -1);710711/** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]712* @param[in] val the new coefficient in [0..1]713*/714void setFrictionCoefficient(double val) const;715716/** @brief Returns the maximum speed the vehicle may use on this edge717*718* @caution Only the first lane is considered719* @return The maximum velocity on this edge for the given vehicle720*/721double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;722723724virtual void addTransportable(MSTransportable* t) const;725726virtual void removeTransportable(MSTransportable* t) const;727728inline bool isRoundabout() const {729return myAmRoundabout;730}731732void markAsRoundabout() {733myAmRoundabout = true;734}735736void markDelayed() const {737myAmDelayed = true;738}739740// return whether there have been vehicles on this or the bidi edge (if there is any) at least once741inline bool isDelayed() const {742return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);743}744745bool hasLaneChanger() const {746return myLaneChanger != nullptr;747}748749/// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index750std::pair<double, SUMOTime> getLastBlocked(int index) const;751752/// @brief whether this edge allows changing to the opposite direction edge753bool canChangeToOpposite() const;754755/// @brief Returns the opposite direction edge if on exists else a nullptr756const MSEdge* getOppositeEdge() const;757758/// @brief get the mean speed759double getMeanSpeed() const;760761/// @brief get the mean friction over the lanes762double getMeanFriction() const;763764/// @brief get the mean speed of all bicycles on this edge765double getMeanSpeedBike() const;766767/// @brief whether any lane has a minor link768bool hasMinorLink() const;769770/// @brief return whether this edge is at the fringe of the network771bool isFringe() const {772return myAmFringe;773}774775/// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index776bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;777778/// @brief whether this lane is selected in the GUI779virtual bool isSelected() const {780return false;781}782783/// @brief grant exclusive access to the mesoscopic state784virtual void lock() const {}785786/// @brief release exclusive access to the mesoscopic state787virtual void unlock() const {};788789/// @brief Adds a vehicle to the list of waiting vehicles790void addWaiting(SUMOVehicle* vehicle) const;791792/// @brief Removes a vehicle from the list of waiting vehicles793void removeWaiting(const SUMOVehicle* vehicle) const;794795/* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position796* @param[in] transportable The person or container that wants to ride797* @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance798*/799SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;800801/** @brief Remove all transportables before quick-loading state */802void clearState();803804/// @brief update meso segment parameters805void updateMesoType();806807void postLoadInitLaneChanger();808809static DepartLaneDefinition& getDefaultDepartLaneDefinition() {810return myDefaultDepartLaneDefinition;811}812813static int& getDefaultDepartLane() {814return myDefaultDepartLane;815}816817/** @brief Inserts edge into the static dictionary818Returns true if the key id isn't already in the dictionary. Otherwise819returns false. */820static bool dictionary(const std::string& id, MSEdge* edge);821822/** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */823static MSEdge* dictionary(const std::string& id);824825/** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */826static MSEdge* dictionaryHint(const std::string& id, const int startIdx);827828/// @brief Returns all edges with a numerical id829static const MSEdgeVector& getAllEdges();830831/** @brief Clears the dictionary */832static void clear();833834/** @brief Inserts IDs of all known edges into the given vector */835static void insertIDs(std::vector<std::string>& into);836837static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);838839static void setMesoIgnoredVClasses(SVCPermissions ignored) {840myMesoIgnoredVClasses = ignored;841}842843public:844/// @name Static parser helper845/// @{846847/** @brief Parses the given string assuming it contains a list of edge ids divided by spaces848*849* Splits the string at spaces, uses polymorph method to generate edge vector.850* @param[in] desc The string containing space-separated edge ids851* @param[out] into The vector to fill852* @param[in] rid The id of the route these description belongs to; used for error message generation853* @exception ProcessError If one of the strings contained is not a known edge id854*/855static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,856const std::string& rid);857858859/** @brief Parses the given string vector assuming it edge ids860* @param[in] desc The string vector containing edge ids861* @param[out] into The vector to fill862* @param[in] rid The id of the route these description belongs to; used for error message generation863* @exception ProcessError If one of the strings contained is not a known edge id864*/865static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,866const std::string& rid);867/// @}868869870ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {871if (myReversedRoutingEdge == nullptr) {872myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);873}874return myReversedRoutingEdge;875}876877RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {878if (myRailwayRoutingEdge == nullptr) {879myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);880}881return myRailwayRoutingEdge;882}883884protected:885/** @class by_id_sorter886* @brief Sorts edges by their ids887*/888class by_id_sorter {889public:890/// @brief constructor891explicit by_id_sorter() { }892893/// @brief comparing operator894int operator()(const MSEdge* const e1, const MSEdge* const e2) const {895return e1->getNumericalID() < e2->getNumericalID();896}897898};899900/** @class transportable_by_position_sorter901* @brief Sorts transportables by their positions902*/903class transportable_by_position_sorter {904public:905/// @brief constructor906explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }907908/// @brief comparing operator909int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;910private:911SUMOTime myTime;912};913914915/// @brief return upper bound for the depart position on this edge916double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;917918protected:919/// @brief This edge's numerical id920const int myNumericalID;921922/// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index923std::shared_ptr<const std::vector<MSLane*> > myLanes;924925/// @brief This member will do the lane-change926MSLaneChanger* myLaneChanger;927928/// @brief the purpose of the edge929const SumoXMLEdgeFunc myFunction;930931/// @brief Vaporizer counter932int myVaporizationRequests;933934/// @brief The time of last insertion failure935mutable SUMOTime myLastFailedInsertionTime;936937/// @brief A cache for the rejected insertion attempts. Used to assure that no938/// further insertion attempts are made on a lane where an attempt has939/// already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.940mutable std::set<int> myFailedInsertionMemory;941942/// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty943std::vector<std::string> myCrossingEdges;944945/// @brief The succeeding edges946MSEdgeVector mySuccessors;947948MSConstEdgePairVector myViaSuccessors;949950/// @brief The preceeding edges951MSEdgeVector myPredecessors;952953/// @brief the junctions for this edge954MSJunction* myFromJunction;955MSJunction* myToJunction;956957/// @brief Persons on the edge for drawing and pushbutton958mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;959960/// @brief Containers on the edge961mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;962963/// @name Storages for allowed lanes (depending on vehicle classes)964/// @{965966/// @brief Associative container from vehicle class to allowed-lanes.967AllowedLanesCont myAllowed;968AllowedLanesCont myOrigAllowed;969970/// @brief From target edge to lanes allowed to be used to reach it971AllowedLanesByTarget myAllowedTargets;972AllowedLanesByTarget myOrigAllowedTargets;973974/// @brief The intersection of lane permissions for this edge975SVCPermissions myMinimumPermissions = SVCAll;976/// @brief The union of lane permissions for this edge977SVCPermissions myCombinedPermissions = 0;978979/// @brief The original intersection of lane permissions for this edge (before temporary modifications)980SVCPermissions myOriginalMinimumPermissions = SVCAll;981/// @brief The original union of lane permissions for this edge (before temporary modifications)982SVCPermissions myOriginalCombinedPermissions;983984/// @brief whether transient permission changes were applied to this edge or a predecessor985bool myHaveTransientPermissions;986/// @}987988/// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr989const MSEdge* myOtherTazConnector;990991/// @brief the real-world name of this edge (need not be unique)992std::string myStreetName;993994/// @brief the type of the edge (optionally used during network creation)995std::string myEdgeType;996997/// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)998std::string myRoutingType;9991000/// @brief the priority of the edge (used during network creation)1001const int myPriority;10021003/// @brief the kilometrage/mileage at the start of the edge1004const double myDistance;10051006/// Edge width [m]1007double myWidth;10081009/// @brief the length of the edge (cached value for speedup)1010double myLength;10111012/// @brief the traveltime on the empty edge (cached value for speedup)1013double myEmptyTraveltime;10141015/// @brief flat penalty when computing traveltime1016double myTimePenalty;10171018/// @brief whether this edge had a vehicle with less than max speed on it1019mutable bool myAmDelayed;10201021/// @brief whether this edge belongs to a roundabout1022bool myAmRoundabout;10231024/// @brief whether this edge is at the network fringe1025bool myAmFringe;10261027/// @brief the right side for each sublane on this edge1028std::vector<double> mySublaneSides;10291030/// @name Static edge container1031/// @{10321033/// @brief definition of the static dictionary type1034typedef std::map< std::string, MSEdge* > DictType;10351036/** @brief Static dictionary to associate string-ids with objects.1037* @deprecated Move to MSEdgeControl, make non-static1038*/1039static DictType myDict;10401041/** @brief Static list of edges1042* @deprecated Move to MSEdgeControl, make non-static1043*/1044static MSEdgeVector myEdges;10451046static SVCPermissions myMesoIgnoredVClasses;10471048static DepartLaneDefinition myDefaultDepartLaneDefinition;1049static int myDefaultDepartLane;1050/// @}105110521053/// @brief The successors available for a given vClass1054mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;10551056/// @brief The successors available for a given vClass1057mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;1058mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;10591060/// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges1061Boundary myBoundary;10621063/// @brief List of waiting vehicles1064mutable std::vector<SUMOVehicle*> myWaiting;10651066#ifdef HAVE_FOX1067/// @brief Mutex for accessing waiting vehicles1068mutable FXMutex myWaitingMutex;10691070/// @brief Mutex for accessing successor edges1071mutable FXMutex mySuccessorMutex;1072#endif10731074private:10751076/// @brief the oppositing superposable edge1077const MSEdge* myBidiEdge;10781079/// @brief a reversed version for backward routing1080mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;1081mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;10821083/// @brief Invalidated copy constructor.1084MSEdge(const MSEdge&);10851086/// @brief assignment operator.1087MSEdge& operator=(const MSEdge&) = delete;10881089void setBidiLanes();10901091bool isSuperposable(const MSEdge* other);10921093void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;1094};109510961097