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