SUMO - Simulation of Urban MObility
IntermodalRouter.h
Go to the documentation of this file.
1 /****************************************************************************/
7 // The Pedestrian Router build a special network and (delegegates to a SUMOAbstractRouter)
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 #ifndef IntermodalRouter_h
21 #define IntermodalRouter_h
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include <vector>
35 #include <algorithm>
36 #include <assert.h>
38 #include <utils/common/SUMOTime.h>
39 #include <utils/common/ToString.h>
40 #include "SUMOAbstractRouter.h"
41 #include "SUMOVehicleParameter.h"
42 #include "DijkstraRouterTT.h"
43 #include "IntermodalNetwork.h"
44 #include "CarEdge.h"
45 #include "PedestrianRouter.h"
46 
47 //#define IntermodalRouter_DEBUG_ROUTES
48 
49 
50 // ===========================================================================
51 // class definitions
52 // ===========================================================================
57 template<class E, class L, class N, class V, class INTERNALROUTER = DijkstraRouterTT<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V>, prohibited_withPermissions<IntermodalEdge<E, L, N, V>, IntermodalTrip<E, N, V> > > >
58 class IntermodalRouter : public SUMOAbstractRouter<E, IntermodalTrip<E, N, V> > {
59 private:
66 
67 public:
68  struct TripItem {
69  TripItem(const std::string& _line = "") : line(_line) {}
70  std::string line;
71  std::string destStop;
72  std::vector<const E*> edges;
73  };
74 
77  SUMOAbstractRouter<E, _IntermodalTrip>(0, "IntermodalRouter"), myAmClone(false), myInternalRouter(0), myIntermodalNet(0), myNumericalID(0), myCallback(callback) {
78  }
79 
81  virtual ~IntermodalRouter() {
82  delete myInternalRouter;
83  if (!myAmClone) {
84  delete myIntermodalNet;
85  }
86  }
87 
89  createNet();
91  }
92 
93  void addAccess(const std::string& stopId, const E* stopEdge, const double pos) {
94  assert(stopEdge != 0);
95  if (myStopConnections.count(stopId) == 0) {
96  myStopConnections[stopId] = new StopEdge<E, L, N, V>(stopId, myNumericalID++, stopEdge);
98  }
99  _IntermodalEdge* const stopConn = myStopConnections[stopId];
100  const L* lane = getSidewalk<E, L>(stopEdge);
101  if (lane != 0) {
102  const std::pair<_IntermodalEdge*, _IntermodalEdge*>& pair = myIntermodalNet->getBothDirections(stopEdge);
103  _IntermodalEdge* const fwdSplit = new PedestrianEdge<E, L, N, V>(myNumericalID++, stopEdge, lane, true, pos);
104  const int splitIndex = splitEdge(pair.first, fwdSplit, pos, stopConn);
105  _IntermodalEdge* const backSplit = new PedestrianEdge<E, L, N, V>(myNumericalID++, stopEdge, lane, false, pos);
106  splitEdge(pair.second, backSplit, stopEdge->getLength() - pos, stopConn);
107  if (splitIndex >= 0) {
108  _IntermodalEdge* carSplit = 0;
109  if (myCarLookup.count(stopEdge) > 0) {
110  carSplit = new CarEdge<E, L, N, V>(myNumericalID++, stopEdge, pos);
111  splitEdge(myCarLookup[stopEdge], carSplit, pos, fwdSplit, backSplit);
112  }
113 
114  _IntermodalEdge* const prevDep = myIntermodalNet->getDepartEdge(stopEdge, pos);
115  _IntermodalEdge* const backBeforeSplit = myAccessSplits[pair.second][myAccessSplits[pair.second].size() - 1 - splitIndex];
116  // depart and arrival edges (the router can decide the initial direction to take and the direction to arrive from)
117  _IntermodalEdge* const depConn = new _IntermodalEdge(stopEdge->getID() + "_depart_connector" + toString(pos), myNumericalID++, stopEdge, "!connector");
118  depConn->addSuccessor(fwdSplit);
119  depConn->addSuccessor(backBeforeSplit);
120  depConn->setLength(fwdSplit->getLength());
121  prevDep->removeSuccessor(backBeforeSplit);
122  prevDep->addSuccessor(backSplit);
123  prevDep->setLength(backSplit->getLength());
124  if (carSplit != 0) {
125  depConn->addSuccessor(carSplit);
126  }
127 
128  _IntermodalEdge* const arrConn = new _IntermodalEdge(stopEdge->getID() + "_arrival_connector" + toString(pos), myNumericalID++, stopEdge, "!connector");
129  fwdSplit->addSuccessor(arrConn);
130  backBeforeSplit->addSuccessor(arrConn);
131  if (carSplit != 0) {
132  carSplit->addSuccessor(arrConn);
133  }
134  myIntermodalNet->addConnectors(depConn, arrConn, splitIndex);
135  }
136  }
137  }
138 
139  void addSchedule(const SUMOVehicleParameter& pars, const std::vector<SUMOVehicleParameter::Stop>* addStops = 0) {
140  SUMOTime lastUntil = 0;
141  std::vector<SUMOVehicleParameter::Stop> validStops;
142  if (addStops != 0) {
143  // stops are part of a stand-alone route. until times are offsets from vehicle departure
144  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = addStops->begin(); s != addStops->end(); ++s) {
145  if (myStopConnections.count(s->busstop) > 0) {
146  // compute stop times for the first vehicle
147  SUMOVehicleParameter::Stop stop = *s;
148  stop.until += pars.depart;
149  if (stop.until >= lastUntil) {
150  validStops.push_back(stop);
151  lastUntil = stop.until;
152  } else {
153  WRITE_WARNING("Ignoring unordered stop at '" + stop.busstop + "' at " + time2string(stop.until) + " for vehicle '" + pars.id + "'.");
154  }
155  }
156  }
157  }
158  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = pars.stops.begin(); s != pars.stops.end(); ++s) {
159  // stops are part of the vehicle until times are absolute times for the first vehicle
160  if (myStopConnections.count(s->busstop) > 0 && s->until >= lastUntil) {
161  validStops.push_back(*s);
162  lastUntil = s->until;
163  }
164  }
165  if (validStops.size() < 2) {
166  WRITE_WARNING("Ignoring public transport line '" + pars.line + "' with less than two usable stops.");
167  return;
168  }
169 
170  typename std::vector<_PTEdge*>& lineEdges = myPTLines[pars.line];
171  if (lineEdges.empty()) {
172  _IntermodalEdge* lastStop = 0;
173  SUMOTime lastTime = 0;
174  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = validStops.begin(); s != validStops.end(); ++s) {
175  _IntermodalEdge* currStop = myStopConnections[s->busstop];
176  if (lastStop != 0) {
177  _PTEdge* const newEdge = new _PTEdge(s->busstop, myNumericalID++, lastStop, currStop->getEdge(), pars.line);
178  myIntermodalNet->addEdge(newEdge);
179  newEdge->addSchedule(lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime));
180  lastStop->addSuccessor(newEdge);
181  newEdge->addSuccessor(currStop);
182  lineEdges.push_back(newEdge);
183  }
184  lastTime = s->until;
185  lastStop = currStop;
186  }
187  } else {
188  if (validStops.size() != lineEdges.size() + 1) {
189  WRITE_WARNING("Number of stops for public transport line '" + pars.line + "' does not match earlier definitions, ignoring schedule.");
190  return;
191  }
192  if (lineEdges.front()->getEntryStop() != myStopConnections[validStops.front().busstop]) {
193  WRITE_WARNING("Different stop for '" + pars.line + "' compared to earlier definitions, ignoring schedule.");
194  return;
195  }
196  typename std::vector<_PTEdge*>::const_iterator lineEdge = lineEdges.begin();
197  typename std::vector<SUMOVehicleParameter::Stop>::const_iterator s = validStops.begin() + 1;
198  for (; s != validStops.end(); ++s, ++lineEdge) {
199  if ((*lineEdge)->getSuccessors(SVC_IGNORING)[0] != myStopConnections[s->busstop]) {
200  WRITE_WARNING("Different stop for '" + pars.line + "' compared to earlier definitions, ignoring schedule.");
201  return;
202  }
203  }
204  SUMOTime lastTime = validStops.front().until;
205  for (lineEdge = lineEdges.begin(), s = validStops.begin() + 1; lineEdge != lineEdges.end(); ++lineEdge, ++s) {
206  (*lineEdge)->addSchedule(lastTime, lastTime + pars.repetitionOffset * (pars.repetitionNumber - 1), pars.repetitionOffset, STEPS2TIME(s->until - lastTime));
207  lastTime = s->until;
208  }
209  }
210  }
211 
214  bool compute(const E* from, const E* to, double departPos, double arrivalPos, double speed,
215  const V* const vehicle, const SVCPermissions modeSet, SUMOTime msTime,
216  std::vector<TripItem>& into) {
217  createNet();
218  _IntermodalTrip trip(from, to, departPos, arrivalPos, speed, msTime, 0, vehicle, modeSet);
219  std::vector<const _IntermodalEdge*> intoPed;
220  const bool success = myInternalRouter->compute(myIntermodalNet->getDepartEdge(from, departPos),
221  myIntermodalNet->getArrivalEdge(to, arrivalPos),
222  &trip, msTime, intoPed);
223  if (success) {
224  std::string lastLine = "";
225  for (int i = 0; i < (int)intoPed.size(); ++i) {
226  if (intoPed[i]->includeInRoute(false)) {
227  if (intoPed[i]->getLine() == "!stop") {
228  into.back().destStop = intoPed[i]->getID();
229  } else {
230  if (intoPed[i]->getLine() != lastLine) {
231  lastLine = intoPed[i]->getLine();
232  if (lastLine == "!car") {
233  into.push_back(TripItem(vehicle->getID()));
234  } else if (lastLine == "!ped") {
235  into.push_back(TripItem());
236  } else {
237  into.push_back(TripItem(lastLine));
238  }
239  }
240  if (into.back().edges.empty() || into.back().edges.back() != intoPed[i]->getEdge()) {
241  into.back().edges.push_back(intoPed[i]->getEdge());
242  }
243  }
244  }
245  }
246  }
247 #ifdef IntermodalRouter_DEBUG_ROUTES
248  double time = STEPS2TIME(msTime);
249  for (int i = 0; i < intoPed.size(); ++i) {
250  time += myInternalRouter->getEffort(intoPed[i], &trip, time);
251  }
252  std::cout << TIME2STEPS(msTime) << " trip from " << from->getID() << " to " << to->getID()
253  << " departPos=" << departPos
254  << " arrivalPos=" << arrivalPos
255  << " edges=" << toString(intoPed)
256 // << " resultEdges=" << toString(into)
257  << " time=" << time
258  << "\n";
259 #endif
260  return success;
261  }
262 
265  bool compute(const E*, const E*, const _IntermodalTrip* const,
266  SUMOTime, std::vector<const E*>&) {
267  throw ProcessError("Do not use this method");
268  }
269 
270  double recomputeCosts(const std::vector<const E*>&, const _IntermodalTrip* const, SUMOTime) const {
271  throw ProcessError("Do not use this method");
272  }
273 
274  void prohibit(const std::vector<E*>& toProhibit) {
275  std::vector<_IntermodalEdge*> toProhibitPE;
276  for (typename std::vector<E*>::const_iterator it = toProhibit.begin(); it != toProhibit.end(); ++it) {
277  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).first);
278  toProhibitPE.push_back(myIntermodalNet->getBothDirections(*it).second);
279  toProhibitPE.push_back(getCarEdge(*it));
280  }
281  myInternalRouter->prohibit(toProhibitPE);
282  }
283 
284 private:
285  IntermodalRouter(_IntermodalNetwork* net):
286  SUMOAbstractRouter<E, _IntermodalTrip>(0, "PedestrianRouter"), myAmClone(true),
287  myInternalRouter(new INTERNALROUTER(net->getAllEdges(), true, &_IntermodalEdge::getTravelTimeStatic)),
288  myIntermodalNet(net), myNumericalID((int)net->getAllEdges().size()) {}
289 
290  int splitEdge(_IntermodalEdge* const toSplit, _IntermodalEdge* afterSplit, const double pos,
291  _IntermodalEdge* const fwdConn, _IntermodalEdge* const backConn = 0) {
292  int splitIndex = 1;
293  std::vector<_IntermodalEdge*>& splitList = myAccessSplits[toSplit];
294  if (splitList.empty()) {
295  splitList.push_back(toSplit);
296  }
297  typename std::vector<_IntermodalEdge*>::iterator splitIt = splitList.begin();
298  double relPos = pos;
299  while (splitIt != splitList.end() && relPos > (*splitIt)->getLength() + POSITION_EPS) {
300  relPos -= (*splitIt)->getLength();
301  ++splitIt;
302  splitIndex++;
303  }
304  assert(splitIt != splitList.end());
305  _IntermodalEdge* const beforeSplit = *splitIt;
306  if (fabs(relPos - beforeSplit->getLength()) < POSITION_EPS && splitIt + 1 != splitList.end()) {
307  // don't split, use the present split edges
308  splitIndex = -1;
309  afterSplit = *(splitIt + 1);
310  } else {
311  myIntermodalNet->addEdge(afterSplit);
312  afterSplit->setSuccessors(beforeSplit->getSuccessors(SVC_IGNORING));
313  beforeSplit->clearSuccessors();
314  beforeSplit->addSuccessor(afterSplit);
315  afterSplit->setLength(beforeSplit->getLength() - relPos);
316  beforeSplit->setLength(relPos);
317  splitList.insert(splitIt + 1, afterSplit);
318  }
319  // add access to / from edge
320  _AccessEdge* access = new _AccessEdge(myNumericalID++, beforeSplit, fwdConn);
321  myIntermodalNet->addEdge(access);
322  beforeSplit->addSuccessor(access);
323  access->addSuccessor(fwdConn);
324  if (backConn == 0) {
325  _AccessEdge* exit = new _AccessEdge(myNumericalID++, fwdConn, afterSplit);
326  myIntermodalNet->addEdge(exit);
327  fwdConn->addSuccessor(exit);
328  exit->addSuccessor(afterSplit);
329  } else {
330  _AccessEdge* backward = new _AccessEdge(myNumericalID++, beforeSplit, backConn);
331  myIntermodalNet->addEdge(backward);
332  beforeSplit->addSuccessor(backward);
333  backward->addSuccessor(backConn);
334  }
335  return splitIndex;
336  }
337 
338  void addCarEdges(const std::vector<E*>& edges) {
339  for (typename std::vector<E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
340  const E* const edge = *i;
341  if (!edge->isInternal()) {
342  myCarLookup[edge] = new CarEdge<E, L, N, V>(myNumericalID++, edge);
344  }
345  }
346  for (typename std::vector<E*>::const_iterator i = edges.begin(); i != edges.end(); ++i) {
347  const E* const edge = *i;
348  if (!edge->isInternal()) {
349  _IntermodalEdge* startConnector = myIntermodalNet->getDepartEdge(edge);
350  _IntermodalEdge* endConnector = myIntermodalNet->getArrivalEdge(edge);
351  _IntermodalEdge* carEdge = getCarEdge(edge);
352  const std::vector<E*>& successors = edge->getSuccessors();
353  for (typename std::vector<E*>::const_iterator it = successors.begin(); it != successors.end(); ++it) {
354  carEdge->addSuccessor(getCarEdge(*it));
355  }
356  startConnector->addSuccessor(carEdge);
357  carEdge->addSuccessor(endConnector);
358  }
359  }
360  }
361 
362  inline void createNet() {
363  if (myIntermodalNet == 0) {
364  myIntermodalNet = new _IntermodalNetwork(E::getAllEdges(), myNumericalID);
365  myNumericalID = (int)myIntermodalNet->getAllEdges().size();
366  addCarEdges(E::getAllEdges());
367  myCallback(*this);
369  }
370  }
371 
373  _IntermodalEdge* getCarEdge(const E* e) {
374  typename std::map<const E*, _IntermodalEdge*>::const_iterator it = myCarLookup.find(e);
375  if (it == myCarLookup.end()) {
376  throw ProcessError("Car edge '" + e->getID() + "' not found in pedestrian network.");
377  }
378  return it->second;
379  }
380 
381 private:
382  const bool myAmClone;
383  INTERNALROUTER* myInternalRouter;
384  _IntermodalNetwork* myIntermodalNet;
387 
389  std::map<const E*, _IntermodalEdge*> myCarLookup;
390 
392  std::map<std::string, std::vector<_PTEdge*> > myPTLines;
393 
395  std::map<std::string, _IntermodalEdge*> myStopConnections;
396 
398  std::map<_IntermodalEdge*, std::vector<_IntermodalEdge*> > myAccessSplits;
399 
400 
401 private:
404 
405 };
406 
407 
408 
413 template<class E, class L, class N, class V>
415 public:
418  IntermodalRouter<E, L, N, V>* interRouter)
419  : myVehRouter(vehRouter), myPedRouter(pedRouter), myInterRouter(interRouter) {}
420 
422  : myVehRouter(original.getVehicleRouter().clone()),
423  myPedRouter(static_cast<PedestrianRouterDijkstra<E, L, N, V>*>(original.myPedRouter == 0 ? 0 : original.getPedestrianRouter().clone())),
424  myInterRouter(static_cast<IntermodalRouter<E, L, N, V>*>(original.myInterRouter == 0 ? 0 : original.getIntermodalRouter().clone())) {}
425 
427  return *myVehRouter;
428  }
429 
431  return *myPedRouter;
432  }
433 
435  return *myInterRouter;
436  }
437 
438  virtual ~RouterProvider() {
439  delete myVehRouter;
440  delete myPedRouter;
441  delete myInterRouter;
442  }
443 
444 
445 private:
449 
450 
451 private:
454 
455 };
456 
457 
458 #endif
459 
460 /****************************************************************************/
IntermodalRouter< E, L, N, V > & getIntermodalRouter() const
IntermodalRouter & operator=(const IntermodalRouter &s)
Invalidated assignment operator.
std::map< const E *, _IntermodalEdge * > myCarLookup
retrieve the car edge for the given input edge E
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
_IntermodalEdge * getDepartEdge(const E *e, const double pos=-1.)
Returns the departing Intermodal edge.
const std::vector< _IntermodalEdge * > & getAllEdges()
RouterProvider(const RouterProvider &original)
virtual ~RouterProvider()
SUMOAbstractRouter< E, V > *const myVehRouter
void addEdge(_IntermodalEdge *edge)
void(* CreateNetCallback)(IntermodalRouter< E, L, N, V, INTERNALROUTER > &)
int splitEdge(_IntermodalEdge *const toSplit, _IntermodalEdge *afterSplit, const double pos, _IntermodalEdge *const fwdConn, _IntermodalEdge *const backConn=0)
static double getTravelTimeStatic(const IntermodalEdge *const edge, const IntermodalTrip< E, N, V > *const trip, double time)
AccessEdge< E, L, N, V > _AccessEdge
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
void addSuccessor(IntermodalEdge *s)
_IntermodalNetwork * myIntermodalNet
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
std::map< _IntermodalEdge *, std::vector< _IntermodalEdge * > > myAccessSplits
retrieve the splitted edges for the given "original"
the car edge type that is given to the internal router (SUMOAbstractRouter)
Definition: CarEdge.h:44
void addSchedule(const SUMOTime begin, const SUMOTime end, const SUMOTime period, const double travelTimeSec)
Definition: CarEdge.h:158
std::map< std::string, std::vector< _PTEdge * > > myPTLines
retrieve the public transport edges for the given line
SUMOTime until
The time at which the vehicle may continue its journey.
const std::string & getID() const
Returns the id.
Definition: Named.h:66
#define TIME2STEPS(x)
Definition: SUMOTime.h:66
TripItem(const std::string &_line="")
void addAccess(const std::string &stopId, const E *stopEdge, const double pos)
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
void removeSuccessor(const IntermodalEdge *const edge)
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
const E * getEdge() const
std::string busstop
(Optional) bus stop if one is assigned to the stop
PublicTransportEdge< E, L, N, V > _PTEdge
bool compute(const E *, const E *, const _IntermodalTrip *const, SUMOTime, std::vector< const E *> &)
Builds the route between the given edges using the minimum effort at the given time The definition of...
bool compute(const E *from, const E *to, double departPos, double arrivalPos, double speed, const V *const vehicle, const SVCPermissions modeSet, SUMOTime msTime, std::vector< TripItem > &into)
Builds the route between the given edges using the minimum effort at the given time The definition of...
_IntermodalEdge * getArrivalEdge(const E *e, const double pos=-1.)
Returns the arriving Intermodal edge.
CreateNetCallback myCallback
void addSchedule(const SUMOVehicleParameter &pars, const std::vector< SUMOVehicleParameter::Stop > *addStops=0)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
IntermodalRouter(_IntermodalNetwork *net)
void setSuccessors(const std::vector< IntermodalEdge *> &edges)
IntermodalTrip< E, N, V > _IntermodalTrip
SUMOAbstractRouter< E, _IntermodalTrip > * clone()
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
the "vehicle" type that is given to the internal router (SUMOAbstractRouter)
PedestrianRouterDijkstra< E, L, N, V > & getPedestrianRouter() const
IntermodalRouter(CreateNetCallback callback)
Constructor.
#define POSITION_EPS
Definition: config.h:175
std::vector< const E * > edges
_IntermodalEdge * getCarEdge(const E *e)
Returns the associated car edge.
PedestrianRouterDijkstra< E, L, N, V > *const myPedRouter
the pedestrian network storing edges, connections and the mappings to the "real" edges ...
std::string line
The vehicle&#39;s line (mainly for public transport)
the base edge type that is given to the internal router (SUMOAbstractRouter)
INTERNALROUTER * myInternalRouter
std::map< std::string, _IntermodalEdge * > myStopConnections
retrieve the connecting edges for the given "bus" stop
SUMOAbstractRouter< E, V > & getVehicleRouter() const
IntermodalNetwork< E, L, N, V > _IntermodalNetwork
Structure representing possible vehicle parameter.
IntermodalEdge< E, L, N, V > _IntermodalEdge
virtual ~IntermodalRouter()
Destructor.
Definition of vehicle stop (position and duration)
the public transport edge type connecting the stop edges
Definition: CarEdge.h:132
const EdgePair & getBothDirections(const E *e)
Returns the pair of forward and backward edge.
void prohibit(const std::vector< E *> &toProhibit)
IntermodalRouter< E, L, N, V > *const myInterRouter
double getLength() const
double recomputeCosts(const std::vector< const E *> &, const _IntermodalTrip *const, SUMOTime) const
the pedestrian edge type that is given to the internal router (SUMOAbstractRouter) ...
long long int SUMOTime
Definition: TraCIDefs.h:52
RouterProvider(SUMOAbstractRouter< E, V > *vehRouter, PedestrianRouterDijkstra< E, L, N, V > *pedRouter, IntermodalRouter< E, L, N, V > *interRouter)
void addConnectors(_IntermodalEdge *const depConn, _IntermodalEdge *const arrConn, const int splitIndex)
the stop edge type representing bus and train stops
Definition: CarEdge.h:115
vehicles ignoring classes
void addCarEdges(const std::vector< E *> &edges)
the access edge connecting different modes that is given to the internal router (SUMOAbstractRouter) ...
Definition: CarEdge.h:193
std::string id
The vehicle&#39;s id.
void setLength(const double length)