SUMO - Simulation of Urban MObility
RORouteHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
20 // Parser and container for routes during their loading
21 /****************************************************************************/
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 <map>
35 #include <vector>
36 #include <iostream>
46 #include <utils/xml/XMLSubSys.h>
48 #include "ROPerson.h"
49 #include "RONet.h"
50 #include "ROEdge.h"
51 #include "ROLane.h"
52 #include "RORouteDef.h"
53 #include "RORouteHandler.h"
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
59 RORouteHandler::RORouteHandler(RONet& net, const std::string& file,
60  const bool tryRepair,
61  const bool emptyDestinationsAllowed,
62  const bool ignoreErrors) :
63  SUMORouteHandler(file),
64  myNet(net),
65  myActivePerson(0),
66  myActiveContainerPlan(0),
67  myActiveContainerPlanSize(0),
68  myTryRepair(tryRepair),
69  myEmptyDestinationsAllowed(emptyDestinationsAllowed),
70  myErrorOutput(ignoreErrors ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
71  myBegin(string2time(OptionsCont::getOptions().getString("begin"))),
72  myKeepVTypeDist(OptionsCont::getOptions().getBool("keep-vtype-distributions")),
73  myCurrentVTypeDistribution(0),
74  myCurrentAlternatives(0) {
75  myActiveRoute.reserve(100);
76 }
77 
78 
80 }
81 
82 
83 void
84 RORouteHandler::parseFromViaTo(std::string element,
85  const SUMOSAXAttributes& attrs) {
86  myActiveRoute.clear();
87  bool useTaz = OptionsCont::getOptions().getBool("with-taz");
89  WRITE_WARNING("Taz usage was requested but no taz present in " + element + " '" + myVehicleParameter->id + "'!");
90  useTaz = false;
91  }
92  bool ok = true;
94  const ROEdge* fromTaz = myNet.getEdge(myVehicleParameter->fromTaz + "-source");
95  if (fromTaz == 0) {
96  myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
97  } else if (fromTaz->getNumSuccessors() == 0) {
98  myErrorOutput->inform("Source taz '" + myVehicleParameter->fromTaz + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
99  } else {
100  myActiveRoute.push_back(fromTaz);
101  }
102  } else {
103  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok, "", true),
104  myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
105  }
106  if (!attrs.hasAttribute(SUMO_ATTR_VIA)) {
107  myInsertStopEdgesAt = (int)myActiveRoute.size();
108  }
109  ConstROEdgeVector viaEdges;
110  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true),
111  viaEdges, "for " + element + " '" + myVehicleParameter->id + "'");
112  for (ConstROEdgeVector::const_iterator i = viaEdges.begin(); i != viaEdges.end(); ++i) {
113  myActiveRoute.push_back(*i);
114  myVehicleParameter->via.push_back((*i)->getID());
115  }
116 
118  const ROEdge* toTaz = myNet.getEdge(myVehicleParameter->toTaz + "-sink");
119  if (toTaz == 0) {
120  myErrorOutput->inform("Sink taz '" + myVehicleParameter->toTaz + "' not known for " + element + " '" + myVehicleParameter->id + "'!");
121  } else if (toTaz->getNumPredecessors() == 0) {
122  myErrorOutput->inform("Sink taz '" + myVehicleParameter->toTaz + "' has no incoming edges for " + element + " '" + myVehicleParameter->id + "'!");
123  } else {
124  myActiveRoute.push_back(toTaz);
125  }
126  } else {
127  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "", true),
128  myActiveRoute, "for " + element + " '" + myVehicleParameter->id + "'");
129  }
131  if (myVehicleParameter->routeid == "") {
133  }
134 }
135 
136 
137 void
139  const SUMOSAXAttributes& attrs) {
140  SUMORouteHandler::myStartElement(element, attrs);
141  switch (element) {
142  case SUMO_TAG_PERSON: {
144  if (type == 0) {
145  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
147  }
149  break;
150  }
151  case SUMO_TAG_RIDE: {
152  std::vector<ROPerson::PlanItem*>& plan = myActivePerson->getPlan();
153  const std::string pid = myVehicleParameter->id;
154  bool ok = true;
155  ROEdge* from = 0;
156  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
157  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
158  from = myNet.getEdge(fromID);
159  if (from == 0) {
160  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
161  }
162  if (!plan.empty() && plan.back()->getDestination() != from) {
163  throw ProcessError("Disconnected plan for person '" + myVehicleParameter->id + "' (" + fromID + "!=" + plan.back()->getDestination()->getID() + ").");
164  }
165  } else if (plan.empty()) {
166  throw ProcessError("The start edge for person '" + pid + "' is not known.");
167  }
168  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, pid.c_str(), ok);
169  ROEdge* to = myNet.getEdge(toID);
170  if (to == 0) {
171  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
172  }
173  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
174  const std::string busStop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, pid.c_str(), ok, "");
175  myActivePerson->addRide(from, to, desc, busStop);
176  break;
177  }
178  case SUMO_TAG_CONTAINER:
182  (*myActiveContainerPlan) << attrs;
183  break;
184  case SUMO_TAG_TRANSPORT: {
186  (*myActiveContainerPlan) << attrs;
189  break;
190  }
191  case SUMO_TAG_TRANSHIP: {
192  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
193  // copy walk as it is
194  // XXX allow --repair?
196  (*myActiveContainerPlan) << attrs;
199  } else {
200  //routePerson(attrs, *myActiveContainerPlan);
201  }
202  break;
203  }
204  case SUMO_TAG_FLOW:
206  parseFromViaTo("flow", attrs);
207  break;
208  case SUMO_TAG_TRIP: {
210  parseFromViaTo("trip", attrs);
211  }
212  break;
213  default:
214  break;
215  }
216 }
217 
218 
219 void
221  bool ok = true;
222  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
223  if (ok) {
225  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
226  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
227  StringTokenizer st(vTypes);
228  while (st.hasNext()) {
229  const std::string typeID = st.next();
230  SUMOVTypeParameter* const type = myNet.getVehicleTypeSecure(typeID);
231  if (type == 0) {
232  myErrorOutput->inform("Unknown vehicle type '" + typeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
233  } else {
234  myCurrentVTypeDistribution->add(type, 1.);
235  }
236  }
237  }
238  }
239 }
240 
241 
242 void
244  if (myCurrentVTypeDistribution != 0) {
247  myErrorOutput->inform("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
250  myErrorOutput->inform("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
251  }
253  }
254 }
255 
256 
257 void
259  myActiveRoute.clear();
260  myInsertStopEdgesAt = -1;
261  // check whether the id is really necessary
262  std::string rid;
263  if (myCurrentAlternatives != 0) {
265  rid = "distribution '" + myCurrentAlternatives->getID() + "'";
266  } else if (myVehicleParameter != 0) {
267  // ok, a vehicle is wrapping the route,
268  // we may use this vehicle's id as default
269  myVehicleParameter->routeid = myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
270  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
271  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
272  }
273  } else {
274  bool ok = true;
275  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
276  if (!ok) {
277  return;
278  }
279  rid = "'" + myActiveRouteID + "'";
280  }
281  if (myVehicleParameter != 0) { // have to do this here for nested route distributions
282  rid = "for vehicle '" + myVehicleParameter->id + "'";
283  }
284  bool ok = true;
285  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
286  parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid);
287  }
288  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
290  myErrorOutput->inform("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
291  }
292  if (myCurrentAlternatives != 0 && !attrs.hasAttribute(SUMO_ATTR_PROB)) {
293  WRITE_WARNING("No probability for a route in '" + rid + "', using default.");
294  }
296  if (ok && myActiveRouteProbability < 0) {
297  myErrorOutput->inform("Invalid probability for route '" + myActiveRouteID + "'.");
298  }
300  ok = true;
301  myCurrentCosts = attrs.getOpt<double>(SUMO_ATTR_COST, myActiveRouteID.c_str(), ok, -1);
302  if (ok && myCurrentCosts != -1 && myCurrentCosts < 0) {
303  myErrorOutput->inform("Invalid cost for route '" + myActiveRouteID + "'.");
304  }
305 }
306 
307 
308 void
311  switch (element) {
312  case SUMO_TAG_VTYPE:
314  if (myCurrentVTypeDistribution != 0) {
316  }
317  }
318  myCurrentVType = 0;
319  break;
320  case SUMO_TAG_TRIP:
321  closeRoute(true);
322  closeVehicle();
323  delete myVehicleParameter;
324  myVehicleParameter = 0;
325  myInsertStopEdgesAt = -1;
326  break;
327  default:
328  break;
329  }
330 }
331 
332 
333 void
334 RORouteHandler::closeRoute(const bool mayBeDisconnected) {
335  if (myActiveRoute.size() == 0) {
336  if (myActiveRouteRefID != "" && myCurrentAlternatives != 0) {
338  myActiveRouteID = "";
339  myActiveRouteRefID = "";
340  return;
341  }
342  if (myVehicleParameter != 0) {
343  myErrorOutput->inform("The route for vehicle '" + myVehicleParameter->id + "' has no edges.");
344  } else {
345  myErrorOutput->inform("Route '" + myActiveRouteID + "' has no edges.");
346  }
347  myActiveRouteID = "";
348  myActiveRouteStops.clear();
349  return;
350  }
351  if (myActiveRoute.size() == 1 && myActiveRoute.front()->isTazConnector()) {
352  myErrorOutput->inform("The routing information for vehicle '" + myVehicleParameter->id + "' is insufficient.");
353  myActiveRouteID = "";
354  myActiveRouteStops.clear();
355  return;
356  }
359  myActiveRoute.clear();
360  if (myCurrentAlternatives == 0) {
361  if (myNet.getRouteDef(myActiveRouteID) != 0) {
362  delete route;
363  if (myVehicleParameter != 0) {
364  myErrorOutput->inform("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
365  } else {
366  myErrorOutput->inform("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
367  }
368  myActiveRouteID = "";
369  myActiveRouteStops.clear();
370  return;
371  } else {
372  myCurrentAlternatives = new RORouteDef(myActiveRouteID, 0, mayBeDisconnected || myTryRepair, mayBeDisconnected);
376  }
377  } else {
379  }
380  myActiveRouteID = "";
381  myActiveRouteStops.clear();
382 }
383 
384 
385 void
387  // check whether the id is really necessary
388  bool ok = true;
389  std::string id;
390  if (myVehicleParameter != 0) {
391  // ok, a vehicle is wrapping the route,
392  // we may use this vehicle's id as default
393  myVehicleParameter->routeid = id = "!" + myVehicleParameter->id; // !!! document this
394  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
395  WRITE_WARNING("Ids of internal route distributions are ignored (vehicle '" + myVehicleParameter->id + "').");
396  }
397  } else {
398  id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
399  if (!ok) {
400  return;
401  }
402  }
403  // try to get the index of the last element
404  int index = attrs.getOpt<int>(SUMO_ATTR_LAST, id.c_str(), ok, 0);
405  if (ok && index < 0) {
406  myErrorOutput->inform("Negative index of a route alternative (id='" + id + "').");
407  return;
408  }
409  // build the alternative cont
410  myCurrentAlternatives = new RORouteDef(id, index, myTryRepair, false);
411  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
412  ok = true;
413  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, id.c_str(), ok));
414  while (st.hasNext()) {
415  const std::string routeID = st.next();
416  const RORouteDef* route = myNet.getRouteDef(routeID);
417  if (route == 0) {
418  myErrorOutput->inform("Unknown route '" + routeID + "' in distribution '" + id + "'.");
419  } else {
421  }
422  }
423  }
424 }
425 
426 
427 void
429  if (myCurrentAlternatives != 0) {
431  myErrorOutput->inform("Route distribution '" + myCurrentAlternatives->getID() + "' is empty.");
432  delete myCurrentAlternatives;
433  } else if (!myNet.addRouteDef(myCurrentAlternatives)) {
434  myErrorOutput->inform("Another route (or distribution) with the id '" + myCurrentAlternatives->getID() + "' exists.");
435  delete myCurrentAlternatives;
436  }
438  }
439 }
440 
441 
442 void
444  // get the vehicle id
446  return;
447  }
448  // get vehicle type
450  if (type == 0) {
451  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
453  } else {
454  if (!myKeepVTypeDist) {
455  // fix the type id in case we used a distribution
456  myVehicleParameter->vtypeid = type->id;
457  }
458  }
459  if (type->vehicleClass == SVC_PEDESTRIAN) {
460  WRITE_WARNING("Vehicle type '" + type->id + "' with vClass=pedestrian should only be used for persons and not for vehicle '" + myVehicleParameter->id + "'.");
461  }
462  // get the route
464  if (route == 0) {
465  myErrorOutput->inform("The route of the vehicle '" + myVehicleParameter->id + "' is not known.");
466  return;
467  }
468  if (route->getID()[0] != '!') {
469  route = route->copy("!" + myVehicleParameter->id, myVehicleParameter->depart);
470  }
471  // build the vehicle
472  if (!MsgHandler::getErrorInstance()->wasInformed()) {
473  ROVehicle* veh = new ROVehicle(*myVehicleParameter, route, type, &myNet, myErrorOutput);
474  if (myNet.addVehicle(myVehicleParameter->id, veh)) {
476  }
477  }
478 }
479 
480 
481 void
483  if (myActivePerson->getPlan().empty()) {
484  WRITE_WARNING("Discarding person '" + myVehicleParameter->id + "' because it's plan is empty");
485  } else {
488  }
489  }
490  delete myVehicleParameter;
491  myVehicleParameter = 0;
492  myActivePerson = 0;
493 }
494 
495 
496 void
499  if (myActiveContainerPlanSize > 0) {
502  } else {
503  WRITE_WARNING("Discarding container '" + myVehicleParameter->id + "' because it's plan is empty");
504  }
505  delete myVehicleParameter;
506  myVehicleParameter = 0;
507  delete myActiveContainerPlan;
510 }
511 
512 
513 void
515  // @todo: consider myScale?
517  delete myVehicleParameter;
518  myVehicleParameter = 0;
519  return;
520  }
521  // let's check whether vehicles had to depart before the simulation starts
523  const SUMOTime offsetToBegin = myBegin - myVehicleParameter->depart;
527  delete myVehicleParameter;
528  myVehicleParameter = 0;
529  return;
530  }
531  }
533  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
534  }
536  closeRoute(true);
537  }
539  myErrorOutput->inform("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
540  delete myVehicleParameter;
541  myVehicleParameter = 0;
542  return;
543  }
544  myActiveRouteID = "";
545  if (!MsgHandler::getErrorInstance()->wasInformed()) {
546  if (myNet.addFlow(myVehicleParameter, OptionsCont::getOptions().getBool("randomize-flows"))) {
548  } else {
549  myErrorOutput->inform("Another flow with the id '" + myVehicleParameter->id + "' exists.");
550  }
551  } else {
552  delete myVehicleParameter;
553  }
554  myVehicleParameter = 0;
555  myInsertStopEdgesAt = -1;
556 }
557 
558 
559 void
561  if (myActiveContainerPlan != 0) {
563  (*myActiveContainerPlan) << attrs;
566  return;
567  }
568  std::string errorSuffix;
569  if (myVehicleParameter != 0) {
570  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
571  } else {
572  errorSuffix = " in route '" + myActiveRouteID + "'.";
573  }
575  bool ok = parseStop(stop, attrs, errorSuffix, myErrorOutput);
576  if (!ok) {
577  return;
578  }
579  // try to parse the assigned bus stop
580  ROEdge* edge = 0;
581  if (stop.busstop != "") {
583  if (busstop == 0) {
584  myErrorOutput->inform("Unknown bus stop '" + stop.busstop + "'" + errorSuffix);
585  return;
586  }
587  stop.lane = busstop->lane;
588  stop.endPos = busstop->endPos;
589  stop.startPos = busstop->startPos;
590  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
591  } // try to parse the assigned container stop
592  else if (stop.containerstop != "") {
594  if (containerstop == 0) {
595  myErrorOutput->inform("Unknown container stop '" + stop.containerstop + "'" + errorSuffix);
596  return;
597  }
598  stop.lane = containerstop->lane;
599  stop.endPos = containerstop->endPos;
600  stop.startPos = containerstop->startPos;
601  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
602  } // try to parse the assigned parking area
603  else if (stop.parkingarea != "") {
605  if (parkingarea == 0) {
606  myErrorOutput->inform("Unknown parking area '" + stop.parkingarea + "'" + errorSuffix);
607  return;
608  }
609  stop.lane = parkingarea->lane;
610  stop.endPos = parkingarea->endPos;
611  stop.startPos = parkingarea->startPos;
612  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
613  } else {
614  // no, the lane and the position should be given
615  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, 0, ok, "");
616  if (!ok || stop.lane == "") {
617  myErrorOutput->inform("A stop must be placed on a bus stop, a container stop, a parking area or a lane" + errorSuffix);
618  return;
619  }
620  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
621  if (edge == 0) {
622  myErrorOutput->inform("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
623  return;
624  }
625  stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, 0, ok, edge->getLength());
626  stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, 0, ok, stop.endPos - 2 * POSITION_EPS);
627  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, 0, ok, false);
628  const double endPosOffset = edge->isInternal() ? edge->getNormalBefore()->getLength() : 0;
629  if (!ok || !checkStopPos(stop.startPos, stop.endPos, edge->getLength() + endPosOffset, POSITION_EPS, friendlyPos)) {
630  myErrorOutput->inform("Invalid start or end position for stop" + errorSuffix);
631  return;
632  }
633  }
634  if (myActivePerson != 0) {
635  myActivePerson->addStop(stop, edge);
636  } else if (myVehicleParameter != 0) {
637  myVehicleParameter->stops.push_back(stop);
638  } else {
639  myActiveRouteStops.push_back(stop);
640  }
641  if (myInsertStopEdgesAt >= 0) {
642  myActiveRoute.insert(myActiveRoute.begin() + myInsertStopEdgesAt, edge);
644  }
645 }
646 
647 
648 void
649 RORouteHandler::parseEdges(const std::string& desc, ConstROEdgeVector& into,
650  const std::string& rid) {
651  if (desc[0] == BinaryFormatter::BF_ROUTE) {
652  std::istringstream in(desc, std::ios::binary);
653  char c;
654  in >> c;
655  FileHelpers::readEdgeVector(in, into, rid);
656  } else {
657  for (StringTokenizer st(desc); st.hasNext();) {
658  const std::string id = st.next();
659  const ROEdge* edge = myNet.getEdge(id);
660  if (edge == 0) {
661  myErrorOutput->inform("The edge '" + id + "' within the route " + rid + " is not known.");
662  } else {
663  into.push_back(edge);
664  }
665  }
666  }
667 }
668 
669 
670 void
672  bool ok = true;
673  const char* const id = myVehicleParameter->id.c_str();
674  assert(!attrs.hasAttribute(SUMO_ATTR_EDGES));
675  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, id, ok);
676  const std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, id, ok);
677  const std::string busStop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, id, ok, "");
678 
679  const ROEdge* from = myNet.getEdge(fromID);
680  if (from == 0) {
681  myErrorOutput->inform("The edge '" + fromID + "' within a walk of " + myVehicleParameter->id + " is not known."
682  + "\n The route can not be build.");
683  ok = false;
684  }
685  const ROEdge* to = myNet.getEdge(toID);
686  if (to == 0) {
687  myErrorOutput->inform("The edge '" + toID + "' within a walk of " + myVehicleParameter->id + " is not known."
688  + "\n The route can not be build.");
689  ok = false;
690  }
691 
692  double departPos = 0.;
693  double arrivalPos = 0.;
694  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
695  WRITE_WARNING("The attribute departPos is no longer supported for walks, please use the person attribute, the arrivalPos of the previous step or explicit stops.");
696  }
697  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
699  attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, id, ok));
700  }
701 
702  const std::string modes = attrs.getOpt<std::string>(SUMO_ATTR_MODES, id, ok, "");
703  SVCPermissions modeSet = 0;
704  for (StringTokenizer st(modes); st.hasNext();) {
705  const std::string mode = st.next();
706  if (mode == "car") {
707  modeSet |= SVC_PASSENGER;
708  } else if (mode == "bicycle") {
709  modeSet |= SVC_BICYCLE;
710  } else if (mode == "public") {
711  modeSet |= SVC_BUS;
712  } else {
713  throw InvalidArgument("Unknown person mode '" + mode + "'.");
714  }
715  }
716  const std::string types = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id, ok, "");
717  double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, id, ok, OptionsCont::getOptions().getFloat("persontrip.walkfactor"));
718  if (ok) {
719  myActivePerson->addTrip(from, to, modeSet, types, departPos, arrivalPos, busStop, walkFactor);
720  }
721 }
722 
723 
724 void
726  // XXX allow --repair?
727  bool ok = true;
728  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
729  const std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, myVehicleParameter->id.c_str(), ok);
730  RORouteDef* routeDef = myNet.getRouteDef(routeID);
731  const RORoute* route = routeDef != 0 ? routeDef->getFirstRoute() : 0;
732  if (route == 0) {
733  throw ProcessError("The route '" + routeID + "' for walk of person '" + myVehicleParameter->id + "' is not known.");
734  }
735  myActiveRoute = route->getEdgeVector();
736  } else {
737  myActiveRoute.clear();
738  parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myVehicleParameter->id.c_str(), ok), myActiveRoute, " walk for person '" + myVehicleParameter->id + "'");
739  }
740  const char* const objId = myVehicleParameter->id.c_str();
741  const double duration = attrs.getOpt<double>(SUMO_ATTR_DURATION, objId, ok, -1);
742  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
743  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
744  }
745  const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, objId, ok, -1.);
746  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && speed <= 0) {
747  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
748  }
749  double departPos = 0.;
750  double arrivalPos = 0.;
751  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
752  WRITE_WARNING("The attribute departPos is no longer supported for walks, please use the person attribute, the arrivalPos of the previous step or explicit stops.");
753  }
754  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
755  arrivalPos = SUMOVehicleParserHelper::parseWalkPos(SUMO_ATTR_ARRIVALPOS, objId, myActiveRoute.back()->getLength(),
756  attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, objId, ok));
757  }
758  const std::string busStop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, objId, ok, "");
759  if (ok) {
760  myActivePerson->addWalk(myActiveRoute, duration, speed, departPos, arrivalPos, busStop);
761  }
762 }
763 
764 
765 /****************************************************************************/
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
Definition: RORouteDef.cpp:411
const int VEHPARS_TO_TAZ_SET
RORouteDef * myCurrentAlternatives
The currently parsed route alternatives.
void addRide(const ROEdge *const from, const ROEdge *const to, const std::string &lines, const std::string &destStop)
Definition: ROPerson.cpp:93
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:75
virtual void myEndElement(int element)
Called when a closing tag occurs.
description of a vehicle type
void closeVehicleTypeDistribution()
The time is given.
is a pedestrian
std::string next()
std::string containerstop
(Optional) container stop if one is assigned to the stop
int repetitionNumber
The number of times the vehicle shall be repeatedly inserted.
void closePerson()
Ends the processing of a person.
std::string vtypeid
The vehicle&#39;s type id.
int getNumSuccessors() const
Returns the number of edges this edge is connected to.
Definition: ROEdge.cpp:234
void openRouteDistribution(const SUMOSAXAttributes &attrs)
a flow definition (used by router)
Represents a generic random distribution.
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, container or flow.
static void readEdgeVector(std::istream &in, std::vector< const E *> &edges, const std::string &rid)
Reads an edge vector binary.
Definition: FileHelpers.h:273
Structure representing possible vehicle parameter.
ConstROEdgeVector myActiveRoute
The current route.
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
Definition: RORouteDef.cpp:81
double defaultProbability
The probability when being added to a distribution without an explicit probability.
vehicle is a bicycle
std::string getString() const
Returns the current content as a string.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
void addWalk(const SUMOSAXAttributes &attrs)
add a fully specified walk
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
int repetitionsDone
The number of times the vehicle was already inserted.
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
SUMOVehicleClass vehicleClass
The vehicle&#39;s class.
double myActiveRouteProbability
The probability of the current route.
MsgHandler *const myErrorOutput
Depending on the "ignore-errors" option different outputs are used.
virtual void myEndElement(int element)
Called when a closing tag occurs.
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:204
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
const double DEFAULT_VEH_PROB
int myActiveContainerPlanSize
The number of stages in myActiveContainerPlan.
std::vector< const ROEdge * > ConstROEdgeVector
Definition: ROEdge.h:62
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
const std::string & getID() const
Returns the id.
Definition: Named.h:65
std::string myActiveRouteID
The id of the current route.
int myInsertStopEdgesAt
where stop edges can be inserted into the current route (-1 means no insertion)
const std::string DEFAULT_VTYPE_ID
const SUMOTime myBegin
The begin time.
double getOverallProb() const
Returns the sum of the probablities of the contained routes.
Definition: RORouteDef.cpp:425
void closeVehicle()
Ends the processing of a vehicle.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition: RONet.h:301
static double parseWalkPos(SumoXMLAttr attr, const std::string &id, double maxPos, const std::string &val, std::mt19937 *rng=0)
parse departPos or arrivalPos for a walk
std::string parkingarea
(Optional) parking area if one is assigned to the stop
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:199
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition: RONet.cpp:329
RandomDistributor< SUMOVTypeParameter * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability->vehicle type)
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition: RONet.cpp:352
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
std::string toTaz
The vehicle&#39;s destination zone (district)
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
RORouteHandler(RONet &net, const std::string &file, const bool tryRepair, const bool emptyDestinationsAllowed, const bool ignoreErrors)
standard constructor
RONet & myNet
The current route.
int getNumPredecessors() const
Returns the number of edges connected to this edge.
Definition: ROEdge.cpp:243
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter *> *vehTypeDistribution)
Adds a vehicle type distribution.
Definition: RONet.cpp:342
std::string busstop
(Optional) bus stop if one is assigned to the stop
A vehicle as used by router.
Definition: ROVehicle.h:59
bool addRouteDef(RORouteDef *def)
Definition: RONet.cpp:208
ROPerson * myActivePerson
The plan of the current person.
the edges of a route
std::string routeid
The vehicle&#39;s route id.
double startPos
The stopping position start.
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
const SUMOVehicleParameter::Stop * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Retrieves a stopping place from the network.
Definition: RONet.h:218
std::vector< PlanItem * > & getPlan()
Definition: ROPerson.h:326
void addContainer(const SUMOTime depart, const std::string desc)
Definition: RONet.cpp:398
void parseEdges(const std::string &desc, ConstROEdgeVector &into, const std::string &rid)
Parse edges from strings.
void addStop(const SUMOVehicleParameter::Stop &stopPar, const ROEdge *const stopEdge)
Definition: ROPerson.cpp:111
SUMOTime depart
The vehicle&#39;s departure time.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
SUMOTime string2time(const std::string &r)
Definition: SUMOTime.cpp:46
A person as used by router.
Definition: ROPerson.h:57
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
#define POSITION_EPS
Definition: config.h:175
std::string fromTaz
The vehicle&#39;s origin zone (district)
double endPos
The stopping position end.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
vehicle is a passenger car (a "normal" car)
A basic edge for routing applications.
Definition: ROEdge.h:77
const int VEHPARS_FROM_TAZ_SET
void addTrip(const ROEdge *const from, const ROEdge *const to, const SVCPermissions modeSet, const std::string &vTypes, const double departPos, const double arrivalPos, const std::string &busStop, double walkFactor)
Definition: ROPerson.cpp:66
std::string lane
The lane to stop at.
Parser for routes during their loading.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
bool isInternal() const
return whether this edge is an internal edge
Definition: ROEdge.h:149
void closeContainer()
Ends the processing of a container.
vehicle is a bus
stop for vehicles
static bool checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
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 router&#39;s network representation.
Definition: RONet.h:74
void openRoute(const SUMOSAXAttributes &attrs)
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
const std::string DEFAULT_PEDTYPE_ID
void addWalk(const ConstROEdgeVector &edges, const double duration, const double speed, const double departPos, const double arrivalPos, const std::string &busStop)
Definition: ROPerson.cpp:102
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
const bool myKeepVTypeDist
whether to keep the the vtype distribution in output
const bool myTryRepair
Information whether routes shall be repaired.
const ConstROEdgeVector & getEdgeVector() const
Returns the list of edges this route consists of.
Definition: RORoute.h:161
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:84
A storage for options typed value containers)
Definition: OptionsCont.h:98
OutputDevice_String * myActiveContainerPlan
The plan of the current container.
Base class for a vehicle&#39;s route definition.
Definition: RORouteDef.h:62
std::string id
The vehicle type&#39;s id.
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
void addLoadedAlternative(RORoute *alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA...
Definition: RORouteDef.cpp:75
void closeRoute(const bool mayBeDisconnected=false)
bool wasSet(int what) const
Returns whether the given parameter was set.
const RGBColor * myActiveRouteColor
The currently parsed route&#39;s color.
double myCurrentCosts
The currently parsed route costs.
virtual ~RORouteHandler()
standard destructor
void addPersonTrip(const SUMOSAXAttributes &attrs)
add a routing request for a walking or intermodal person
bool closeTag()
Closes the most recently opened tag.
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition: RONet.cpp:277
long long int SUMOTime
Definition: TraCIDefs.h:51
a single trip definition (used by router)
void closeFlow()
Ends the processing of a flow.
const ROEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself ...
Definition: ROEdge.cpp:252
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:163
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition: RONet.cpp:372
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
std::string myActiveRouteRefID
The id of the route the current route references to.
A color information.
bool addPerson(ROPerson *person)
Definition: RONet.cpp:386
void parseFromViaTo(std::string element, const SUMOSAXAttributes &attrs)
Called for parsing from and to and the corresponding taz attributes.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
A complete router&#39;s route.
Definition: RORoute.h:61
An output device that encapsulates an ofstream.
void closeRouteDistribution()
std::string myCurrentVTypeDistributionID
The id of the currently parsed vehicle type distribution.
std::string id
The vehicle&#39;s id.