1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
10 /// @file    MSEdge.h
11 /// @author  Christian Roessel
12 /// @author  Daniel Krajzewicz
13 /// @author  Jakob Erdmann
14 /// @author  Sascha Krieg
15 /// @author  Michael Behrisch
16 /// @date    Mon, 12 Mar 2001
17 /// @version $Id$
18 ///
19 // A road/street connecting two junctions
20 /****************************************************************************/
21 #ifndef MSEdge_h
22 #define MSEdge_h
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #include <config.h>
29 
30 #include <vector>
31 #include <map>
32 #include <string>
33 #include <iostream>
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/vehicle/SUMOVehicle.h>
40 #include <utils/vehicle/SUMOTrafficObject.h>
41 #include "MSNet.h"
42 
43 
44 // ===========================================================================
45 // class declarations
46 // ===========================================================================
47 class Boundary;
48 class OutputDevice;
49 class SUMOVehicle;
50 class SUMOVehicleParameter;
51 class MSVehicle;
52 class MSLane;
53 class MSLaneChanger;
54 class MSPerson;
55 class MSJunction;
56 class MSEdge;
57 class MSContainer;
58 class MSTransportable;
59 
60 
61 // ===========================================================================
62 // class definitions
63 // ===========================================================================
64 /**
65  * @class MSEdge
66  * @brief A road/street connecting two junctions
67  *
68  * A single connection between two junctions.
69  * Holds lanes which are reponsible for vehicle movements.
70  */
71 
72 typedef std::vector<MSEdge*> MSEdgeVector;
73 typedef std::vector<const MSEdge*> ConstMSEdgeVector;
74 typedef std::vector<std::pair<const MSEdge*, const MSEdge*> > MSConstEdgePairVector;
75 
76 class MSEdge : public Named, public Parameterised {
77 private:
78     /** @brief "Map" from vehicle class to allowed lanes */
79     typedef std::vector<std::pair<SVCPermissions, const std::vector<MSLane*>* > > AllowedLanesCont;
80 
81     /** @brief Succeeding edges (keys) and allowed lanes to reach these edges (values). */
82     typedef std::map<const MSEdge*, AllowedLanesCont> AllowedLanesByTarget;
83 
84 
85 public:
86     /** @brief Constructor.
87      *
88      * After calling this constructor, the edge is not yet initialised
89      *  completely. A call to "initialize" with proper values is needed
90      *  for this.
91      *
92      * @param[in] id The id of the edge
93      * @param[in] numericalID The numerical id (index) of the edge
94      * @param[in] function A basic type of the edge
95      * @param[in] streetName The street name for that edge
96      */
97     MSEdge(const std::string& id, int numericalID, const SumoXMLEdgeFunc function,
98            const std::string& streetName, const std::string& edgeType, int priority);
99 
100 
101     /// @brief Destructor.
102     virtual ~MSEdge();
103 
104 
105     /** @brief Initialize the edge.
106      *
107      * @param[in] allowed Information which edges may be reached from which lanes
108      * @param[in] lanes List of this edge's lanes
109      */
110     void initialize(const std::vector<MSLane*>* lanes);
111 
112 
113     /** @brief Recalculates the cached values
114      */
115     void recalcCache();
116 
117 
118     /// @todo Has to be called after all edges were built and all connections were set...; Still, is not very nice
119     void closeBuilding();
120 
121     /// Has to be called after all sucessors and predecessors have been set (after closeBuilding())
122     void buildLaneChanger();
123 
124     /* @brief returns whether initizliaing a lane change is permitted on this edge
125      * @note Has to be called after all sucessors and predecessors have been set (after closeBuilding())
126      */
127     bool allowsLaneChanging() const;
128 
129     /// @name Access to the edge's lanes
130     /// @{
131 
132     /** @brief Returns the lane left to the one given, 0 if the given lane is leftmost
133      *
134      * @param[in] lane The lane right to the one to be returned
135      * @return The lane left to the given, 0 if no such lane exists
136      * @todo This method searches for the given in the container; probably, this could be done faster
137      */
138     MSLane* leftLane(const MSLane* const lane) const;
139 
140 
141     /** @brief Returns the lane right to the one given, 0 if the given lane is rightmost
142      *
143      * @param[in] lane The lane left to the one to be returned
144      * @return The lane right to the given, 0 if no such lane exists
145      * @todo This method searches for the given in the container; probably, this could be done faster
146      */
147     MSLane* rightLane(const MSLane* const lane) const;
148 
149 
150     /** @brief Returns the lane with the given offset parallel to the given lane one or 0 if it does not exist
151      *
152      * @param[in] lane The base lane
153      * @param[in] offset The offset of the result lane
154      * @todo This method searches for the given in the container; probably, this could be done faster
155      */
156     MSLane* parallelLane(const MSLane* const lane, int offset) const;
157 
158 
159     /** @brief Returns this edge's lanes
160      *
161      * @return This edge's lanes
162      */
getLanes()163     inline const std::vector<MSLane*>& getLanes() const {
164         return *myLanes;
165     }
166 
167     /** @brief Returns this edge's persons set.
168      *  @brief Avoids the creation of new vector as in getSortedPersons
169      *
170      * @return This edge's persons.
171      */
getPersons()172     inline const std::set<MSTransportable*>& getPersons() const {
173         return myPersons;
174     }
175 
176     /** @brief Returns this edge's persons sorted by pos
177      *
178      * @return This edge's persons sorted by pos
179      */
180     std::vector<MSTransportable*> getSortedPersons(SUMOTime timestep, bool includeRiding = false) const;
181 
182 
183     /** @brief Returns this edge's containers sorted by pos
184      *
185      * @return This edge's containers sorted by pos
186      */
187     std::vector<MSTransportable*> getSortedContainers(SUMOTime timestep, bool includeRiding = false) const;
188 
189     /** @brief Get the allowed lanes to reach the destination-edge.
190      *
191      * If there is no such edge, get 0. Then you are on the wrong edge.
192      *
193      * @param[in] destination The edge to reach
194      * @param[in] vclass The vehicle class for which this information shall be returned
195      * @return The lanes that may be used to reach the given edge, nullptr if no such lanes exist
196      */
197     const std::vector<MSLane*>* allowedLanes(const MSEdge& destination,
198             SUMOVehicleClass vclass = SVC_IGNORING) const;
199 
200 
201 
202     /** @brief Get the allowed lanes for the given vehicle class.
203      *
204      * If there is no such edge, get 0. Then you are on the wrong edge.
205      *
206      * @param[in] vclass The vehicle class for which this information shall be returned
207      * @return The lanes that may be used by the given vclass
208      */
209     const std::vector<MSLane*>* allowedLanes(SUMOVehicleClass vclass = SVC_IGNORING) const;
210     /// @}
211 
212 
213 
214     /// @name Access to other edge attributes
215     /// @{
216 
217     /** @brief Returns the edge type (SumoXMLEdgeFunc)
218      * @return This edge's SumoXMLEdgeFunc
219      * @see SumoXMLEdgeFunc
220      */
getFunction()221     inline SumoXMLEdgeFunc getFunction() const {
222         return myFunction;
223     }
224 
225     /// @brief return whether this edge is an internal edge
isInternal()226     inline bool isInternal() const {
227         return myFunction == EDGEFUNC_INTERNAL;
228     }
229 
230     /// @brief return whether this edge is a pedestrian crossing
isCrossing()231     inline bool isCrossing() const {
232         return myFunction == EDGEFUNC_CROSSING;
233     }
234 
235 
236     /// @brief check and register the opposite superposable edge if any
237     void checkAndRegisterBiDirEdge(const std::string& bidiID = "");
238 
239     /// @brief return opposite superposable/congruent edge, if it exist and 0 else
getBidiEdge()240     inline const MSEdge* getBidiEdge() const {
241         return myBidiEdge;
242     }
243 
244     /// @brief return whether this edge is walking area
isWalkingArea()245     inline bool isWalkingArea() const {
246         return myFunction == EDGEFUNC_WALKINGAREA;
247     }
248 
isTazConnector()249     inline bool isTazConnector() const {
250         return myFunction == EDGEFUNC_CONNECTOR;
251     }
252 
253     /** @brief Returns the numerical id of the edge
254      * @return This edge's numerical id
255      */
getNumericalID()256     inline int getNumericalID() const {
257         return myNumericalID;
258     }
259 
260 
261     /** @brief Returns the street name of the edge
262      */
getStreetName()263     const std::string& getStreetName() const {
264         return myStreetName;
265     }
266 
267     /** @brief Returns the type of the edge
268      */
getEdgeType()269     const std::string& getEdgeType() const {
270         return myEdgeType;
271     }
272 
273     /** @brief Returns the priority of the edge
274      */
getPriority()275     int getPriority() const {
276         return myPriority;
277     }
278     /// @}
279 
280     /**@brief Sets the crossed edge ids for a crossing edge
281      *
282      */
setCrossingEdges(const std::vector<std::string> & crossingEdges)283     void setCrossingEdges(const std::vector<std::string>& crossingEdges)		{
284         myCrossingEdges.clear();
285         myCrossingEdges.insert(myCrossingEdges.begin(), crossingEdges.begin(), crossingEdges.end());
286     }
287 
288     /**@brief Gets the crossed edge ids
289      *@return The list of crossed edge ids in a crossing edge or an empty vector
290      */
getCrossingEdges()291     const std::vector<std::string>& getCrossingEdges() const {
292         return myCrossingEdges;
293     }
294 
295 
296     /// @name Access to succeeding/predecessing edges
297     /// @{
298 
299     /** @brief Adds an edge to the list of edges which may be reached from this edge and to the incoming of the other edge
300      *
301      * This is mainly used by the taz (district) parsing
302      * @param[in] edge The edge to add
303      */
304     void addSuccessor(MSEdge* edge, const MSEdge* via = nullptr);
305 
306     /** @brief Returns the number of edges that may be reached from this edge
307      * @return The number of following edges
308      */
getNumSuccessors()309     int getNumSuccessors() const {
310         return (int) mySuccessors.size();
311     }
312 
313 
314     /** @brief Returns the following edges, restricted by vClass
315      * @param[in] vClass The vClass for which to restrict the successors
316      * @return The eligible following edges
317      */
318     const MSEdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
319 
320     /** @brief Returns the following edges with internal vias, restricted by vClass
321      * @param[in] vClass The vClass for which to restrict the successors
322      * @return The eligible following edges
323      */
324     const MSConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const;
325 
326 
327     /** @brief Returns the number of edges this edge is connected to
328      *
329      * @return The number of edges following this edge
330      */
getNumPredecessors()331     int getNumPredecessors() const {
332         return (int) myPredecessors.size();
333     }
334 
335 
336     /** @brief
337      * @return
338      */
getPredecessors()339     const MSEdgeVector& getPredecessors() const {
340         return myPredecessors;
341     }
342 
343 
getFromJunction()344     const MSJunction* getFromJunction() const {
345         return myFromJunction;
346     }
347 
getToJunction()348     const MSJunction* getToJunction() const {
349         return myToJunction;
350     }
351 
352 
353     void setJunctions(MSJunction* from, MSJunction* to);
354     /// @}
355 
356 
357 
358     /// @name Access to vaporizing interface
359     /// @{
360 
361     /** @brief Returns whether vehicles on this edge shall be vaporized
362      * @return Whether no vehicle shall be on this edge
363      */
isVaporizing()364     bool isVaporizing() const {
365         return myVaporizationRequests > 0;
366     }
367 
368 
369     /** @brief Enables vaporization
370      *
371      * The internal vaporization counter is increased enabling the
372      *  vaporization.
373      * Called from the event handler.
374      * @param[in] t The current time (unused)
375      * @return Time to next call (always 0)
376      * @exception ProcessError not thrown by this method, just derived
377      */
378     SUMOTime incVaporization(SUMOTime t);
379 
380 
381     /** @brief Disables vaporization
382      *
383      * The internal vaporization counter is decreased what disables
384      *  the vaporization if it was only once enabled.
385      * Called from the event handler.
386      * @param[in] t The current time (unused)
387      * @return Time to next call (always 0)
388      * @exception ProcessError not thrown by this method, just derived
389      */
390     SUMOTime decVaporization(SUMOTime t);
391     /// @}
392 
393 
394     /** @brief Computes and returns the current travel time for this edge
395      *
396      * The mean speed of all lanes is used to compute the travel time.
397      * To avoid infinite travel times, the given minimum speed is used.
398      *
399      * @param[in] minSpeed The minimumSpeed to assume if traffic on this edge is stopped
400      * @return The current effort (travel time) to pass the edge
401      */
402     double getCurrentTravelTime(const double minSpeed = NUMERICAL_EPS) const;
403 
404 
405     /// @brief returns the minimum travel time for the given vehicle
getMinimumTravelTime(const SUMOVehicle * const veh)406     inline double getMinimumTravelTime(const SUMOVehicle* const veh) const {
407         if (myFunction == EDGEFUNC_CONNECTOR) {
408             return 0;
409         } else if (veh != 0) {
410             return getLength() / getVehicleMaxSpeed(veh) + myTimePenalty;
411         } else {
412             return myEmptyTraveltime;
413         }
414     }
415 
416 
417     /** @brief Returns the travel time for the given edge
418      *
419      * @param[in] edge The edge for which the travel time shall be retrieved
420      * @param[in] veh The vehicle for which the travel time on this edge shall be retrieved
421      * @param[in] time The time for which the travel time shall be returned [s]
422      * @return The traveltime needed by the given vehicle to pass the edge at the given time
423      */
getTravelTimeStatic(const MSEdge * const edge,const SUMOVehicle * const veh,double time)424     static inline double getTravelTimeStatic(const MSEdge* const edge, const SUMOVehicle* const veh, double time) {
425         return MSNet::getInstance()->getTravelTime(edge, veh, time);
426     }
427 
428     /** @brief Returns the averaged speed used by the routing device
429      */
430     double getRoutingSpeed() const;
431 
432 
433     /// @name Methods releated to vehicle insertion
434     /// @{
435 
436     /** @brief Tries to insert the given vehicle into the network
437      *
438      * The procedure for choosing the proper lane is determined, first.
439      *  In dependance to this, the proper lane is chosen.
440      *
441      * Insertion itself is done by calling the chose lane's "insertVehicle"
442      *  method but only if the checkOnly argument is false. The check needs
443      *  to be certain only in the negative case (if false is returned, there
444      *  is no way this vehicle would be inserted).
445      *
446      * @param[in] v The vehicle to insert
447      * @param[in] time The current simulation time
448      * @param[in] checkOnly Whether we perform only the check without actually inserting
449      * @param[in] forceCheck Whether the full insertion check should be run for each pending vehicle
450      *            or whether insertion on lanes for which an insertion has already a failed should be ignored
451      *            in the current time step.
452      * @return Whether the vehicle could be inserted
453      * @see MSLane::insertVehicle
454      */
455     bool insertVehicle(SUMOVehicle& v, SUMOTime time, const bool checkOnly = false, const bool forceCheck = false) const;
456 
457 
458     /** @brief Finds the emptiest lane allowing the vehicle class
459      *
460      * The emptiest lane is the one which vehicle insertion is most likely to succeed.
461      *
462      * If there are no vehicles before departPos, then the lane with the largest
463      * gap between departPos and the last vehicle is
464      * Otheriwise the lane with lowes occupancy is selected
465      * If there is more than one, the first according to its
466      *  index in the lane container is chosen.
467      *
468      * If allowed==0, the lanes allowed for the given vehicle class
469      *  will be used.
470      *
471      * @param[in] allowed The lanes to choose from
472      * @param[in] vclass The vehicle class to look for
473      * @param[in] departPos An upper bound on vehicle depart position
474      * @return the least occupied lane
475      * @see allowedLanes
476      */
477     MSLane* getFreeLane(const std::vector<MSLane*>* allowed, const SUMOVehicleClass vclass, double departPos) const;
478 
479 
480     /** @brief Finds a depart lane for the given vehicle parameters
481      *
482      * Depending on the depart lane procedure a depart lane is chosen.
483      *  Repeated calls with the same vehicle may return different results
484      *  if the procedure is "random" or "free". In case no appropriate
485      *  lane was found, 0 is returned.
486      *
487      * @param[in] veh The vehicle to get the depart lane for
488      * @return a possible/chosen depart lane, 0 if no lane can be used
489      */
490     MSLane* getDepartLane(MSVehicle& veh) const;
491 
492 
493     /** @brief Returns the last time a vehicle could not be inserted
494      * @return The current value
495      */
getLastFailedInsertionTime()496     inline SUMOTime getLastFailedInsertionTime() const {
497         return myLastFailedInsertionTime;
498     }
499 
500 
501     /** @brief Sets the last time a vehicle could not be inserted
502      * @param[in] time the new value
503      */
setLastFailedInsertionTime(SUMOTime time)504     inline void setLastFailedInsertionTime(SUMOTime time) const {
505         myLastFailedInsertionTime = time;
506     }
507     /// @}
508 
509 
510     /** @brief Performs lane changing on this edge */
511     virtual void changeLanes(SUMOTime t);
512 
513 
514     /// @todo extension: inner junctions are not filled
515     const MSEdge* getInternalFollowingEdge(const MSEdge* followerAfterInternal) const;
516 
517 
518     /// @brief returns the length of all internal edges on the junction until reaching the non-internal edge followerAfterInternal.
519     double getInternalFollowingLengthTo(const MSEdge* followerAfterInternal) const;
520 
521     /// @brief if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
522     const MSEdge* getNormalBefore() const;
523 
524     /// @brief Returns whether the vehicle (class) is not allowed on the edge
prohibits(const SUMOVehicle * const vehicle)525     inline bool prohibits(const SUMOVehicle* const vehicle) const {
526         if (vehicle == 0) {
527             return false;
528         }
529         const SUMOVehicleClass svc = vehicle->getVClass();
530         return (myCombinedPermissions & svc) != svc;
531     }
532 
getPermissions()533     inline SVCPermissions getPermissions() const {
534         return myCombinedPermissions;
535     }
536 
537     /** @brief Returns the edges's width (sum over all lanes)
538      * @return This edges's width
539      */
getWidth()540     double getWidth() const {
541         return myWidth;
542     }
543 
544     /// @brief Returns the right side offsets of this edge's sublanes
getSubLaneSides()545     const std::vector<double> getSubLaneSides() const {
546         return mySublaneSides;
547     }
548 
549     void rebuildAllowedLanes();
550 
551     void rebuildAllowedTargets(const bool updateVehicles = true);
552 
553 
554     /** @brief optimistic air distance heuristic for use in routing
555      * @param[in] other The edge to which the distance shall be returned
556      * @param[in] doBoundaryEstimate whether the distance should be estimated by looking at the distance of the bounding boxes
557      * @return The distance to the other edge
558      */
559     double getDistanceTo(const MSEdge* other, const bool doBoundaryEstimate = false) const;
560 
561 
562     /// @brief return the coordinates of the center of the given stop
563     static const Position getStopPosition(const SUMOVehicleParameter::Stop& stop);
564 
565 
566     /** @brief return the length of the edge
567      * @return The edge's length
568      */
getLength()569     inline double getLength() const {
570         return myLength;
571     }
572 
573 
574     /** @brief Returns the speed limit of the edge
575      * @caution The speed limit of the first lane is retured; should probably be the fastest edge
576      * @return The maximum speed allowed on this edge
577      */
578     double getSpeedLimit() const;
579 
580     /// @brief return shape.length() / myLength
581     double getLengthGeometryFactor() const;
582 
583     /** @brief Sets a new maximum speed for all lanes (used by TraCI and MSCalibrator)
584      * @param[in] val the new speed in m/s
585      */
586     void setMaxSpeed(double val) const;
587 
588     /** @brief Returns the maximum speed the vehicle may use on this edge
589      *
590      * @caution Only the first lane is considered
591      * @return The maximum velocity on this edge for the given vehicle
592      */
593     double getVehicleMaxSpeed(const SUMOTrafficObject* const veh) const;
594 
595 
addPerson(MSTransportable * p)596     virtual void addPerson(MSTransportable* p) const {
597         myPersons.insert(p);
598     }
599 
removePerson(MSTransportable * p)600     virtual void removePerson(MSTransportable* p) const {
601         std::set<MSTransportable*>::iterator i = myPersons.find(p);
602         if (i != myPersons.end()) {
603             myPersons.erase(i);
604         }
605     }
606 
607     /// @brief Add a container to myContainers
addContainer(MSTransportable * container)608     virtual void addContainer(MSTransportable* container) const {
609         myContainers.insert(container);
610     }
611 
612     /// @brief Remove container from myContainers
removeContainer(MSTransportable * container)613     virtual void removeContainer(MSTransportable* container) const {
614         std::set<MSTransportable*>::iterator i = myContainers.find(container);
615         if (i != myContainers.end()) {
616             myContainers.erase(i);
617         }
618     }
619 
isRoundabout()620     inline bool isRoundabout() const {
621         return myAmRoundabout;
622     }
623 
markAsRoundabout()624     void markAsRoundabout() {
625         myAmRoundabout = true;
626     }
627 
markDelayed()628     void markDelayed() const {
629         myAmDelayed = true;
630     }
631 
632     // return whether there have been vehicles on this edge at least once
isDelayed()633     inline bool isDelayed() const {
634         return myAmDelayed || myBidiEdge == nullptr || myBidiEdge->myAmDelayed;
635     }
636 
hasLaneChanger()637     bool hasLaneChanger() const {
638         return myLaneChanger != 0;
639     }
640 
641     /// @brief whether this edge allows changing to the opposite direction edge
642     bool canChangeToOpposite();
643 
644     /// @brief Returns the opposite direction edge if on exists else a nullptr
645     const MSEdge* getOppositeEdge() const;
646 
647     /// @brief get the mean speed
648     double getMeanSpeed() const;
649 
650     /// @brief whether any lane has a minor link
651     bool hasMinorLink() const;
652 
653     /// @brief return whether this edge is at the fringe of the network
isFringe()654     bool isFringe() const {
655         return myAmFringe;
656     }
657 
658     /// @brief whether this lane is selected in the GUI
isSelected()659     virtual bool isSelected() const {
660         return false;
661     }
662 
663     /// @brief grant exclusive access to the mesoscopic state
lock()664     virtual void lock() const {}
665 
666     /// @brief release exclusive access to the mesoscopic state
unlock()667     virtual void unlock() const {};
668 
669     /** @brief Inserts edge into the static dictionary
670         Returns true if the key id isn't already in the dictionary. Otherwise
671         returns false. */
672     static bool dictionary(const std::string& id, MSEdge* edge);
673 
674     /** @brief Returns the MSEdge associated to the key id if exists, otherwise returns 0. */
675     static MSEdge* dictionary(const std::string& id);
676 
677     /// @brief Returns the number of edges
678     static int dictSize();
679 
680     /// @brief Returns all edges with a numerical id
681     static const MSEdgeVector& getAllEdges();
682 
683     /** @brief Clears the dictionary */
684     static void clear();
685 
686     /** @brief Inserts IDs of all known edges into the given vector */
687     static void insertIDs(std::vector<std::string>& into);
688 
689 
690 public:
691     /// @name Static parser helper
692     /// @{
693 
694     /** @brief Parses the given string assuming it contains a list of edge ids divided by spaces
695      *
696      * Splits the string at spaces, uses polymorph method to generate edge vector.
697      * @param[in] desc The string containing space-separated edge ids
698      * @param[out] into The vector to fill
699      * @param[in] rid The id of the route these description belongs to; used for error message generation
700      * @exception ProcessError If one of the strings contained is not a known edge id
701      */
702     static void parseEdgesList(const std::string& desc, ConstMSEdgeVector& into,
703                                const std::string& rid);
704 
705 
706     /** @brief Parses the given string vector assuming it edge ids
707      * @param[in] desc The string vector containing edge ids
708      * @param[out] into The vector to fill
709      * @param[in] rid The id of the route these description belongs to; used for error message generation
710      * @exception ProcessError If one of the strings contained is not a known edge id
711      */
712     static void parseEdgesList(const std::vector<std::string>& desc, ConstMSEdgeVector& into,
713                                const std::string& rid);
714     /// @}
715 
716 
717 protected:
718     /** @class by_id_sorter
719      * @brief Sorts edges by their ids
720      */
721     class by_id_sorter {
722     public:
723         /// @brief constructor
by_id_sorter()724         explicit by_id_sorter() { }
725 
726         /// @brief comparing operator
operator()727         int operator()(const MSEdge* const e1, const MSEdge* const e2) const {
728             return e1->getNumericalID() < e2->getNumericalID();
729         }
730 
731     };
732 
733     /** @class transportable_by_position_sorter
734      * @brief Sorts transportables by their positions
735      */
736     class transportable_by_position_sorter {
737     public:
738         /// @brief constructor
transportable_by_position_sorter(SUMOTime timestep)739         explicit transportable_by_position_sorter(SUMOTime timestep): myTime(timestep) { }
740 
741         /// @brief comparing operator
742         int operator()(const MSTransportable* const c1, const MSTransportable* const c2) const;
743     private:
744         SUMOTime myTime;
745     };
746 
747 
748     /// @brief return upper bound for the depart position on this edge
749     double getDepartPosBound(const MSVehicle& veh, bool upper = true) const;
750 
751 protected:
752     /// @brief This edge's numerical id
753     const int myNumericalID;
754 
755     /// @brief Container for the edge's lane; should be sorted: (right-hand-traffic) the more left the lane, the higher the container-index
756     const std::vector<MSLane*>* myLanes;
757 
758     /// @brief This member will do the lane-change
759     MSLaneChanger* myLaneChanger;
760 
761     /// @brief the purpose of the edge
762     const SumoXMLEdgeFunc myFunction;
763 
764     /// @brief Vaporizer counter
765     int myVaporizationRequests;
766 
767     /// @brief The time of last insertion failure
768     mutable SUMOTime myLastFailedInsertionTime;
769 
770     /// @brief A cache for the rejected insertion attempts. Used to assure that no
771     ///        further insertion attempts are made on a lane where an attempt has
772     ///        already failed in the current time step if MSInsertionControl::myEagerInsertionCheck is off.
773     mutable std::set<int> myFailedInsertionMemory;
774 
775     /// @brief The crossed edges id for a crossing edge. On not crossing edges it is empty
776     std::vector<std::string> myCrossingEdges;
777 
778     /// @brief The succeeding edges
779     MSEdgeVector mySuccessors;
780 
781     MSConstEdgePairVector myViaSuccessors;
782 
783     /// @brief The preceeding edges
784     MSEdgeVector myPredecessors;
785 
786     /// @brief the junctions for this edge
787     MSJunction* myFromJunction;
788     MSJunction* myToJunction;
789 
790     /// @brief Persons on the edge for drawing and pushbutton
791     mutable std::set<MSTransportable*> myPersons;
792 
793     /// @brief Containers on the edge
794     mutable std::set<MSTransportable*> myContainers;
795 
796     /// @name Storages for allowed lanes (depending on vehicle classes)
797     /// @{
798 
799     /// @brief Associative container from vehicle class to allowed-lanes.
800     AllowedLanesCont myAllowed;
801 
802     /// @brief From target edge to lanes allowed to be used to reach it
803     AllowedLanesByTarget myAllowedTargets;
804 
805     /// @brief The intersection of lane permissions for this edge
806     SVCPermissions myMinimumPermissions;
807     /// @brief The union of lane permissions for this edge
808     SVCPermissions myCombinedPermissions;
809     /// @}
810 
811     /// @brief the real-world name of this edge (need not be unique)
812     std::string myStreetName;
813 
814     /// @brief the type of the edge (optionally used during network creation)
815     std::string myEdgeType;
816 
817     /// @brief the priority of the edge (used during network creation)
818     const int myPriority;
819 
820     /// Edge width [m]
821     double myWidth;
822 
823     /// @brief the length of the edge (cached value for speedup)
824     double myLength;
825 
826     /// @brief the traveltime on the empty edge (cached value for speedup)
827     double myEmptyTraveltime;
828 
829     /// @brief flat penalty when computing traveltime
830     double myTimePenalty;
831 
832     /// @brief whether this edge had a vehicle with less than max speed on it
833     mutable bool myAmDelayed;
834 
835     /// @brief whether this edge belongs to a roundabout
836     bool myAmRoundabout;
837 
838     /// @brief whether this edge is at the network fringe
839     bool myAmFringe;
840 
841     /// @brief the right side for each sublane on this edge
842     std::vector<double> mySublaneSides;
843 
844     /// @name Static edge container
845     /// @{
846 
847     /// @brief definition of the static dictionary type
848     typedef std::map< std::string, MSEdge* > DictType;
849 
850     /** @brief Static dictionary to associate string-ids with objects.
851      * @deprecated Move to MSEdgeControl, make non-static
852      */
853     static DictType myDict;
854 
855     /** @brief Static list of edges
856      * @deprecated Move to MSEdgeControl, make non-static
857      */
858     static MSEdgeVector myEdges;
859     /// @}
860 
861 
862     /// @brief The successors available for a given vClass
863     mutable std::map<SUMOVehicleClass, MSEdgeVector> myClassesSuccessorMap;
864 
865     /// @brief The successors available for a given vClass
866     mutable std::map<SUMOVehicleClass, MSConstEdgePairVector> myClassesViaSuccessorMap;
867 
868     /// @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
869     Boundary myBoundary;
870 
871 private:
872 
873     /// @brief the oppositing superposble edge
874     const MSEdge* myBidiEdge;
875 
876     /// @brief Invalidated copy constructor.
877     MSEdge(const MSEdge&);
878 
879     /// @brief assignment operator.
880     MSEdge& operator=(const MSEdge&);
881 
882     bool isSuperposable(const MSEdge* other);
883 
884     void addToAllowed(const SVCPermissions permissions, const std::vector<MSLane*>* allowedLanes, AllowedLanesCont& laneCont) const;
885 };
886 
887 
888 #endif
889 
890 /****************************************************************************/
891 
892