SUMO - Simulation of Urban MObility
MSDevice_Tripinfo.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2009-2018 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 /****************************************************************************/
18 // A device which collects info on the vehicle trip
19 /****************************************************************************/
20 
21 // ===========================================================================
22 // included modules
23 // ===========================================================================
24 #include <config.h>
25 
26 #include <microsim/MSGlobals.h>
27 #include <microsim/MSNet.h>
28 #include <microsim/MSLane.h>
29 #include <microsim/MSEdge.h>
30 #include <microsim/MSVehicle.h>
31 #include <mesosim/MEVehicle.h>
35 #include "MSDevice_Tripinfo.h"
36 
37 #define NOT_ARRIVED TIME2STEPS(-1)
38 
39 
40 // ===========================================================================
41 // static members
42 // ===========================================================================
43 std::set<const MSDevice_Tripinfo*, ComparatorNumericalIdLess> MSDevice_Tripinfo::myPendingOutput;
44 
52 
57 
66 
67 // ===========================================================================
68 // method definitions
69 // ===========================================================================
70 // ---------------------------------------------------------------------------
71 // static initialisation methods
72 // ---------------------------------------------------------------------------
73 void
74 MSDevice_Tripinfo::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
75  if (OptionsCont::getOptions().isSet("tripinfo-output") || OptionsCont::getOptions().getBool("duration-log.statistics")) {
76  MSDevice_Tripinfo* device = new MSDevice_Tripinfo(v, "tripinfo_" + v.getID());
77  into.push_back(device);
78  myPendingOutput.insert(device);
79  }
80 }
81 
82 
83 // ---------------------------------------------------------------------------
84 // MSDevice_Tripinfo-methods
85 // ---------------------------------------------------------------------------
86 MSDevice_Tripinfo::MSDevice_Tripinfo(SUMOVehicle& holder, const std::string& id) :
87  MSVehicleDevice(holder, id),
88  myDepartLane(""),
89  myDepartSpeed(-1),
90  myDepartPosLat(0),
91  myWaitingTime(0),
92  myAmWaiting(false),
93  myWaitingCount(0),
94  myStoppingTime(0),
97  myArrivalLane(""),
98  myArrivalPos(-1),
99  myArrivalPosLat(0),
100  myArrivalSpeed(-1),
101  myMesoTimeLoss(0) {
102 }
103 
104 
106  // ensure clean up for vaporized vehicles which do not generate output
107  myPendingOutput.erase(this);
108 }
109 
110 void
112  myVehicleCount = 0;
113  myTotalRouteLength = 0;
114  myTotalDuration = 0;
115  myTotalWaitingTime = 0;
116  myTotalTimeLoss = 0;
117  myTotalDepartDelay = 0;
119 
120  myWalkCount = 0;
124 
125  myRideCount = 0;
126  myRideBusCount = 0;
127  myRideRailCount = 0;
128  myRideBikeCount = 0;
129  myRideAbortCount = 0;
133 }
134 
135 bool
137  double /*newPos*/, double newSpeed) {
138  if (veh.isStopped()) {
140  } else if (newSpeed <= SUMO_const_haltingSpeed) {
142  if (!myAmWaiting) {
143  myWaitingCount++;
144  myAmWaiting = true;
145  }
146  } else {
147  myAmWaiting = false;
148  }
149  return true;
150 }
151 
152 void
154  const double /* frontOnLane */,
155  const double timeOnLane,
156  const double /* meanSpeedFrontOnLane */,
157  const double meanSpeedVehicleOnLane,
158  const double /* travelledDistanceFrontOnLane */,
159  const double /* travelledDistanceVehicleOnLane */,
160  const double /* meanLengthOnLane */) {
161 
162  // called by meso
163  const MEVehicle* mesoVeh = dynamic_cast<const MEVehicle*>(&veh);
164  assert(mesoVeh);
165  const double vmax = veh.getEdge()->getVehicleMaxSpeed(&veh);
166  if (vmax > 0) {
167  myMesoTimeLoss += TIME2STEPS(timeOnLane * (vmax - meanSpeedVehicleOnLane) / vmax);
168  }
169  myWaitingTime += veh.getWaitingTime();
171 }
172 
173 bool
176  if (!MSGlobals::gUseMesoSim) {
177  myDepartLane = static_cast<MSVehicle&>(veh).getLane()->getID();
178  myDepartPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
179  }
180  myDepartSpeed = veh.getSpeed();
181  } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
182  // notifyMove is not called while parking
183  // @note insertion delay when resuming after parking is included
185  }
186  return true;
187 }
188 
189 
190 bool
192  MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
193  if (reason >= MSMoveReminder::NOTIFICATION_ARRIVED) {
195  if (!MSGlobals::gUseMesoSim) {
196  myArrivalLane = static_cast<MSVehicle&>(veh).getLane()->getID();
197  myArrivalPosLat = static_cast<MSVehicle&>(veh).getLateralPositionOnLane();
198  }
199  // @note vehicle may have moved past its arrivalPos during the last step
200  // due to non-zero arrivalspeed but we consider it as arrived at the desired position
201  // However, vaporization may happen anywhere (via TraCI)
204  } else {
206  }
207  myArrivalSpeed = veh.getSpeed();
208  } else if (reason == MSMoveReminder::NOTIFICATION_PARKING) {
210  }
211  return true;
212 }
213 
214 void
215 MSDevice_Tripinfo::computeLengthAndDuration(double& routeLength, SUMOTime& duration) const {
216  SUMOTime finalTime;
217  double finalPos;
218  double finalPosOnInternal = 0;
219  if (myArrivalTime == NOT_ARRIVED) {
220  finalTime = MSNet::getInstance()->getCurrentTimeStep();
221  finalPos = myHolder.getPositionOnLane();
222  if (!MSGlobals::gUseMesoSim) {
223  const MSLane* lane = static_cast<MSVehicle&>(myHolder).getLane();
224  if (lane->getEdge().isInternal()) {
225  finalPosOnInternal = finalPos;
226  finalPos = myHolder.getEdge()->getLength();
227  }
228  }
229  } else {
230  finalTime = myArrivalTime;
231  finalPos = myArrivalPos;
232  }
233  const bool includeInternalLengths = MSGlobals::gUsingInternalLanes && MSNet::getInstance()->hasInternalLinks();
234  routeLength = myHolder.getRoute().getDistanceBetween(myHolder.getDepartPos(), finalPos,
235  myHolder.getRoute().begin(), myHolder.getCurrentRouteEdge(), includeInternalLengths) + finalPosOnInternal;
236 
237  duration = finalTime - myHolder.getDeparture();
238 }
239 
240 
241 void
243  const SUMOTime timeLoss = MSGlobals::gUseMesoSim ? myMesoTimeLoss : static_cast<MSVehicle&>(myHolder).getTimeLoss();
244  updateStatistics(timeLoss);
245  if (!OptionsCont::getOptions().isSet("tripinfo-output")) {
246  return;
247  }
248  myPendingOutput.erase(this);
249  double routeLength;
250  SUMOTime duration;
251  computeLengthAndDuration(routeLength, duration);
252 
253  // write
254  OutputDevice& os = OutputDevice::getDeviceByOption("tripinfo-output");
255  os.openTag("tripinfo").writeAttr("id", myHolder.getID());
256  os.writeAttr("depart", time2string(myHolder.getDeparture()));
257  os.writeAttr("departLane", myDepartLane);
258  os.writeAttr("departPos", myHolder.getDepartPos());
260  os.writeAttr("departPosLat", myDepartPosLat);
261  }
262  os.writeAttr("departSpeed", myDepartSpeed);
263  os.writeAttr("departDelay", time2string(myHolder.getDepartDelay()));
264  os.writeAttr("arrival", time2string(myArrivalTime));
265  os.writeAttr("arrivalLane", myArrivalLane);
266  os.writeAttr("arrivalPos", myArrivalPos);
268  os.writeAttr("arrivalPosLat", myArrivalPosLat);
269  }
270  os.writeAttr("arrivalSpeed", myArrivalSpeed);
271  os.writeAttr("duration", time2string(duration));
272  os.writeAttr("routeLength", routeLength);
273  os.writeAttr("waitingTime", time2string(myWaitingTime));
274  os.writeAttr("waitingCount", myWaitingCount);
275  os.writeAttr("stopTime", time2string(myStoppingTime));
276  os.writeAttr("timeLoss", time2string(timeLoss));
277  os.writeAttr("rerouteNo", myHolder.getNumberReroutes());
278  os.writeAttr("devices", toString(myHolder.getDevices()));
279  os.writeAttr("vType", myHolder.getVehicleType().getID());
280  os.writeAttr("speedFactor", myHolder.getChosenSpeedFactor());
281  os.writeAttr("vaporized", (myHolder.getEdge() == *(myHolder.getRoute().end() - 1) ? "" : "0"));
282  // cannot close tag because emission device output might follow
283 }
284 
285 
286 void
288  const bool writeTripinfos = OptionsCont::getOptions().isSet("tripinfo-output");
290  int undeparted = 0;
291  int departed = 0;
293  while (myPendingOutput.size() > 0) {
294  const MSDevice_Tripinfo* d = *myPendingOutput.begin();
295  if (d->myHolder.hasDeparted()) {
296  departed++;
297  d->generateOutput();
298  if (writeTripinfos) {
299  // @todo also generate emission output if holder has a device
300  OutputDevice::getDeviceByOption("tripinfo-output").closeTag();
301  } else {
302  myPendingOutput.erase(d);
303  }
304  } else {
305  undeparted++;
307  myPendingOutput.erase(d);
308  }
309  }
310  if (myWaitingDepartDelay > 0) {
311  myWaitingDepartDelay /= undeparted;
312  }
313 }
314 
315 
316 void
318  double routeLength;
319  SUMOTime duration;
320  computeLengthAndDuration(routeLength, duration);
321 
322  myVehicleCount++;
323  myTotalRouteLength += routeLength;
324  myTotalDuration += duration;
326  myTotalTimeLoss += timeLoss;
328 }
329 
330 
331 void
332 MSDevice_Tripinfo::addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss) {
333  myWalkCount++;
334  myTotalWalkRouteLength += walkLength;
335  myTotalWalkDuration += walkDuration;
336  myTotalWalkTimeLoss += walkTimeLoss;
337 }
338 
339 void
340 MSDevice_Tripinfo::addRideData(double rideLength, SUMOTime rideDuration, SUMOVehicleClass vClass, const std::string& line, SUMOTime waitingTime) {
341  myRideCount++;
342  if (rideDuration > 0) {
343  myTotalRideWaitingTime += waitingTime;
344  myTotalRideRouteLength += rideLength;
345  myTotalRideDuration += rideDuration;
346  if (vClass == SVC_BICYCLE) {
347  myRideBikeCount++;
348  } else if (!line.empty()) {
349  if (isRailway(vClass)) {
350  myRideRailCount++;
351  } else {
352  // some kind of road vehicle
353  myRideBusCount++;
354  }
355  }
356  } else {
358  }
359 }
360 
361 
362 std::string
364  std::ostringstream msg;
365  msg.setf(msg.fixed);
366  msg.precision(gPrecision);
367  msg << "Statistics (avg):\n"
368  << " RouteLength: " << getAvgRouteLength() << "\n"
369  << " Duration: " << getAvgDuration() << "\n"
370  << " WaitingTime: " << getAvgWaitingTime() << "\n"
371  << " TimeLoss: " << getAvgTimeLoss() << "\n"
372  << " DepartDelay: " << getAvgDepartDelay() << "\n";
373  if (myWaitingDepartDelay >= 0) {
374  msg << " DepartDelayWaiting: " << STEPS2TIME(myWaitingDepartDelay) << "\n";
375  }
376  if (myWalkCount > 0) {
377  msg << "Pedestrian Statistics (avg of " << myWalkCount << " walks):\n"
378  << " RouteLength: " << getAvgWalkRouteLength() << "\n"
379  << " Duration: " << getAvgWalkDuration() << "\n"
380  << " TimeLoss: " << getAvgWalkTimeLoss() << "\n";
381  }
382  if (myRideCount > 0) {
383  msg << "Ride Statistics (avg of " << myRideCount << " rides):\n"
384  << " WaitingTime: " << getAvgRideWaitingTime() << "\n"
385  << " RouteLength: " << getAvgRideRouteLength() << "\n"
386  << " Duration: " << getAvgRideDuration() << "\n"
387  << " Bus: " << myRideBusCount << "\n"
388  << " Train: " << myRideRailCount << "\n"
389  << " Bike: " << myRideBikeCount << "\n"
390  << " Aborted: " << myRideAbortCount << "\n";
391  }
392  return msg.str();
393 }
394 
395 
396 double
398  if (myVehicleCount > 0) {
400  } else {
401  return 0;
402  }
403 }
404 
405 double
407  if (myVehicleCount > 0) {
409  } else {
410  return 0;
411  }
412 }
413 
414 double
416  if (myVehicleCount > 0) {
418  } else {
419  return 0;
420  }
421 }
422 
423 
424 double
426  if (myVehicleCount > 0) {
428  } else {
429  return 0;
430  }
431 }
432 
433 
434 double
436  if (myVehicleCount > 0) {
438  } else {
439  return 0;
440  }
441 }
442 
443 
444 double
446  if (myWalkCount > 0) {
448  } else {
449  return 0;
450  }
451 }
452 
453 double
455  if (myWalkCount > 0) {
457  } else {
458  return 0;
459  }
460 }
461 
462 
463 double
465  if (myWalkCount > 0) {
467  } else {
468  return 0;
469  }
470 }
471 
472 
473 double
475  if (myRideCount > 0) {
477  } else {
478  return 0;
479  }
480 }
481 
482 double
484  if (myRideCount > 0) {
486  } else {
487  return 0;
488  }
489 }
490 
491 double
493  if (myRideCount > 0) {
495  } else {
496  return 0;
497  }
498 }
499 
500 
501 void
504  out.writeAttr(SUMO_ATTR_ID, getID());
505  std::vector<std::string> internals;
506  internals.push_back(myDepartLane);
507  internals.push_back(toString(myDepartPosLat));
508  internals.push_back(toString(myDepartSpeed));
509  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
510  out.closeTag();
511 }
512 
513 
514 void
516  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
517  bis >> myDepartLane;
518  bis >> myDepartPosLat;
519  bis >> myDepartSpeed;
520 }
521 
522 
523 /****************************************************************************/
static SUMOTime myTotalWalkDuration
static double getAvgRideRouteLength()
static int myRideBikeCount
static SUMOTime myTotalWalkTimeLoss
static double gLateralResolution
Definition: MSGlobals.h:85
const MSLane * getLane() const
Returns the lane the reminder works on.
SUMOTime myArrivalTime
The vehicle&#39;s arrival time.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
void computeLengthAndDuration(double &routeLength, SUMOTime &duration) const
MSEdge & getEdge() const
Returns the lane&#39;s edge.
Definition: MSLane.h:640
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
long long int SUMOTime
Definition: SUMOTime.h:36
static void addPedestrianData(double walkLength, SUMOTime walkDuration, SUMOTime walkTimeLoss)
record tripinfo data for pedestrians
virtual bool hasDeparted() const =0
Returns whether this vehicle has departed.
virtual double getArrivalPos() const =0
Returns this vehicle&#39;s desired arrivalPos for its current route (may change on reroute) ...
A vehicle from the mesoscopic point of view.
Definition: MEVehicle.h:45
static SUMOTime myTotalWaitingTime
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
bool notifyEnter(SUMOVehicle &veh, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
virtual const MSRoute & getRoute() const =0
Returns the current route.
void updateStatistics(SUMOTime timeLoss) const
update tripinfo statistics
static double myTotalRouteLength
bool notifyLeave(SUMOVehicle &veh, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
A device which collects info on the vehicle trip (mainly on departure and arrival) ...
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:27
static double getAvgTimeLoss()
vehicle is a bicycle
virtual const MSEdge * getEdge() const =0
Returns the edge the vehicle is currently at.
Notification
Definition of a vehicle state.
SUMOVehicle & myHolder
The vehicle that stores the device.
static void addRideData(double rideLength, SUMOTime rideDuration, SUMOVehicleClass vClass, const std::string &line, SUMOTime waitingTime)
record tripinfo data for rides
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:65
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:165
~MSDevice_Tripinfo()
Destructor.
SUMOTime DELTA_T
Definition: SUMOTime.cpp:35
The vehicle got vaporized.
static double myVehicleCount
global tripinfo statistics
const std::string & getID() const
Returns the id.
Definition: Named.h:78
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
static SUMOTime myWaitingDepartDelay
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
SUMOTime myStoppingTime
The overall intentional stopping time.
double getLength() const
return the length of the edge
Definition: MSEdge.h:568
static double getAvgRideWaitingTime()
static std::set< const MSDevice_Tripinfo *, ComparatorNumericalIdLess > myPendingOutput
devices which may still need to produce output
double myArrivalSpeed
The speed when arriving.
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
static double getAvgDuration()
SUMOTime myWaitingTime
The overall waiting time.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
#define NOT_ARRIVED
The state of a link.
static double getAvgWalkTimeLoss()
int myWaitingCount
The overall number of unintended stops.
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getCurrentStoppingTimeSeconds() const
Returns the delay that is accrued due to option –meso-tls-penalty or –meso-minor-penalty.
Definition: MEVehicle.cpp:271
static void generateOutputForUnfinished()
generate output for vehicles which are still in the network
void notifyMoveInternal(const SUMOVehicle &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal() ...
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
static std::string printStatistics()
get statistics for printing to stdout
Representation of a vehicle.
Definition: SUMOVehicle.h:60
static double getAvgWalkRouteLength()
Encapsulated SAX-Attributes.
virtual int getNumberReroutes() const =0
Returns the number of new routes this vehicle got.
SUMOTime myParkingStarted
The time when parking started.
static SUMOTime myTotalDuration
virtual const std::vector< MSVehicleDevice * > & getDevices() const =0
Returns this vehicle&#39;s devices.
The vehicle arrived at its destination (is deleted)
SUMOTime depart
The vehicle&#39;s departure time.
#define STEPS2TIME(x)
Definition: SUMOTime.h:58
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:263
static double myTotalRideWaitingTime
bool hasInternalLinks() const
return whether the network contains internal links
Definition: MSNet.h:605
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice *> &into)
Build devices for the given vehicle, if needed.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:69
double myArrivalPosLat
The lateral position on the lane the vehicle arrived at.
static double getAvgWalkDuration()
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:225
virtual double getChosenSpeedFactor() const =0
std::string myDepartLane
The lane the vehicle departed at.
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the maximum speed the vehicle may use on this edge.
Definition: MSEdge.cpp:911
static void cleanup()
resets counters
static SUMOTime myTotalRideDuration
static double getAvgRideDuration()
static double getAvgWaitingTime()
virtual double getDepartPos() const =0
Returns this vehicle&#39;s real departure position.
virtual SUMOTime getDepartDelay() const =0
The vehicle starts or ends parking.
The vehicle has departed (was inserted into the network)
bool notifyMove(SUMOVehicle &veh, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
static double myTotalWalkRouteLength
std::string myArrivalLane
The lane the vehicle arrived at.
virtual SUMOTime getDeparture() const =0
Returns this vehicle&#39;s real departure time.
virtual double getPositionOnLane() const =0
Get the vehicle&#39;s position along the lane.
static OutputDevice & getDeviceByOption(const std::string &name)
Returns the device described by the option.
double myDepartSpeed
The speed on departure.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle&#39;s parameter (including departure definition)
MSDevice_Tripinfo()
dummy constructor
static SUMOTime myTotalDepartDelay
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:94
Abstract in-vehicle device.
virtual SUMOTime getWaitingTime() const =0
static double getAvgRouteLength()
accessors for GUINet-Parameters
static double myTotalRideRouteLength
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
static double getAvgDepartDelay()
static int myRideAbortCount
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop.
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:64
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static int myRideRailCount
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:70
void generateOutput() const
Called on writing tripinfo output.
static SUMOTime myTotalTimeLoss
SUMOTime myMesoTimeLoss
The time loss when compared to the desired and allowed speed.
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
double myDepartPosLat
The lateral depart position.
virtual double getSpeed() const =0
Returns the vehicle&#39;s current speed.
void loadState(const SUMOSAXAttributes &attrs)
Loads the state of the device from the given description.
static bool gUseMesoSim
Definition: MSGlobals.h:91
Representation of a lane in the micro simulation.
Definition: MSLane.h:78
double myArrivalPos
The position on the lane the vehicle arrived at.
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:76
virtual const std::string & getID() const =0
Get the vehicle&#39;s ID.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
void saveState(OutputDevice &out) const
Saves the state of the device.
bool myAmWaiting
Whether the vehicle is currently waiting.
virtual const MSVehicleType & getVehicleType() const =0
Returns the vehicle&#39;s type.
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes...
Definition: MSRoute.cpp:277