/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2026 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;241const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass, bool ignoreTransientPermissions) const;242243inline bool isConnectedTo(const MSEdge& destination, SUMOVehicleClass vclass, bool ignoreTransientPermissions = false) const {244const std::vector<MSLane*>* const lanes = allowedLanes(destination, vclass, ignoreTransientPermissions);245return lanes != nullptr && !lanes->empty();246}247/// @}248249250251/// @name Access to other edge attributes252/// @{253254/** @brief Returns the edge type (SumoXMLEdgeFunc)255* @return This edge's SumoXMLEdgeFunc256* @see SumoXMLEdgeFunc257*/258inline SumoXMLEdgeFunc getFunction() const {259return myFunction;260}261262/// @brief return whether this edge is an internal edge263inline bool isNormal() const {264return myFunction == SumoXMLEdgeFunc::NORMAL;265}266267/// @brief return whether this edge is an internal edge268inline bool isInternal() const {269return myFunction == SumoXMLEdgeFunc::INTERNAL;270}271272/// @brief return whether this edge is a pedestrian crossing273inline bool isCrossing() const {274return myFunction == SumoXMLEdgeFunc::CROSSING;275}276277278/// @brief check and register the opposite superposable edge if any279void checkAndRegisterBiDirEdge(const std::string& bidiID = "");280281/// @brief return opposite superposable/congruent edge, if it exist and 0 else282inline const MSEdge* getBidiEdge() const {283return myBidiEdge;284}285286/// @brief return whether this edge is walking area287inline bool isWalkingArea() const {288return myFunction == SumoXMLEdgeFunc::WALKINGAREA;289}290291inline bool isTazConnector() const {292return myFunction == SumoXMLEdgeFunc::CONNECTOR;293}294295void setOtherTazConnector(const MSEdge* edge) {296myOtherTazConnector = edge;297}298299const MSEdge* getOtherTazConnector() const {300return myOtherTazConnector;301}302303/** @brief Returns the numerical id of the edge304* @return This edge's numerical id305*/306inline int getNumericalID() const {307return myNumericalID;308}309310311/** @brief Returns the street name of the edge312*/313const std::string& getStreetName() const {314return myStreetName;315}316317/** @brief Returns the type of the edge318*/319const std::string& getEdgeType() const {320return myEdgeType;321}322323/** @brief Returns the type of the edge324*/325const std::string& getRoutingType() const {326return myRoutingType.empty() ? myEdgeType : myRoutingType;327}328329double getPreference(const SUMOVTypeParameter& pars) const;330331// @brief try to infer edge type for internal edges332void inferEdgeType();333334/** @brief Returns the priority of the edge335*/336int getPriority() const {337return myPriority;338}339340/** @brief Returns the kilometrage/mileage encoding at the start of the edge341* (negative values encode descending direction)342*/343double getDistance() const {344return myDistance;345}346347/** @brief Returns the kilometrage/mileage at the given offset along the edge348*/349double getDistanceAt(double pos) const;350351bool hasDistance() const {352return myDistance != 0;353}354/// @}355356/**@brief Sets the crossed edge ids for a crossing edge357*358*/359void setCrossingEdges(const std::vector<std::string>& crossingEdges) {360myCrossingEdges.clear();361myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());362}363364/**@brief Gets the crossed edge ids365*@return The list of crossed edge ids in a crossing edge or an empty vector366*/367const std::vector<std::string>& getCrossingEdges() const {368return myCrossingEdges;369}370371372/// @name Access to succeeding/predecessing edges373/// @{374375/** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge376*377* This is mainly used by the taz (district) parsing378* @param[in] edge The edge to add379*/380void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);381382void resetTAZ(MSJunction* junction);383384/** @brief Returns the number of edges that may be reached from this edge385* @return The number of following edges386*/387int getNumSuccessors() const {388return (int) mySuccessors.size();389}390391392/** @brief Returns the following edges, restricted by vClass393* @param[in] vClass The vClass for which to restrict the successors394* @return The eligible following edges395*/396const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;397398/** @brief Returns the following edges with internal vias, restricted by vClass399* @param[in] vClass The vClass for which to restrict the successors400* @return The eligible following edges401*/402const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING, bool ignoreTransientPermissions = false) const;403404405/** @brief Returns the number of edges this edge is connected to406*407* @return The number of edges following this edge408*/409int getNumPredecessors() const {410return (int) myPredecessors.size();411}412413414/** @brief415* @return416*/417const MSEdgeVector& getPredecessors() const {418return myPredecessors;419}420421422const MSJunction* getFromJunction() const {423return myFromJunction;424}425426const MSJunction* getToJunction() const {427return myToJunction;428}429430431void setJunctions(MSJunction* from, MSJunction* to);432/// @}433434435436/// @name Access to vaporizing interface437/// @{438439/** @brief Returns whether vehicles on this edge shall be vaporized440* @return Whether no vehicle shall be on this edge441*/442bool isVaporizing() const {443return myVaporizationRequests > 0;444}445446447/** @brief Enables vaporization448*449* The internal vaporization counter is increased enabling the450* vaporization.451* Called from the event handler.452* @param[in] t The current time (unused)453* @return Time to next call (always 0)454* @exception ProcessError not thrown by this method, just derived455*/456SUMOTime incVaporization(SUMOTime t);457458459/** @brief Disables vaporization460*461* The internal vaporization counter is decreased what disables462* the vaporization if it was only once enabled.463* Called from the event handler.464* @param[in] t The current time (unused)465* @return Time to next call (always 0)466* @exception ProcessError not thrown by this method, just derived467*/468SUMOTime decVaporization(SUMOTime t);469/// @}470471472/** @brief Computes and returns the current travel time for this edge473*474* The mean speed of all lanes is used to compute the travel time.475* To avoid infinite travel times, the given minimum speed is used.476*477* @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped478* @return The current effort (travel time) to pass the edge479*/480double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;481482483/// @brief returns the minimum travel time for the given vehicle484inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {485if (myFunction == SumoXMLEdgeFunc::CONNECTOR) {486return 0;487} else if (veh != 0) {488return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;489} else {490return myEmptyTraveltime;491}492}493494double getTimePenalty() const {495return myTimePenalty;496}497498/** @brief Returns the travel time for the given edge499*500* @param[in] edge The edge for which the travel time shall be retrieved501* @param[in] veh The vehicle for which the travel time on this edge shall be retrieved502* @param[in] time The time for which the travel time shall be returned [s]503* @return The traveltime needed by the given vehicle to pass the edge at the given time504*/505static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {506return MSNet::getInstance()->getTravelTime(edge, veh, time);507}508509static double getTravelTimeAggregated(const MSEdge* const edge, const SUMOVehicle* const veh, double time);510511/** @brief Returns the averaged speed used by the routing device512*/513double getRoutingSpeed() const;514515516/// @name Methods releated to vehicle insertion517/// @{518519/** @brief Tries to insert the given vehicle into the network520*521* The procedure for choosing the proper lane is determined, first.522* In dependence to this, the proper lane is chosen.523*524* Insertion itself is done by calling the chose lane's "insertVehicle"525* method but only if the checkOnly argument is false. The check needs526* to be certain only in the negative case (if false is returned, there527* is no way this vehicle would be inserted).528*529* @param[in] v The vehicle to insert530* @param[in] time The current simulation time531* @param[in] checkOnly Whether we perform only the check without actually inserting532* @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle533* or whether insertion on lanes for which an insertion has already a failed should be ignored534* in the current time step.535* @return Whether the vehicle could be inserted536* @see MSLane::insertVehicle537*/538bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;539540/// @brief check whether the given departSpeed is valid for this edge541bool validateDepartSpeed(SUMOVehicle& v) const;542543/** @brief Finds the emptiest lane allowing the vehicle class544*545* The emptiest lane is the one which vehicle insertion is most likely to succeed.546*547* If there are no vehicles before departPos, then the lane with the largest548* gap between departPos and the last vehicle is549* Otheriwise the lane with lowes occupancy is selected550* If there is more than one, the first according to its551* index in the lane container is chosen.552*553* If allowed==0, the lanes allowed for the given vehicle class554* will be used.555*556* @param[in] allowed The lanes to choose from557* @param[in] vclass The vehicle class to look for558* @param[in] departPos An upper bound on vehicle depart position559* @return the least occupied lane560* @see allowedLanes561*/562MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;563564/** @brief Finds the most probable lane allowing the vehicle class565*566* The most probable lane is the one which best corresponds to the desired speed of the vehicle567* Vehicles with lower speeds will use lanes to the right while568* vehicles with higher speeds will use lanes to the left569*570* @param[in] allowed The lanes to choose from571* @param[in] vclass The vehicle class to look for572* @param[in] departPos An upper bound on vehicle depart position573* @param[in] maxSpeed The vehicles maxSpeed (including speedFactor)574* @return the least occupied lane575* @see allowedLanes576*/577MSLane* getProbableLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos, double maxSpeed) const;578579580/** @brief Finds a depart lane for the given vehicle parameters581*582* Depending on the depart lane procedure a depart lane is chosen.583* Repeated calls with the same vehicle may return different results584* if the procedure is "random" or "free". In case no appropriate585* lane was found, 0 is returned.586*587* @param[in] veh The vehicle to get the depart lane for588* @return a possible/chosen depart lane, 0 if no lane can be used589*/590MSLane* getDepartLane(MSVehicle& veh) const;591592/* @brief get the rightmost lane that allows the given vClass or nullptr593* @param[in] defaultFirst Whether the first lane should be returned if all lanes are forbidden594*/595MSLane* getFirstAllowed(SUMOVehicleClass vClass, bool defaultFirst = false, int routingMode = 0) const;596597/// @brief consider given departLane parameter (only for validating speeds)598MSLane* getDepartLaneMeso(SUMOVehicle& veh) const;599600/** @brief Returns the last time a vehicle could not be inserted601* @return The current value602*/603inline SUMOTime getLastFailedInsertionTime() const {604return myLastFailedInsertionTime;605}606607608/** @brief Sets the last time a vehicle could not be inserted609* @param[in] time the new value610*/611inline void setLastFailedInsertionTime(SUMOTime time) const {612myLastFailedInsertionTime = time;613}614/// @}615616617/** @brief Performs lane changing on this edge */618void changeLanes(SUMOTime t) const;619620621/// @todo extension: inner junctions are not filled622const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;623624625/// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.626double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal, SUMOVehicleClass vClass) const;627628/// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself629const MSEdge* getNormalBefore() const;630631/// @brief if this edge is an internal edge, return its first normal successor, otherwise the edge itself632const MSEdge* getNormalSuccessor() const;633634/// @brief Returns whether the vehicle (class) is not allowed on the edge635inline bool prohibits(const SUMOVehicle* const vehicle) const {636if (vehicle == nullptr) {637return false;638}639const SUMOVehicleClass svc = vehicle->getVClass();640return (vehicle->ignoreTransientPermissions()641? (myOriginalCombinedPermissions & svc) != svc642: (myCombinedPermissions & svc) != svc);643}644645bool hasTransientPermissions() const;646647/** @brief Returns whether this edge has restriction parameters forbidding the given vehicle to pass it648* The restriction mechanism is not implemented yet for the microsim, so it always returns false.649* @param[in] vehicle The vehicle for which the information has to be returned650* @return Whether the vehicle must not enter this edge651*/652inline bool restricts(const SUMOVehicle* const /* vehicle */) const {653return false;654}655656/// @brief Returns the combined permissions of all lanes of this edge657inline SVCPermissions getPermissions() const {658return myCombinedPermissions;659}660661/** @brief Returns the edges's width (sum over all lanes)662* @return This edges's width663*/664double getWidth() const {665return myWidth;666}667668/// @brief Returns the right side offsets of this edge's sublanes669const std::vector<double> getSubLaneSides() const {670return mySublaneSides;671}672673void rebuildAllowedLanes(const bool onInit = false, bool updateVehicles = false);674675void rebuildAllowedTargets(const bool updateVehicles = true);676677678/** @brief optimistic air distance heuristic for use in routing679* @param[in] other The edge to which the distance shall be returned680* @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes681* @return The distance to the other edge682*/683double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;684685686/// @brief return the coordinates of the center of the given stop687static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);688689690/** @brief return the length of the edge691* @return The edge's length692*/693inline double getLength() const {694return myLength;695}696697698/** @brief Returns the speed limit of the edge699* @caution The speed limit of the first lane is retured; should probably be the fastest edge700* @return The maximum speed allowed on this edge701*/702double getSpeedLimit() const;703704/// @brief return shape.length() / myLength705double getLengthGeometryFactor() const;706707/** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)708* @param[in] val the new speed in m/s709*/710void setMaxSpeed(double val, double jamThreshold = -1);711712/** @brief Sets a new friction coefficient COF for all lanes [*later to be (used by TraCI and MSCalibrator)*]713* @param[in] val the new coefficient in [0..1]714*/715void setFrictionCoefficient(double val) const;716717/** @brief Returns the maximum speed the vehicle may use on this edge718*719* @caution Only the first lane is considered720* @return The maximum velocity on this edge for the given vehicle721*/722double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;723724725virtual void addTransportable(MSTransportable* t) const;726727virtual void removeTransportable(MSTransportable* t) const;728729inline bool isRoundabout() const {730return myAmRoundabout;731}732733void markAsRoundabout() {734myAmRoundabout = true;735}736737void markDelayed() const {738myAmDelayed = true;739}740741// return whether there have been vehicles on this or the bidi edge (if there is any) at least once742inline bool isDelayed() const {743return myAmDelayed || (myBidiEdge != nullptr && myBidiEdge->myAmDelayed);744}745746bool hasLaneChanger() const {747return myLaneChanger != nullptr;748}749750/// @brief retrieve properties of a blocked vehicle that wants to chane to the lane with the given index751std::pair<double, SUMOTime> getLastBlocked(int index) const;752753/// @brief whether this edge allows changing to the opposite direction edge754bool canChangeToOpposite() const;755756/// @brief Returns the opposite direction edge if on exists else a nullptr757const MSEdge* getOppositeEdge() const;758759/// @brief get the mean speed760double getMeanSpeed() const;761762/// @brief get the mean friction over the lanes763double getMeanFriction() const;764765/// @brief get the mean speed of all bicycles on this edge766double getMeanSpeedBike() const;767768/// @brief whether any lane has a minor link769bool hasMinorLink() const;770771/// @brief return whether this edge is at the fringe of the network772bool isFringe() const {773return myAmFringe;774}775776/// @brief return whether this edge prohibits changing for the given vClass when starting on the given lane index777bool hasChangeProhibitions(SUMOVehicleClass svc, int index) const;778779/// @brief whether this lane is selected in the GUI780virtual bool isSelected() const {781return false;782}783784/// @brief grant exclusive access to the mesoscopic state785virtual void lock() const {}786787/// @brief release exclusive access to the mesoscopic state788virtual void unlock() const {};789790/// @brief Adds a vehicle to the list of waiting vehicles791void addWaiting(SUMOVehicle* vehicle) const;792793/// @brief Removes a vehicle from the list of waiting vehicles794void removeWaiting(const SUMOVehicle* vehicle) const;795796/* @brief returns a vehicle that is waiting for a for a person or a container at this edge at the given position797* @param[in] transportable The person or container that wants to ride798* @param[in] position The vehicle shall be positioned in the interval [position - t, position + t], where t is some tolerance799*/800SUMOVehicle* getWaitingVehicle(MSTransportable* transportable, const double position) const;801802/** @brief Remove all transportables before quick-loading state */803void clearState();804805void postLoadInitLaneChanger();806807static DepartLaneDefinition& getDefaultDepartLaneDefinition() {808return myDefaultDepartLaneDefinition;809}810811static int& getDefaultDepartLane() {812return myDefaultDepartLane;813}814815/** @brief Inserts edge into the static dictionary816Returns true if the key id isn't already in the dictionary. Otherwise817returns false. */818static bool dictionary(const std::string& id, MSEdge* edge);819820/** @brief Returns the MSEdge associated to the key id if it exists, otherwise returns nullptr. */821static MSEdge* dictionary(const std::string& id);822823/** @brief Returns the MSEdge associated to the key id giving a hint with a numerical id. */824static MSEdge* dictionaryHint(const std::string& id, const int startIdx);825826/// @brief Returns all edges with a numerical id827static const MSEdgeVector& getAllEdges();828829/** @brief Clears the dictionary */830static void clear();831832/** @brief Inserts IDs of all known edges into the given vector */833static void insertIDs(std::vector<std::string>& into);834835static SVCPermissions getMesoPermissions(SVCPermissions p, SVCPermissions ignoreIgnored = 0);836837static void setMesoIgnoredVClasses(SVCPermissions ignored) {838myMesoIgnoredVClasses = ignored;839}840841public:842/// @name Static parser helper843/// @{844845/** @brief Parses the given string assuming it contains a list of edge ids divided by spaces846*847* Splits the string at spaces, uses polymorph method to generate edge vector.848* @param[in] desc The string containing space-separated edge ids849* @param[out] into The vector to fill850* @param[in] rid The id of the route these description belongs to; used for error message generation851* @exception ProcessError If one of the strings contained is not a known edge id852*/853static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,854const std::string& rid);855856857/** @brief Parses the given string vector assuming it edge ids858* @param[in] desc The string vector containing edge ids859* @param[out] into The vector to fill860* @param[in] rid The id of the route these description belongs to; used for error message generation861* @exception ProcessError If one of the strings contained is not a known edge id862*/863static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,864const std::string& rid);865/// @}866867868ReversedEdge<MSEdge, SUMOVehicle>* getReversedRoutingEdge() const {869if (myReversedRoutingEdge == nullptr) {870myReversedRoutingEdge = new ReversedEdge<MSEdge, SUMOVehicle>(this);871}872return myReversedRoutingEdge;873}874875RailEdge<MSEdge, SUMOVehicle>* getRailwayRoutingEdge() const {876if (myRailwayRoutingEdge == nullptr) {877myRailwayRoutingEdge = new RailEdge<MSEdge, SUMOVehicle>(this);878}879return myRailwayRoutingEdge;880}881882protected:883/** @class by_id_sorter884* @brief Sorts edges by their ids885*/886class by_id_sorter {887public:888/// @brief constructor889explicit by_id_sorter() { }890891/// @brief comparing operator892int operator()(const MSEdge* const e1, const MSEdge* const e2) const {893return e1->getNumericalID() < e2->getNumericalID();894}895896};897898/** @class transportable_by_position_sorter899* @brief Sorts transportables by their positions900*/901class transportable_by_position_sorter {902public:903/// @brief constructor904explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }905906/// @brief comparing operator907int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;908private:909SUMOTime myTime;910};911912913/// @brief return upper bound for the depart position on this edge914double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;915916protected:917/// @brief This edge's numerical id918const int myNumericalID;919920/// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index921std::shared_ptr<const std::vector<MSLane*> > myLanes;922923/// @brief This member will do the lane-change924MSLaneChanger* myLaneChanger;925926/// @brief the purpose of the edge927const SumoXMLEdgeFunc myFunction;928929/// @brief Vaporizer counter930int myVaporizationRequests;931932/// @brief The time of last insertion failure933mutable SUMOTime myLastFailedInsertionTime;934935/// @brief A cache for the rejected insertion attempts. Used to assure that no936/// further insertion attempts are made on a lane where an attempt has937/// already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.938mutable std::set<int> myFailedInsertionMemory;939940/// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty941std::vector<std::string> myCrossingEdges;942943/// @brief The succeeding edges944MSEdgeVector mySuccessors;945946MSConstEdgePairVector myViaSuccessors;947948/// @brief The preceeding edges949MSEdgeVector myPredecessors;950951/// @brief the junctions for this edge952MSJunction* myFromJunction;953MSJunction* myToJunction;954955/// @brief Persons on the edge for drawing and pushbutton956mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myPersons;957958/// @brief Containers on the edge959mutable std::set<MSTransportable*, ComparatorNumericalIdLess> myContainers;960961/// @name Storages for allowed lanes (depending on vehicle classes)962/// @{963964/// @brief Associative container from vehicle class to allowed-lanes.965AllowedLanesCont myAllowed;966AllowedLanesCont myOrigAllowed;967968/// @brief From target edge to lanes allowed to be used to reach it969AllowedLanesByTarget myAllowedTargets;970AllowedLanesByTarget myOrigAllowedTargets;971972/// @brief The intersection of lane permissions for this edge973SVCPermissions myMinimumPermissions = SVCAll;974/// @brief The union of lane permissions for this edge975SVCPermissions myCombinedPermissions = 0;976977/// @brief The original intersection of lane permissions for this edge (before temporary modifications)978SVCPermissions myOriginalMinimumPermissions = SVCAll;979/// @brief The original union of lane permissions for this edge (before temporary modifications)980SVCPermissions myOriginalCombinedPermissions = SVCAll;981982/// @brief whether transient permission changes were applied to this edge or a predecessor983bool myHaveTransientPermissions;984/// @}985986/// @brief the other taz-connector if this edge isTazConnector, otherwise nullptr987const MSEdge* myOtherTazConnector;988989/// @brief the real-world name of this edge (need not be unique)990std::string myStreetName;991992/// @brief the type of the edge (optionally used during network creation)993std::string myEdgeType;994995/// @brief the routing type of the edge (used to look up vType and vClass specific routing preferences)996std::string myRoutingType;997998/// @brief the priority of the edge (used during network creation)999const int myPriority;10001001/// @brief the kilometrage/mileage at the start of the edge1002const double myDistance;10031004/// Edge width [m]1005double myWidth;10061007/// @brief the length of the edge (cached value for speedup)1008double myLength;10091010/// @brief the traveltime on the empty edge (cached value for speedup)1011double myEmptyTraveltime;10121013/// @brief flat penalty when computing traveltime1014double myTimePenalty;10151016/// @brief whether this edge had a vehicle with less than max speed on it1017mutable bool myAmDelayed;10181019/// @brief whether this edge belongs to a roundabout1020bool myAmRoundabout;10211022/// @brief whether this edge is at the network fringe1023bool myAmFringe;10241025/// @brief the right side for each sublane on this edge1026std::vector<double> mySublaneSides;10271028/// @name Static edge container1029/// @{10301031/// @brief definition of the static dictionary type1032typedef std::map< std::string, MSEdge* > DictType;10331034/** @brief Static dictionary to associate string-ids with objects.1035* @deprecated Move to MSEdgeControl, make non-static1036*/1037static DictType myDict;10381039/** @brief Static list of edges1040* @deprecated Move to MSEdgeControl, make non-static1041*/1042static MSEdgeVector myEdges;10431044static SVCPermissions myMesoIgnoredVClasses;10451046static DepartLaneDefinition myDefaultDepartLaneDefinition;1047static int myDefaultDepartLane;1048/// @}104910501051/// @brief The successors available for a given vClass1052mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;10531054/// @brief The successors available for a given vClass1055mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;1056mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myOrigClassesViaSuccessorMap;10571058/// @brief The bounding rectangle of end nodes incoming or outgoing edges for taz connectors or of my own start and end node for normal edges1059Boundary myBoundary;10601061/// @brief List of waiting vehicles1062mutable std::vector<SUMOVehicle*> myWaiting;10631064#ifdef HAVE_FOX1065/// @brief Mutex for accessing waiting vehicles1066mutable FXMutex myWaitingMutex;10671068/// @brief Mutex for accessing successor edges1069mutable FXMutex mySuccessorMutex;1070#endif10711072private:10731074/// @brief the oppositing superposable edge1075const MSEdge* myBidiEdge;10761077/// @brief a reversed version for backward routing1078mutable ReversedEdge<MSEdge, SUMOVehicle>* myReversedRoutingEdge = nullptr;1079mutable RailEdge<MSEdge, SUMOVehicle>* myRailwayRoutingEdge = nullptr;10801081/// @brief Invalidated copy constructor.1082MSEdge(const MSEdge&);10831084/// @brief assignment operator.1085MSEdge& operator=(const MSEdge&) = delete;10861087void setBidiLanes();10881089bool isSuperposable(const MSEdge* other);10901091void addToAllowed(const SVCPermissions permissions, std::shared_ptr<const std::vector<MSLane*> > allowedLanes, AllowedLanesCont& laneCont) const;1092};109310941095