SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSRouteHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // Parser and container for routes during their loading
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
35 #include <map>
36 #include <vector>
37 #include <microsim/MSRoute.h>
38 #include <microsim/MSEdge.h>
39 #include <microsim/MSVehicleType.h>
40 #include <microsim/MSVehicle.h>
43 #include <microsim/MSLane.h>
44 #include "MSRouteHandler.h"
45 #include "MSPersonControl.h"
53 #include "MSNet.h"
54 
56 #include <microsim/MSGlobals.h>
58 
59 #ifdef CHECK_MEMORY_LEAKS
60 #include <foreign/nvwa/debug_new.h>
61 #endif // CHECK_MEMORY_LEAKS
62 
63 
64 // ===========================================================================
65 // method definitions
66 // ===========================================================================
67 MSRouteHandler::MSRouteHandler(const std::string& file,
68  bool addVehiclesDirectly) :
69  SUMORouteHandler(file),
70  myActivePlan(0),
71  myAddVehiclesDirectly(addVehiclesDirectly),
72  myCurrentVTypeDistribution(0),
73  myCurrentRouteDistribution(0) {
74  myActiveRoute.reserve(100);
75 }
76 
77 
79 }
80 
81 
82 void
84  const SUMOSAXAttributes& attrs) {
85  SUMORouteHandler::myStartElement(element, attrs);
86  switch (element) {
87  case SUMO_TAG_PERSON:
89  break;
90  case SUMO_TAG_RIDE: {
91  const std::string pid = myVehicleParameter->id;
92  bool ok = true;
93  MSEdge* from = 0;
94  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
95  StringTokenizer st(desc);
96  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
97  MSBusStop* bs = 0;
98  if (bsID != "") {
99  bs = MSNet::getInstance()->getBusStop(bsID);
100  if (bs == 0) {
101  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
102  }
103  }
104  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
105  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
106  from = MSEdge::dictionary(fromID);
107  if (from == 0) {
108  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
109  }
110  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != from) {
111  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + myActivePlan->back()->getDestination().getID() + ").");
112  }
113  if (myActivePlan->empty()) {
115  *from, -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
116  }
117  } else if (myActivePlan->empty()) {
118  throw ProcessError("The start edge within for person '" + pid + "' is not known.");
119  }
120  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
121  MSEdge* to = MSEdge::dictionary(toID);
122  if (to == 0) {
123  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
124  }
125  myActivePlan->push_back(new MSPerson::MSPersonStage_Driving(*to, bs, st.getVector()));
126  break;
127  }
128  case SUMO_TAG_WALK: {
129  myActiveRoute.clear();
130  bool ok = true;
131  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
133  } else {
134  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
135  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok);
136  MSEdge* from = MSEdge::dictionary(fromID);
137  if (from == 0) {
138  throw ProcessError("The from edge '" + fromID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
139  }
140  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok);
141  MSEdge* to = MSEdge::dictionary(toID);
142  if (to == 0) {
143  throw ProcessError("The to edge '" + toID + "' within a walk of person '" + myVehicleParameter->id + "' is not known.");
144  }
145  MSNet::getInstance()->getRouterTT().compute(from, to, 0, 0, myActiveRoute); // @todo: only footways, current time?
146  }
147  }
148  if (myActiveRoute.empty()) {
149  throw ProcessError("No edges to walk for person '" + myVehicleParameter->id + "'.");
150  }
151  if (!myActivePlan->empty() && &myActivePlan->back()->getDestination() != myActiveRoute.front()) {
152  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + myActiveRoute.front()->getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
153  }
154  SUMOReal departPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_DEPARTPOS, myVehicleParameter->id.c_str(), ok, 0);
155  SUMOReal arrivalPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok, -1);
156  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, 0, ok, -1);
157  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
158  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
159  }
161  if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
162  speed = attrs.getOpt<SUMOReal>(SUMO_ATTR_SPEED, 0, ok, speed);
163  if (speed <= 0) {
164  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
165  }
166  }
167  std::string bsID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, 0, ok, "");
168  MSBusStop* bs = 0;
169  if (bsID != "") {
170  bs = MSNet::getInstance()->getBusStop(bsID);
171  if (bs == 0) {
172  throw ProcessError("Unknown bus stop '" + bsID + "' for person '" + myVehicleParameter->id + "'.");
173  }
174  }
175  if (myActivePlan->empty()) {
177  *myActiveRoute.front(), -1, myVehicleParameter->depart, departPos, "start"));
178  }
179  myActivePlan->push_back(new MSPerson::MSPersonStage_Walking(myActiveRoute, bs, duration, speed, departPos, arrivalPos));
180  myActiveRoute.clear();
181  break;
182  }
183  case SUMO_TAG_FLOW:
184  if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
186  bool ok = true;
187  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
188  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
189  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
190  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
191  closeRoute(true);
192  }
193  break;
194  case SUMO_TAG_TRIP: {
195  bool ok = true;
197  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok),
198  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
199  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok),
200  myActiveRoute, "for vehicle '" + myVehicleParameter->id + "'");
201  } else {
202  const MSEdge* fromTaz = MSEdge::dictionary(myVehicleParameter->fromTaz + "-source");
203  if (fromTaz == 0) {
204  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' not known for '" + myVehicleParameter->id + "'!");
205  } else if (fromTaz->getNoFollowing() == 0) {
206  WRITE_ERROR("Source district '" + myVehicleParameter->fromTaz + "' has no outgoing edges for '" + myVehicleParameter->id + "'!");
207  } else {
208  myActiveRoute.push_back(fromTaz->getFollower(0));
209  }
210  }
211  closeRoute(true);
212  closeVehicle();
213  }
214  break;
215  default:
216  break;
217  }
218  // parse embedded vtype information
219  if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_PARAM) {
221  return;
222  }
223 }
224 
225 
226 void
228  bool ok = true;
229  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
230  if (ok) {
232  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
233  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
234  StringTokenizer st(vTypes);
235  while (st.hasNext()) {
236  std::string vtypeID = st.next();
238  if (type == 0) {
239  throw ProcessError("Unknown vtype '" + vtypeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
240  }
242  }
243  }
244  }
245 }
246 
247 
248 void
250  if (myCurrentVTypeDistribution != 0) {
251  if (MSGlobals::gStateLoaded && MSNet::getInstance()->getVehicleControl().hasVTypeDistribution(myCurrentVTypeDistributionID)) {
253  return;
254  }
257  throw ProcessError("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
258  }
259  if (!MSNet::getInstance()->getVehicleControl().addVTypeDistribution(myCurrentVTypeDistributionID, myCurrentVTypeDistribution)) {
261  throw ProcessError("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
262  }
264  }
265 }
266 
267 
268 void
270  // check whether the id is really necessary
271  std::string rid;
272  if (myCurrentRouteDistribution != 0) {
274  rid = "distribution '" + myCurrentRouteDistributionID + "'";
275  } else if (myVehicleParameter != 0) {
276  // ok, a vehicle is wrapping the route,
277  // we may use this vehicle's id as default
278  myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
279  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
280  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
281  }
282  } else {
283  bool ok = true;
284  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok, false);
285  if (!ok) {
286  return;
287  }
288  rid = "'" + myActiveRouteID + "'";
289  }
290  if (myVehicleParameter != 0) { // have to do this here for nested route distributions
291  rid = "for vehicle '" + myVehicleParameter->id + "'";
292  }
293  bool ok = true;
294  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
295  MSEdge::parseEdgesList(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
296  }
297  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
299  WRITE_ERROR("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
300  }
303 }
304 
305 
306 void
309  switch (element) {
310  case SUMO_TAG_VTYPE: {
312  delete myCurrentVType;
313  myCurrentVType = 0;
314  if (!MSNet::getInstance()->getVehicleControl().addVType(vehType)) {
315  const std::string id = vehType->getID();
316  delete vehType;
318  throw ProcessError("Another vehicle type (or distribution) with the id '" + id + "' exists.");
319  }
320  } else {
321  if (myCurrentVTypeDistribution != 0) {
323  }
324  }
325  }
326  break;
327  default:
328  break;
329  }
330 }
331 
332 
333 void
334 MSRouteHandler::closeRoute(const bool /* mayBeDisconnected */) {
335  if (myActiveRoute.size() == 0) {
336  delete myActiveRouteColor;
337  myActiveRouteColor = 0;
340  if (route != 0) {
342  route->addReference();
343  }
344  }
345  myActiveRouteID = "";
346  myActiveRouteRefID = "";
347  return;
348  }
349  if (myVehicleParameter != 0) {
350  throw ProcessError("Vehicle's '" + myVehicleParameter->id + "' route has no edges.");
351  } else {
352  throw ProcessError("Route '" + myActiveRouteID + "' has no edges.");
353  }
354  }
358  myActiveRoute.clear();
359  if (!MSRoute::dictionary(myActiveRouteID, route)) {
360  delete route;
362  if (myVehicleParameter != 0) {
363  if (MSNet::getInstance()->getVehicleControl().getVehicle(myVehicleParameter->id) == 0) {
364  throw ProcessError("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
365  } else {
366  throw ProcessError("A vehicle with id '" + myVehicleParameter->id + "' already exists.");
367  }
368  } else {
369  throw ProcessError("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
370  }
371  }
372  } else {
373  if (myCurrentRouteDistribution != 0) {
375  route->addReference();
376  }
377  }
378  }
379  myActiveRouteID = "";
380  myActiveRouteColor = 0;
381  myActiveRouteStops.clear();
382 }
383 
384 
385 void
387  // check whether the id is really necessary
388  bool ok = true;
389  if (myVehicleParameter != 0) {
390  // ok, a vehicle is wrapping the route,
391  // we may use this vehicle's id as default
392  myCurrentRouteDistributionID = "!" + myVehicleParameter->id; // !!! document this
393  } else {
394  myCurrentRouteDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
395  if (!ok) {
396  return;
397  }
398  }
400  std::vector<SUMOReal> probs;
401  if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
402  bool ok = true;
403  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentRouteDistributionID.c_str(), ok));
404  while (st.hasNext()) {
405  probs.push_back(TplConvert::_2SUMORealSec(st.next().c_str(), 1.0));
406  }
407  }
408  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
409  bool ok = true;
410  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, myCurrentRouteDistributionID.c_str(), ok));
411  size_t probIndex = 0;
412  while (st.hasNext()) {
413  std::string routeID = st.next();
414  const MSRoute* route = MSRoute::dictionary(routeID);
415  if (route == 0) {
416  throw ProcessError("Unknown route '" + routeID + "' in distribution '" + myCurrentRouteDistributionID + "'.");
417  }
418  const SUMOReal prob = (probs.size() > probIndex ? probs[probIndex] : 1.0);
419  if (myCurrentRouteDistribution->add(prob, route, false)) {
420  route->addReference();
421  }
422  probIndex++;
423  }
424  if (probs.size() > 0 && probIndex != probs.size()) {
425  WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
426  " routes in routeDistribution '" + myCurrentRouteDistributionID + "'");
427  }
428  }
429 }
430 
431 
432 void
434  if (myCurrentRouteDistribution != 0) {
435  const bool haveSameID = MSRoute::dictionary(myCurrentRouteDistributionID) != 0;
436  if (MSGlobals::gStateLoaded && haveSameID) {
438  return;
439  }
440  if (haveSameID) {
442  throw ProcessError("Another route (or distribution) with the id '" + myCurrentRouteDistributionID + "' exists.");
443  }
446  throw ProcessError("Route distribution '" + myCurrentRouteDistributionID + "' is empty.");
447  }
450  }
451 }
452 
453 
454 void
456  // get nested route
457  const MSRoute* route = MSRoute::dictionary("!" + myVehicleParameter->id);
460  // let's check whether this vehicle had to depart before the simulation starts
462  if (route != 0) {
463  route->addReference();
464  route->release();
465  }
466  return;
467  }
468  }
469  // get the vehicle's type
470  MSVehicleType* vtype = 0;
471  if (myVehicleParameter->vtypeid != "") {
472  vtype = vehControl.getVType(myVehicleParameter->vtypeid);
473  if (vtype == 0) {
474  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
475  }
476  } else {
477  // there should be one (at least the default one)
478  vtype = vehControl.getVType();
479  }
480  if (route == 0) {
481  // if there is no nested route, try via the (hopefully) given route-id
483  }
484  if (route == 0) {
485  // nothing found? -> error
486  if (myVehicleParameter->routeid != "") {
487  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
488  } else {
489  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
490  }
491  }
492  myActiveRouteID = "";
493 
494  // try to build the vehicle
495  SUMOVehicle* vehicle = 0;
496  if (vehControl.getVehicle(myVehicleParameter->id) == 0) {
497  vehicle = vehControl.buildVehicle(myVehicleParameter, route, vtype);
498  // maybe we do not want this vehicle to be inserted due to scaling
499  if (vehControl.isInQuota()) {
500  // add the vehicle to the vehicle control
501  vehControl.addVehicle(myVehicleParameter->id, vehicle);
503  vehControl.addWaiting(*route->begin(), vehicle);
504  vehControl.registerOneWaitingForPerson();
505  }
507  myVehicleParameter = 0;
508  } else {
509  vehControl.deleteVehicle(vehicle, true);
510  myVehicleParameter = 0;
511  vehicle = 0;
512  }
513  } else {
514  // strange: another vehicle with the same id already exists
516  // and was not loaded while loading a simulation state
517  // -> error
518  throw ProcessError("Another vehicle with the id '" + myVehicleParameter->id + "' exists.");
519  } else {
520  // ok, it seems to be loaded previously while loading a simulation state
521  vehicle = 0;
522  }
523  }
524  // check whether the vehicle shall be added directly to the network or
525  // shall stay in the internal buffer
526  if (vehicle != 0) {
527  if (vehicle->getParameter().departProcedure == DEPART_GIVEN) {
529  }
530  }
531 }
532 
533 
534 void
536  if (myActivePlan->size() == 0) {
537  throw ProcessError("Person '" + myVehicleParameter->id + "' has no plan.");
538  }
540  if (type == 0) {
541  throw ProcessError("The type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
542  }
544  // @todo: consider myScale?
545  if ((myAddVehiclesDirectly || checkLastDepart()) && MSNet::getInstance()->getPersonControl().add(myVehicleParameter->id, person)) {
548  } else {
549  delete person;
550  }
551  myVehicleParameter = 0;
552  myActivePlan = 0;
553 }
554 
555 
556 void
559  return;
560  }
561  // let's check whether vehicles had to depart before the simulation starts
563  const SUMOTime offsetToBegin = string2time(OptionsCont::getOptions().getString("begin")) - myVehicleParameter->depart;
567  return;
568  }
569  }
570  if (MSNet::getInstance()->getVehicleControl().getVType(myVehicleParameter->vtypeid) == 0) {
571  throw ProcessError("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
572  }
573  if (MSRoute::dictionary("!" + myVehicleParameter->id) == 0) {
574  // if not, try via the (hopefully) given route-id
576  if (myVehicleParameter->routeid != "") {
577  throw ProcessError("The route '" + myVehicleParameter->routeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
578  } else {
579  throw ProcessError("Vehicle '" + myVehicleParameter->id + "' has no route.");
580  }
581  }
582  } else {
584  }
585  myActiveRouteID = "";
586 
587  // check whether the vehicle shall be added directly to the network or
588  // shall stay in the internal buffer
592  }
593  myVehicleParameter = 0;
594 }
595 
596 
597 void
599  std::string errorSuffix;
600  if (myActiveRouteID != "") {
601  errorSuffix = " in route '" + myActiveRouteID + "'.";
602  } else if (myActivePlan) {
603  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
604  } else {
605  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
606  }
608  bool ok = parseStop(stop, attrs, errorSuffix, MsgHandler::getErrorInstance());
609  if (!ok) {
610  return;
611  }
612  // try to parse the assigned bus stop
613  if (stop.busstop != "") {
614  // ok, we have obviously a bus stop
616  if (bs != 0) {
617  const MSLane& l = bs->getLane();
618  stop.lane = l.getID();
619  stop.endPos = bs->getEndLanePosition();
620  stop.startPos = bs->getBeginLanePosition();
621  } else {
622  WRITE_ERROR("The bus stop '" + stop.busstop + "' is not known" + errorSuffix);
623  return;
624  }
625  } else {
626  // no, the lane and the position should be given
627  // get the lane
628  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, 0, ok, "");
629  if (ok && stop.lane != "") {
630  if (MSLane::dictionary(stop.lane) == 0) {
631  WRITE_ERROR("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
632  return;
633  }
634  } else {
635  WRITE_ERROR("A stop must be placed on a bus stop or a lane" + errorSuffix);
636  return;
637  }
638  if (myActivePlan &&
639  !myActivePlan->empty() &&
640  &myActivePlan->back()->getDestination() != &MSLane::dictionary(stop.lane)->getEdge()) {
641  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + MSLane::dictionary(stop.lane)->getEdge().getID() + "!=" + myActivePlan->back()->getDestination().getID() + ").");
642  }
643  if (myActivePlan && myActivePlan->empty()) {
645  MSLane::dictionary(stop.lane)->getEdge(), -1, myVehicleParameter->depart, myVehicleParameter->departPos, "start"));
646  }
647  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, 0, ok, MSLane::dictionary(stop.lane)->getLength());
648  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
649  WRITE_WARNING("Deprecated attribute 'pos' in description of stop" + errorSuffix);
650  stop.endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_POSITION, 0, ok, stop.endPos);
651  }
652  stop.startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, 0, ok, MAX2(0., stop.endPos - 2 * POSITION_EPS));
653  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
654  if (!ok || !checkStopPos(stop.startPos, stop.endPos, MSLane::dictionary(stop.lane)->getLength(), POSITION_EPS, friendlyPos)) {
655  WRITE_ERROR("Invalid start or end position for stop on lane '" + stop.lane + "'" + errorSuffix);
656  return;
657  }
658  }
659  if (myActiveRouteID != "") {
660  myActiveRouteStops.push_back(stop);
661  } else if (myActivePlan) {
662  std::string actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, 0, ok, "waiting");
664  MSLane::dictionary(stop.lane)->getEdge(), stop.duration, stop.until, stop.startPos, actType));
665  } else {
666  myVehicleParameter->stops.push_back(stop);
667  }
668 }
669 
670 
671 /****************************************************************************/
The departure is person triggered.
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
MSRouteHandler(const std::string &file, bool addVehiclesDirectly)
standard constructor
void addWaiting(const MSEdge *const edge, SUMOVehicle *vehicle)
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
virtual MSPerson * buildPerson(const SUMOVehicleParameter *pars, const MSVehicleType *vtype, MSPerson::MSPersonPlan *plan) const
Builds a new person.
virtual void myEndElement(int element)
Called when a closing tag occurs.
virtual void deleteVehicle(SUMOVehicle *v, bool discard=false)
Deletes the vehicle.
RandomDistributor< const MSRoute * > * myCurrentRouteDistribution
The currently parsed distribution of routes (probability->route)
const std::vector< SUMOReal > & getProbs() const
Returns the probabilities assigned to the members of the distribution.
The time is given.
std::string next()
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
MSPerson::MSPersonPlan * myActivePlan
The plan of the current person.
std::string vtypeid
The vehicle's type id.
void closeVehicle()
Ends the processing of a vehicle.
static void parseVTypeEmbedded(SUMOVTypeParameter &into, int element, const SUMOSAXAttributes &attrs, bool fromVType=false)
Parses an element embedded in vtype definition.
bool myAddVehiclesDirectly
Information whether vehicles shall be directly added to the network or kept within the buffer...
SUMOTime duration
The stopping duration.
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, or flow.
bool add(SUMOReal prob, T val, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
MSVehicleType * getVType(const std::string &id=DEFAULT_VTYPE_ID)
Returns the named vehicle type or a sample from the named distribution.
static bool checkStopPos(SUMOReal &startPos, SUMOReal &endPos, const SUMOReal laneLength, const SUMOReal minLength, const bool friendlyPos)
check start and end position of a stop
static bool gStateLoaded
Information whether a state has been loaded.
Definition: MSGlobals.h:85
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
void closePerson()
Ends the processing of a person.
int repetitionsDone
The number of times the vehicle was already inserted.
void openRoute(const SUMOSAXAttributes &attrs)
static SUMOReal _2SUMORealSec(const E *const data, SUMOReal def)
Definition: TplConvert.h:336
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:154
T MAX2(T a, T b)
Definition: StdDefs.h:71
const SUMOReal DEFAULT_VEH_PROB
SUMOReal myActiveRouteProbability
The id of the current route.
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn't already in the dictionary...
Definition: MSEdge.cpp:465
SUMOTime until
The time at which the vehicle may continue its journey.
virtual bool addVehicle(const std::string &id, SUMOVehicle *v)
Tries to insert the vehicle into the internal vehicle container.
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
std::string myActiveRouteID
The id of the current route.
SUMOReal getEndLanePosition() const
Returns the end position of this bus stop.
Definition: MSBusStop.cpp:71
SUMOReal repetitionOffset
The time offset between vehicle reinsertions.
MSEdgeVector myActiveRoute
The current route.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
static MSVehicleType * build(SUMOVTypeParameter &from)
Builds the microsim vehicle type described by the given parameter.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
SUMOReal getBeginLanePosition() const
Returns the begin position of this bus stop.
Definition: MSBusStop.cpp:65
The car-following model and parameter.
Definition: MSVehicleType.h:74
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:67
const MSLane & getLane() const
Returns the lane this bus stop is located at.
Definition: MSBusStop.cpp:59
std::vector< Stop > stops
List of the stops the vehicle will make.
SUMOTime getOptSUMOTimeReporting(int attr, const char *objectid, bool &ok, SUMOTime defaultValue, bool report=true) const
Tries to read given attribute assuming it is a SUMOTime.
virtual SUMOVehicle * buildVehicle(SUMOVehicleParameter *defs, const MSRoute *route, const MSVehicleType *type)
Builds a vehicle, increases the number of built vehicles.
std::string busstop
(Optional) bus stop if one is assigned to the stop
const SUMOReal DEFAULT_PERSON_SPEED
const std::string & getID() const
Returns the id.
Definition: Named.h:60
A road/street connecting two junctions.
Definition: MSEdge.h:73
static void parseEdgesList(const std::string &desc, std::vector< const MSEdge * > &into, const std::string &rid)
Parses the given string assuming it contains a list of edge ids divided by spaces.
Definition: MSEdge.cpp:528
RandomDistributor< MSVehicleType * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability->vehicle type)
SUMOReal startPos
The stopping position start.
the edges of a route
void closeRouteDistribution()
std::string routeid
The vehicle's route id.
Representation of a vehicle.
Definition: SUMOVehicle.h:63
Encapsulated SAX-Attributes.
bool wasSet(int what) const
Returns whether the given parameter was set.
SUMOReal endPos
The stopping position end.
A lane area vehicles can halt at.
Definition: MSBusStop.h:63
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:263
void closeVehicleTypeDistribution()
unsigned int getNoFollowing() const
Returns the number of edges that may be reached from this edge.
Definition: MSEdge.h:248
SUMOTime depart
The vehicle's departure time.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:48
#define POSITION_EPS
Definition: config.h:186
std::string fromTaz
The vehicle's origin zone (district)
MSBusStop * getBusStop(const std::string &id) const
Returns the named bus stop.
Definition: MSNet.cpp:693
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:52
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:99
void registerOneWaitingForPerson()
increases the count of vehicles waiting for a person to allow recogniztion of person related deadlock...
std::string lane
The lane to stop at.
Parser for routes during their loading.
std::string myCurrentRouteDistributionID
The id of the currently parsed route distribution.
void openRouteDistribution(const SUMOSAXAttributes &attrs)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
virtual void myEndElement(int element)
Called when a closing tag occurs.
SUMOReal getOverallProb() const
Return the sum of the probabilites assigned to the members.
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:829
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
virtual MSPersonControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:611
MSInsertionControl & getInsertionControl()
Returns the insertion control.
Definition: MSNet.h:294
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
std::string myCurrentVTypeDistributionID
The id of the currently parsed vehicle type distribution.
Definition of vehicle stop (position and duration)
bool parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs, std::string errorSuffix, MsgHandler *const errorOutput)
parses attributes common to all stops
SUMOReal getDefaultProbability() const
Get the default probability of this vehicle type.
const std::string & getID() const
Returns the name of the vehicle type.
void setDeparture(SUMOTime time, MSPerson *person)
sets the arrival time for a waiting or walking person
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const std::vector< MSEdge * > &prohibited=std::vector< MSEdge * >()) const
Definition: MSNet.cpp:712
SUMOReal departPos
(optional) The position the vehicle shall depart from
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
const MSEdge * getFollower(unsigned int n) const
Returns the n-th of the following edges.
Definition: MSEdge.h:257
const int VEHPARS_TAZ_SET
bool isInQuota(SUMOReal frac=-1) const
Returns the information whether the currently vehicle number shall be emitted considering that only f...
const RGBColor * myActiveRouteColor
The currently parsed route's color.
#define SUMOReal
Definition: config.h:215
virtual void compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
virtual ~MSRouteHandler()
standard destructor
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
The class responsible for building and deletion of vehicles.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:105
void add(SUMOVehicle *veh)
Adds a single vehicle for departure.
bool checkLastDepart()
Checks whether the route file is sorted by departure time if needed.
std::string myActiveRouteRefID
The id of the route the current route references to.
Representation of a lane in the micro simulation.
Definition: MSLane.h:77
std::vector< MSPersonStage * > MSPersonPlan
the structure holding the plan of a person
Definition: MSPerson.h:475
A color information.
void closeRoute(const bool mayBeDisconnected=false)
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
void closeFlow()
Ends the processing of a flow.
std::string id
The vehicle's id.
static bool dictionary(const std::string &id, const MSRoute *route)
Adds a route to the dictionary.
Definition: MSRoute.cpp:115