Eclipse 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-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
21 // Parser and container for routes during their loading
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <string>
26 #include <map>
27 #include <vector>
28 #include <iostream>
40 #include <utils/xml/XMLSubSys.h>
42 #include "RONet.h"
43 #include "ROEdge.h"
44 #include "ROLane.h"
45 #include "RORouteDef.h"
46 #include "RORouteHandler.h"
47 
48 #define JUNCTION_TAZ_MISSING_HELP "\nSet option '--junction-taz' or load a TAZ-file"
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 RORouteHandler::RORouteHandler(RONet& net, const std::string& file,
54  const bool tryRepair,
55  const bool emptyDestinationsAllowed,
56  const bool ignoreErrors,
57  const bool checkSchema) :
58  SUMORouteHandler(file, checkSchema ? "routes" : "", true),
59  myNet(net),
60  myActiveRouteRepeat(0),
61  myActiveRoutePeriod(0),
62  myActivePerson(nullptr),
63  myActiveContainerPlan(nullptr),
64  myActiveContainerPlanSize(0),
65  myTryRepair(tryRepair),
66  myEmptyDestinationsAllowed(emptyDestinationsAllowed),
67  myErrorOutput(ignoreErrors ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
68  myBegin(string2time(OptionsCont::getOptions().getString("begin"))),
69  myKeepVTypeDist(OptionsCont::getOptions().getBool("keep-vtype-distributions")),
70  myMapMatchingDistance(OptionsCont::getOptions().getFloat("mapmatch.distance")),
71  myMapMatchJunctions(OptionsCont::getOptions().getBool("mapmatch.junctions")),
72  myCurrentVTypeDistribution(nullptr),
73  myCurrentAlternatives(nullptr),
74  myLaneTree(nullptr) {
75  myActiveRoute.reserve(100);
76 }
77 
78 
80 }
81 
82 
83 void
85  const std::string element = toString(tag);
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  // from-attributes
93  const std::string rid = "for " + element + " '" + myVehicleParameter->id + "'";
94  if ((useTaz || !attrs.hasAttribute(SUMO_ATTR_FROM)) &&
96  const bool useJunction = attrs.hasAttribute(SUMO_ATTR_FROMJUNCTION);
97  const std::string tazType = useJunction ? "junction" : "taz";
98  const std::string tazID = attrs.get<std::string>(useJunction ? SUMO_ATTR_FROMJUNCTION : SUMO_ATTR_FROM_TAZ, myVehicleParameter->id.c_str(), ok, true);
99  const ROEdge* fromTaz = myNet.getEdge(tazID + "-source");
100  if (fromTaz == nullptr) {
101  myErrorOutput->inform("Source " + tazType + " '" + tazID + "' not known for " + element + " '" + myVehicleParameter->id + "'!"
102  + (useJunction ? JUNCTION_TAZ_MISSING_HELP : ""));
103  ok = false;
104  } else if (fromTaz->getNumSuccessors() == 0 && tag != SUMO_TAG_PERSON) {
105  myErrorOutput->inform("Source " + tazType + " '" + tazID + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
106  ok = false;
107  } else {
108  myActiveRoute.push_back(fromTaz);
109  }
110  } else if (attrs.hasAttribute(SUMO_ATTR_FROMXY)) {
111  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_FROMXY, myVehicleParameter->id.c_str(), ok, true), false, myActiveRoute, rid, true, ok);
112  } else if (attrs.hasAttribute(SUMO_ATTR_FROMLONLAT)) {
113  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_FROMLONLAT, myVehicleParameter->id.c_str(), ok, true), true, myActiveRoute, rid, true, ok);
114  } else {
115  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok, "", true), myActiveRoute, rid, ok);
116  }
118  myInsertStopEdgesAt = (int)myActiveRoute.size();
119  }
120 
121  // via-attributes
122  ConstROEdgeVector viaEdges;
123  if (attrs.hasAttribute(SUMO_ATTR_VIAXY)) {
124  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_VIAXY, myVehicleParameter->id.c_str(), ok, true), false, viaEdges, rid, false, ok);
125  } else if (attrs.hasAttribute(SUMO_ATTR_VIALONLAT)) {
126  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_VIALONLAT, myVehicleParameter->id.c_str(), ok, true), true, viaEdges, rid, false, ok);
127  } else if (attrs.hasAttribute(SUMO_ATTR_VIAJUNCTIONS)) {
128  for (std::string junctionID : attrs.getStringVector(SUMO_ATTR_VIAJUNCTIONS)) {
129  const ROEdge* viaSink = myNet.getEdge(junctionID + "-sink");
130  if (viaSink == nullptr) {
131  myErrorOutput->inform("Junction-taz '" + junctionID + "' not found." + JUNCTION_TAZ_MISSING_HELP);
132  ok = false;
133  } else {
134  viaEdges.push_back(viaSink);
135  }
136  }
137  } else {
138  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true), viaEdges, rid, ok);
139  }
140  for (const ROEdge* e : viaEdges) {
141  myActiveRoute.push_back(e);
142  myVehicleParameter->via.push_back(e->getID());
143  }
144 
145  // to-attributes
146  if ((useTaz || !attrs.hasAttribute(SUMO_ATTR_TO)) &&
148  const bool useJunction = attrs.hasAttribute(SUMO_ATTR_TOJUNCTION);
149  const std::string tazType = useJunction ? "junction" : "taz";
150  const std::string tazID = attrs.get<std::string>(useJunction ? SUMO_ATTR_TOJUNCTION : SUMO_ATTR_TO_TAZ, myVehicleParameter->id.c_str(), ok, true);
151  const ROEdge* toTaz = myNet.getEdge(tazID + "-sink");
152  if (toTaz == nullptr) {
153  myErrorOutput->inform("Sink " + tazType + " '" + tazID + "' not known for " + element + " '" + myVehicleParameter->id + "'!"
154  + (useJunction ? JUNCTION_TAZ_MISSING_HELP : ""));
155  ok = false;
156  } else if (toTaz->getNumPredecessors() == 0 && tag != SUMO_TAG_PERSON) {
157  myErrorOutput->inform("Sink " + tazType + " '" + tazID + "' has no incoming edges for " + element + " '" + myVehicleParameter->id + "'!");
158  ok = false;
159  } else {
160  myActiveRoute.push_back(toTaz);
161  }
162  } else if (attrs.hasAttribute(SUMO_ATTR_TOXY)) {
163  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_TOXY, myVehicleParameter->id.c_str(), ok, true), false, myActiveRoute, rid, false, ok);
164  } else if (attrs.hasAttribute(SUMO_ATTR_TOLONLAT)) {
165  parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_TOLONLAT, myVehicleParameter->id.c_str(), ok, true), true, myActiveRoute, rid, false, ok);
166  } else {
167  parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "", true), myActiveRoute, rid, ok);
168  }
170  if (myVehicleParameter->routeid == "") {
172  }
173 }
174 
175 
176 void
178  const SUMOSAXAttributes& attrs) {
179  SUMORouteHandler::myStartElement(element, attrs);
180  bool ok = true;
181  switch (element) {
182  case SUMO_TAG_PERSON:
183  case SUMO_TAG_PERSONFLOW: {
185  if (type == nullptr) {
186  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
188  }
190  break;
191  }
192  case SUMO_TAG_RIDE: {
193  std::vector<ROPerson::PlanItem*>& plan = myActivePerson->getPlan();
194  const std::string pid = myVehicleParameter->id;
195  ROEdge* from = nullptr;
196  if (attrs.hasAttribute(SUMO_ATTR_FROM)) {
197  const std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, pid.c_str(), ok);
198  from = myNet.getEdge(fromID);
199  if (from == nullptr) {
200  throw ProcessError("The from edge '" + fromID + "' within a ride of person '" + pid + "' is not known.");
201  }
202  } else if (plan.empty()) {
203  throw ProcessError("The start edge for person '" + pid + "' is not known.");
204  }
205  ROEdge* to = nullptr;
206  const SUMOVehicleParameter::Stop* stop = nullptr;
207  const std::string toID = attrs.getOpt<std::string>(SUMO_ATTR_TO, pid.c_str(), ok, "");
208  const std::string busStopID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, pid.c_str(), ok, "");
209  if (toID != "") {
210  to = myNet.getEdge(toID);
211  if (to == nullptr) {
212  throw ProcessError("The to edge '" + toID + "' within a ride of person '" + pid + "' is not known.");
213  }
214  } else if (busStopID != "") {
215  stop = myNet.getStoppingPlace(busStopID, SUMO_TAG_BUS_STOP);
216  if (stop == nullptr) {
217  throw ProcessError("Unknown bus stop '" + busStopID + "' within a ride of '" + myVehicleParameter->id + "'.");
218  }
220  } else {
221  throw ProcessError("The to edge '' within a ride of '" + myVehicleParameter->id + "' is not known.");
222  }
223  double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok,
224  stop == nullptr ? std::numeric_limits<double>::infinity() : stop->endPos);
225  const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
226  const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, pid.c_str(), ok, "");
227  myActivePerson->addRide(from, to, desc, arrivalPos, busStopID, group);
228  break;
229  }
230  case SUMO_TAG_CONTAINER:
234  (*myActiveContainerPlan) << attrs;
235  break;
236  case SUMO_TAG_TRANSPORT: {
238  (*myActiveContainerPlan) << attrs;
241  break;
242  }
243  case SUMO_TAG_TRANSHIP: {
244  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
245  // copy walk as it is
246  // XXX allow --repair?
248  (*myActiveContainerPlan) << attrs;
251  } else {
252  //routePerson(attrs, *myActiveContainerPlan);
253  }
254  break;
255  }
256  case SUMO_TAG_FLOW:
258  parseFromViaTo((SumoXMLTag)element, attrs, ok);
259  break;
260  case SUMO_TAG_TRIP:
262  parseFromViaTo((SumoXMLTag)element, attrs, ok);
263  break;
264  default:
265  break;
266  }
267 }
268 
269 
270 void
272  bool ok = true;
273  myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
274  if (ok) {
276  if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
277  const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
278  StringTokenizer st(vTypes);
279  while (st.hasNext()) {
280  const std::string typeID = st.next();
281  SUMOVTypeParameter* const type = myNet.getVehicleTypeSecure(typeID);
282  if (type == nullptr) {
283  myErrorOutput->inform("Unknown vehicle type '" + typeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
284  } else {
285  myCurrentVTypeDistribution->add(type, 1.);
286  }
287  }
288  }
289  }
290 }
291 
292 
293 void
295  if (myCurrentVTypeDistribution != nullptr) {
298  myErrorOutput->inform("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
301  myErrorOutput->inform("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
302  }
303  myCurrentVTypeDistribution = nullptr;
304  }
305 }
306 
307 
308 void
310  myActiveRoute.clear();
311  myInsertStopEdgesAt = -1;
312  // check whether the id is really necessary
313  std::string rid;
314  if (myCurrentAlternatives != nullptr) {
316  rid = "distribution '" + myCurrentAlternatives->getID() + "'";
317  } else if (myVehicleParameter != nullptr) {
318  // ok, a vehicle is wrapping the route,
319  // we may use this vehicle's id as default
320  myVehicleParameter->routeid = myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
321  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
322  WRITE_WARNING("Ids of internal routes are ignored (vehicle '" + myVehicleParameter->id + "').");
323  }
324  } else {
325  bool ok = true;
326  myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
327  if (!ok) {
328  return;
329  }
330  rid = "'" + myActiveRouteID + "'";
331  }
332  if (myVehicleParameter != nullptr) { // have to do this here for nested route distributions
333  rid = "for vehicle '" + myVehicleParameter->id + "'";
334  }
335  bool ok = true;
336  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
337  parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid, ok);
338  }
339  myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
340  if (myActiveRouteRefID != "" && myNet.getRouteDef(myActiveRouteRefID) == nullptr) {
341  myErrorOutput->inform("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
342  }
343  if (myCurrentAlternatives != nullptr && !attrs.hasAttribute(SUMO_ATTR_PROB)) {
344  WRITE_WARNINGF("No probability for route %, using default.", rid);
345  }
347  if (ok && myActiveRouteProbability < 0) {
348  myErrorOutput->inform("Invalid probability for route '" + myActiveRouteID + "'.");
349  }
351  ok = true;
352  myActiveRouteRepeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, myActiveRouteID.c_str(), ok, 0);
354  if (myActiveRouteRepeat > 0) {
356  if (myVehicleParameter != nullptr) {
358  if (type != nullptr) {
359  vClass = type->vehicleClass;
360  }
361  }
362  if (myActiveRoute.size() > 0 && !myActiveRoute.back()->isConnectedTo(*myActiveRoute.front(), vClass)) {
363  myErrorOutput->inform("Disconnected route " + rid + " when repeating.");
364  }
365  }
366  myCurrentCosts = attrs.getOpt<double>(SUMO_ATTR_COST, myActiveRouteID.c_str(), ok, -1);
367  if (ok && myCurrentCosts != -1 && myCurrentCosts < 0) {
368  myErrorOutput->inform("Invalid cost for route '" + myActiveRouteID + "'.");
369  }
370 }
371 
372 
373 void
375  // currently unused
376 }
377 
378 
379 void
381  // currently unused
382 }
383 
384 
385 void
387  // currently unused
388 }
389 
390 
391 void
392 RORouteHandler::closeRoute(const bool mayBeDisconnected) {
393  const bool mustReroute = myActiveRoute.size() == 0 && myActiveRouteStops.size() != 0;
394  if (mustReroute) {
395  // implicit route from stops
396  for (const SUMOVehicleParameter::Stop& stop : myActiveRouteStops) {
397  ROEdge* edge = myNet.getEdge(stop.edge);
398  myActiveRoute.push_back(edge);
399  }
400  }
401  if (myActiveRoute.size() == 0) {
402  if (myActiveRouteRefID != "" && myCurrentAlternatives != nullptr) {
404  myActiveRouteID = "";
405  myActiveRouteRefID = "";
406  return;
407  }
408  if (myVehicleParameter != nullptr) {
409  myErrorOutput->inform("The route for vehicle '" + myVehicleParameter->id + "' has no edges.");
410  } else {
411  myErrorOutput->inform("Route '" + myActiveRouteID + "' has no edges.");
412  }
413  myActiveRouteID = "";
414  myActiveRouteStops.clear();
415  return;
416  }
417  if (myActiveRoute.size() == 1 && myActiveRoute.front()->isTazConnector()) {
418  myErrorOutput->inform("The routing information for vehicle '" + myVehicleParameter->id + "' is insufficient.");
419  myActiveRouteID = "";
420  myActiveRouteStops.clear();
421  return;
422  }
423  if (!mayBeDisconnected && OptionsCont::getOptions().exists("no-internal-links") && !OptionsCont::getOptions().getBool("no-internal-links")) {
424  // fix internal edges which did not get parsed
425  const ROEdge* last = nullptr;
426  ConstROEdgeVector fullRoute;
427  for (const ROEdge* roe : myActiveRoute) {
428  if (last != nullptr) {
429  for (const ROEdge* intern : last->getSuccessors()) {
430  if (intern->isInternal() && intern->getSuccessors().size() == 1 && intern->getSuccessors().front() == roe) {
431  fullRoute.push_back(intern);
432  }
433  }
434  }
435  fullRoute.push_back(roe);
436  last = roe;
437  }
438  myActiveRoute = fullRoute;
439  }
440  if (myActiveRouteRepeat > 0) {
441  // duplicate route
442  ConstROEdgeVector tmpEdges = myActiveRoute;
443  auto tmpStops = myActiveRouteStops;
444  for (int i = 0; i < myActiveRouteRepeat; i++) {
445  myActiveRoute.insert(myActiveRoute.begin(), tmpEdges.begin(), tmpEdges.end());
446  for (SUMOVehicleParameter::Stop stop : tmpStops) {
447  if (stop.until > 0) {
448  if (myActiveRoutePeriod <= 0) {
449  const std::string description = myVehicleParameter != nullptr
450  ? "for vehicle '" + myVehicleParameter->id + "'"
451  : "'" + myActiveRouteID + "'";
452  throw ProcessError("Cannot repeat stops with 'until' in route " + description + " because no cycleTime is defined.");
453  }
454  stop.until += myActiveRoutePeriod * (i + 1);
455  stop.arrival += myActiveRoutePeriod * (i + 1);
456  }
457  myActiveRouteStops.push_back(stop);
458  }
459  }
460  }
463  myActiveRoute.clear();
464  if (myCurrentAlternatives == nullptr) {
465  if (myNet.getRouteDef(myActiveRouteID) != nullptr) {
466  delete route;
467  if (myVehicleParameter != nullptr) {
468  myErrorOutput->inform("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
469  } else {
470  myErrorOutput->inform("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
471  }
472  myActiveRouteID = "";
473  myActiveRouteStops.clear();
474  return;
475  } else {
476  myCurrentAlternatives = new RORouteDef(myActiveRouteID, 0, mayBeDisconnected || myTryRepair, mayBeDisconnected);
479  myCurrentAlternatives = nullptr;
480  }
481  } else {
483  }
484  myActiveRouteID = "";
485  myActiveRouteStops.clear();
486 }
487 
488 
489 void
491  // check whether the id is really necessary
492  bool ok = true;
493  std::string id;
494  if (myVehicleParameter != nullptr) {
495  // ok, a vehicle is wrapping the route,
496  // we may use this vehicle's id as default
497  myVehicleParameter->routeid = id = "!" + myVehicleParameter->id; // !!! document this
498  if (attrs.hasAttribute(SUMO_ATTR_ID)) {
499  WRITE_WARNING("Ids of internal route distributions are ignored (vehicle '" + myVehicleParameter->id + "').");
500  }
501  } else {
502  id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
503  if (!ok) {
504  return;
505  }
506  }
507  // try to get the index of the last element
508  int index = attrs.getOpt<int>(SUMO_ATTR_LAST, id.c_str(), ok, 0);
509  if (ok && index < 0) {
510  myErrorOutput->inform("Negative index of a route alternative (id='" + id + "').");
511  return;
512  }
513  // build the alternative cont
514  myCurrentAlternatives = new RORouteDef(id, index, myTryRepair, false);
515  if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
516  ok = true;
517  StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, id.c_str(), ok));
518  while (st.hasNext()) {
519  const std::string routeID = st.next();
520  const RORouteDef* route = myNet.getRouteDef(routeID);
521  if (route == nullptr) {
522  myErrorOutput->inform("Unknown route '" + routeID + "' in distribution '" + id + "'.");
523  } else {
525  }
526  }
527  }
528 }
529 
530 
531 void
533  if (myCurrentAlternatives != nullptr) {
535  myErrorOutput->inform("Route distribution '" + myCurrentAlternatives->getID() + "' is empty.");
536  delete myCurrentAlternatives;
537  } else if (!myNet.addRouteDef(myCurrentAlternatives)) {
538  myErrorOutput->inform("Another route (or distribution) with the id '" + myCurrentAlternatives->getID() + "' exists.");
539  delete myCurrentAlternatives;
540  }
541  myCurrentAlternatives = nullptr;
542  }
543 }
544 
545 
546 void
548  // get the vehicle id
550  return;
551  }
552  // get vehicle type
554  if (type == nullptr) {
555  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
557  } else {
558  if (!myKeepVTypeDist) {
559  // fix the type id in case we used a distribution
560  myVehicleParameter->vtypeid = type->id;
561  }
562  }
563  if (type->vehicleClass == SVC_PEDESTRIAN) {
564  WRITE_WARNING("Vehicle type '" + type->id + "' with vClass=pedestrian should only be used for persons and not for vehicle '" + myVehicleParameter->id + "'.");
565  }
566  // get the route
568  if (route == nullptr) {
569  myErrorOutput->inform("The route of the vehicle '" + myVehicleParameter->id + "' is not known.");
570  return;
571  }
572  if (route->getID()[0] != '!') {
573  route = route->copy("!" + myVehicleParameter->id, myVehicleParameter->depart);
574  }
575  // build the vehicle
576  if (!MsgHandler::getErrorInstance()->wasInformed()) {
577  ROVehicle* veh = new ROVehicle(*myVehicleParameter, route, type, &myNet, myErrorOutput);
578  if (myNet.addVehicle(myVehicleParameter->id, veh)) {
580  }
581  }
582 }
583 
584 
585 void
588  if (myCurrentVTypeDistribution != nullptr) {
590  }
591  }
592  if (OptionsCont::getOptions().isSet("restriction-params")) {
593  const std::vector<std::string> paramKeys = OptionsCont::getOptions().getStringVector("restriction-params");
595  }
596  myCurrentVType = nullptr;
597 }
598 
599 
600 void
602  if (myActivePerson->getPlan().empty()) {
603  WRITE_WARNING("Discarding person '" + myVehicleParameter->id + "' because it's plan is empty");
604  } else {
607  }
608  }
609  delete myVehicleParameter;
610  myVehicleParameter = nullptr;
611  myActivePerson = nullptr;
612 }
613 
614 
615 void
617  if (myActivePerson->getPlan().empty()) {
618  WRITE_WARNING("Discarding person '" + myVehicleParameter->id + "' because it's plan is empty");
619  } else {
620  // instantiate all persons of this flow
621  int i = 0;
622  std::string baseID = myVehicleParameter->id;
625  throw ProcessError("probabilistic personFlow '" + myVehicleParameter->id + "' must specify end time");
626  } else {
627  for (SUMOTime t = myVehicleParameter->depart; t < myVehicleParameter->repetitionEnd; t += TIME2STEPS(1)) {
629  addFlowPerson(t, baseID, i++);
630  }
631  }
632  }
633  } else {
635  for (; i < myVehicleParameter->repetitionNumber; i++) {
636  addFlowPerson(depart, baseID, i);
638  }
639  }
640  }
641  delete myVehicleParameter;
642  myVehicleParameter = nullptr;
643  myActivePerson = nullptr;
644 }
645 
646 
647 void
648 RORouteHandler::addFlowPerson(SUMOTime depart, const std::string& baseID, int i) {
650  pars.id = baseID + "." + toString(i);
651  pars.depart = depart;
652  ROPerson* copyPerson = new ROPerson(pars, myActivePerson->getType());
653  for (ROPerson::PlanItem* item : myActivePerson->getPlan()) {
654  copyPerson->getPlan().push_back(item->clone());
655  }
656  if (i == 0) {
657  delete myActivePerson;
658  }
659  myActivePerson = copyPerson;
661  if (i == 0) {
663  }
664  }
665 }
666 
667 void
670  if (myActiveContainerPlanSize > 0) {
673  } else {
674  WRITE_WARNING("Discarding container '" + myVehicleParameter->id + "' because it's plan is empty");
675  }
676  delete myVehicleParameter;
677  myVehicleParameter = nullptr;
678  delete myActiveContainerPlan;
679  myActiveContainerPlan = nullptr;
681 }
682 
683 
684 void
686  // @todo: consider myScale?
688  delete myVehicleParameter;
689  myVehicleParameter = nullptr;
690  return;
691  }
692  // let's check whether vehicles had to depart before the simulation starts
694  const SUMOTime offsetToBegin = myBegin - myVehicleParameter->depart;
698  delete myVehicleParameter;
699  myVehicleParameter = nullptr;
700  return;
701  }
702  }
704  myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
705  }
706  if (myVehicleParameter->routeid[0] == '!' && myNet.getRouteDef(myVehicleParameter->routeid) == nullptr) {
707  closeRoute(true);
708  }
709  if (myNet.getRouteDef(myVehicleParameter->routeid) == nullptr) {
710  myErrorOutput->inform("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
711  delete myVehicleParameter;
712  myVehicleParameter = nullptr;
713  return;
714  }
715  myActiveRouteID = "";
716  if (!MsgHandler::getErrorInstance()->wasInformed()) {
717  if (myNet.addFlow(myVehicleParameter, OptionsCont::getOptions().getBool("randomize-flows"))) {
719  } else {
720  myErrorOutput->inform("Another flow with the id '" + myVehicleParameter->id + "' exists.");
721  }
722  } else {
723  delete myVehicleParameter;
724  }
725  myVehicleParameter = nullptr;
726  myInsertStopEdgesAt = -1;
727 }
728 
729 
730 void
732  closeRoute(true);
733  closeVehicle();
734 }
735 
736 
737 void
739  if (myActiveContainerPlan != nullptr) {
741  (*myActiveContainerPlan) << attrs;
744  return;
745  }
746  std::string errorSuffix;
747  if (myActivePerson != nullptr) {
748  errorSuffix = " in person '" + myVehicleParameter->id + "'.";
749  } else if (myActiveContainerPlan != nullptr) {
750  errorSuffix = " in container '" + myVehicleParameter->id + "'.";
751  } else if (myVehicleParameter != nullptr) {
752  errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
753  } else {
754  errorSuffix = " in route '" + myActiveRouteID + "'.";
755  }
757  bool ok = parseStop(stop, attrs, errorSuffix, myErrorOutput);
758  if (!ok) {
759  return;
760  }
761  // try to parse the assigned bus stop
762  ROEdge* edge = nullptr;
763  if (stop.busstop != "") {
765  if (busstop == nullptr) {
766  myErrorOutput->inform("Unknown bus stop '" + stop.busstop + "'" + errorSuffix);
767  return;
768  }
769  stop.lane = busstop->lane;
770  stop.endPos = busstop->endPos;
771  stop.startPos = busstop->startPos;
772  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
773  } // try to parse the assigned container stop
774  else if (stop.containerstop != "") {
776  if (containerstop == nullptr) {
777  myErrorOutput->inform("Unknown container stop '" + stop.containerstop + "'" + errorSuffix);
778  return;
779  }
780  stop.lane = containerstop->lane;
781  stop.endPos = containerstop->endPos;
782  stop.startPos = containerstop->startPos;
783  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
784  } // try to parse the assigned parking area
785  else if (stop.parkingarea != "") {
787  if (parkingarea == nullptr) {
788  myErrorOutput->inform("Unknown parking area '" + stop.parkingarea + "'" + errorSuffix);
789  return;
790  }
791  stop.lane = parkingarea->lane;
792  stop.endPos = parkingarea->endPos;
793  stop.startPos = parkingarea->startPos;
794  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
795  } else {
796  // no, the lane and the position should be given
797  stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, ok, "");
798  stop.edge = attrs.getOpt<std::string>(SUMO_ATTR_EDGE, nullptr, ok, "");
799  if (ok && stop.edge != "") {
800  edge = myNet.getEdge(stop.edge);
801  if (edge == nullptr) {
802  myErrorOutput->inform("The edge '" + stop.edge + "' for a stop is not known" + errorSuffix);
803  return;
804  }
805  } else if (ok && stop.lane != "") {
806  edge = myNet.getEdge(stop.lane.substr(0, stop.lane.rfind('_')));
807  if (edge == nullptr) {
808  myErrorOutput->inform("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
809  return;
810  }
811  } else if (!ok || (stop.lane == "" && stop.edge == "")) {
812  myErrorOutput->inform("A stop must be placed on a bus stop, a container stop, a parking area, an edge or a lane" + errorSuffix);
813  return;
814  }
815  stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, ok, edge->getLength());
816  stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, ok, stop.endPos - 2 * POSITION_EPS);
817  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
818  const double endPosOffset = edge->isInternal() ? edge->getNormalBefore()->getLength() : 0;
819  if (!ok || (checkStopPos(stop.startPos, stop.endPos, edge->getLength() + endPosOffset, POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
820  myErrorOutput->inform("Invalid start or end position for stop" + errorSuffix);
821  return;
822  }
823  }
824  stop.edge = edge->getID();
825  if (myActivePerson != nullptr) {
826  myActivePerson->addStop(stop, edge);
827  } else if (myVehicleParameter != nullptr) {
828  myVehicleParameter->stops.push_back(stop);
829  } else {
830  myActiveRouteStops.push_back(stop);
831  }
832  if (myInsertStopEdgesAt >= 0) {
833  myActiveRoute.insert(myActiveRoute.begin() + myInsertStopEdgesAt, edge);
835  }
836 }
837 
838 
839 void
841 }
842 
843 
844 void
846 }
847 
848 
849 void
851 }
852 
853 
854 void
856 }
857 
858 
859 void
861 }
862 
863 
864 void
865 RORouteHandler::parseEdges(const std::string& desc, ConstROEdgeVector& into,
866  const std::string& rid, bool& ok) {
867  for (StringTokenizer st(desc); st.hasNext();) {
868  const std::string id = st.next();
869  const ROEdge* edge = myNet.getEdge(id);
870  if (edge == nullptr) {
871  myErrorOutput->inform("The edge '" + id + "' within the route " + rid + " is not known.");
872  ok = false;
873  } else {
874  into.push_back(edge);
875  }
876  }
877 }
878 
879 void
881  ConstROEdgeVector& into, const std::string& rid, bool isFrom, bool& ok) {
882  if (geo && !GeoConvHelper::getFinal().usingGeoProjection()) {
883  WRITE_ERROR("Cannot convert geo-positions because the network has no geo-reference");
884  return;
885  }
888  if (type != nullptr) {
889  vClass = type->vehicleClass;
890  }
891  for (Position pos : positions) {
892  Position orig = pos;
893  if (geo) {
895  }
896  double dist = MIN2(10.0, myMapMatchingDistance);
897  const ROEdge* best = getClosestEdge(pos, dist, vClass);
898  while (best == nullptr && dist < myMapMatchingDistance) {
899  dist = MIN2(dist * 2, myMapMatchingDistance);
900  best = getClosestEdge(pos, dist, vClass);
901  }
902  if (best == nullptr) {
903  myErrorOutput->inform("No edge found near position " + toString(orig, geo ? gPrecisionGeo : gPrecision) + " within the route " + rid + ".");
904  ok = false;
905  } else {
906  if (myMapMatchJunctions) {
907  best = getJunctionTaz(pos, best, vClass, isFrom);
908  if (best != nullptr) {
909  into.push_back(best);
910  }
911  } else {
912  into.push_back(best);
913  }
914  }
915  }
916 }
917 
918 
919 const ROEdge*
920 RORouteHandler::getClosestEdge(const Position& pos, double distance, SUMOVehicleClass vClass) {
921  NamedRTree* t = getLaneTree();
922  Boundary b;
923  b.add(pos);
924  b.grow(distance);
925  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
926  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
927  std::set<const Named*> lanes;
928  Named::StoringVisitor sv(lanes);
929  t->Search(cmin, cmax, sv);
930  // use closest
931  double minDist = std::numeric_limits<double>::max();
932  const ROLane* best = nullptr;
933  for (const Named* o : lanes) {
934  const ROLane* cand = static_cast<const ROLane*>(o);
935  if (!cand->allowsVehicleClass(vClass)) {
936  continue;
937  }
938  double dist = cand->getShape().distance2D(pos);
939  if (dist < minDist) {
940  minDist = dist;
941  best = cand;
942  }
943  }
944  if (best == nullptr) {
945  return nullptr;
946  } else {
947  const ROEdge* bestEdge = &best->getEdge();
948  while (bestEdge->isInternal()) {
949  bestEdge = bestEdge->getSuccessors().front();
950  }
951  return bestEdge;
952  }
953 }
954 
955 
956 const ROEdge*
957 RORouteHandler::getJunctionTaz(const Position& pos, const ROEdge* closestEdge, SUMOVehicleClass vClass, bool isFrom) {
958  if (closestEdge == nullptr) {
959  return nullptr;
960  } else {
961  const RONode* fromJunction = closestEdge->getFromJunction();
962  const RONode* toJunction = closestEdge->getToJunction();
963  const bool fromCloser = (fromJunction->getPosition().distanceSquaredTo2D(pos) <
964  toJunction->getPosition().distanceSquaredTo2D(pos));
965  const ROEdge* fromSource = myNet.getEdge(fromJunction->getID() + "-source");
966  const ROEdge* fromSink = myNet.getEdge(fromJunction->getID() + "-sink");
967  const ROEdge* toSource = myNet.getEdge(toJunction->getID() + "-source");
968  const ROEdge* toSink = myNet.getEdge(toJunction->getID() + "-sink");
969  if (fromSource == nullptr || fromSink == nullptr) {
970  myErrorOutput->inform("Junction-taz '" + fromJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
971  return nullptr;
972  }
973  if (toSource == nullptr || toSink == nullptr) {
974  myErrorOutput->inform("Junction-taz '" + toJunction->getID() + "' not found when mapping position " + toString(pos) + "." + JUNCTION_TAZ_MISSING_HELP);
975  return nullptr;
976  }
977  const bool fromPossible = isFrom ? fromSource->getSuccessors(vClass).size() > 0 : fromSink->getPredecessors().size() > 0;
978  const bool toPossible = isFrom ? toSource->getSuccessors(vClass).size() > 0 : toSink->getPredecessors().size() > 0;
979  //std::cout << "getJunctionTaz pos=" << pos << " isFrom=" << isFrom << " closest=" << closestEdge->getID() << " fromPossible=" << fromPossible << " toPossible=" << toPossible << "\n";
980  if (fromCloser && fromPossible) {
981  // return closest if possible
982  return isFrom ? fromSource : fromSink;
983  } else if (!fromCloser && toPossible) {
984  // return closest if possible
985  return isFrom ? toSource : toSink;
986  } else {
987  // return possible
988  if (fromPossible) {
989  return isFrom ? fromSource : fromSink;
990  } else {
991  return isFrom ? toSource : toSink;
992  }
993  }
994  }
995 }
996 
997 
998 void
999 RORouteHandler::parseWalkPositions(const SUMOSAXAttributes& attrs, const std::string& personID,
1000  const ROEdge* /*fromEdge*/, const ROEdge*& toEdge,
1001  double& departPos, double& arrivalPos, std::string& busStopID,
1002  const ROPerson::PlanItem* const lastStage, bool& ok) {
1003  const std::string description = "walk or personTrip of '" + personID + "'.";
1004  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
1005  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.");
1006  }
1007  departPos = myActivePerson->getParameter().departPos;
1008  if (lastStage != nullptr) {
1009  departPos = lastStage->getDestinationPos();
1010  }
1011 
1012  busStopID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
1013  if (busStopID != "") {
1015  if (bs == nullptr) {
1016  myErrorOutput->inform("Unknown bus stop '" + busStopID + "' for " + description);
1017  ok = false;
1018  } else {
1019  toEdge = myNet.getEdge(bs->lane.substr(0, bs->lane.rfind('_')));
1020  arrivalPos = (bs->startPos + bs->endPos) / 2;
1021  }
1022  }
1023  if (toEdge != nullptr) {
1024  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1026  myHardFail, description, toEdge->getLength(),
1027  attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, description.c_str(), ok));
1028  }
1029  } else {
1030  throw ProcessError("No destination edge for " + description + ".");
1031  }
1032 }
1033 
1034 
1035 void
1037  bool ok = true;
1038  const char* const id = myVehicleParameter->id.c_str();
1039  assert(!attrs.hasAttribute(SUMO_ATTR_EDGES));
1040  const ROEdge* from = nullptr;
1041  const ROEdge* to = nullptr;
1042  parseFromViaTo(SUMO_TAG_PERSON, attrs, ok);
1043  myInsertStopEdgesAt = -1;
1045  if (ok) {
1046  from = myActiveRoute.front();
1047  }
1048  } else if (myActivePerson->getPlan().empty()) {
1049  throw ProcessError("Start edge not defined for person '" + myVehicleParameter->id + "'.");
1050  } else {
1051  from = myActivePerson->getPlan().back()->getDestination();
1052  }
1054  to = myActiveRoute.back();
1055  } // else, to may also be derived from stopping place
1056 
1057  const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, id, ok, -1);
1058  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1059  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
1060  }
1061 
1062  double departPos = 0;
1063  double arrivalPos = std::numeric_limits<double>::infinity();
1064  std::string busStopID;
1065  const ROPerson::PlanItem* const lastStage = myActivePerson->getPlan().empty() ? nullptr : myActivePerson->getPlan().back();
1066  parseWalkPositions(attrs, myVehicleParameter->id, from, to, departPos, arrivalPos, busStopID, lastStage, ok);
1067 
1068  const std::string modes = attrs.getOpt<std::string>(SUMO_ATTR_MODES, id, ok, "");
1069  const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, id, ok, "");
1070  SVCPermissions modeSet = 0;
1071  for (StringTokenizer st(modes); st.hasNext();) {
1072  const std::string mode = st.next();
1073  if (mode == "car") {
1074  modeSet |= SVC_PASSENGER;
1075  } else if (mode == "taxi") {
1076  modeSet |= SVC_TAXI;
1077  } else if (mode == "bicycle") {
1078  modeSet |= SVC_BICYCLE;
1079  } else if (mode == "public") {
1080  modeSet |= SVC_BUS;
1081  } else {
1082  throw InvalidArgument("Unknown person mode '" + mode + "'.");
1083  }
1084  }
1085  const std::string types = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id, ok, "");
1086  double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, id, ok, OptionsCont::getOptions().getFloat("persontrip.walkfactor"));
1087  if (ok) {
1088  myActivePerson->addTrip(from, to, modeSet, types, departPos, arrivalPos, busStopID, walkFactor, group);
1089  }
1090 }
1091 
1092 
1093 void
1095  // parse walks from->to as person trips
1097  // XXX allow --repair?
1098  bool ok = true;
1099  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
1100  const std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, myVehicleParameter->id.c_str(), ok);
1101  RORouteDef* routeDef = myNet.getRouteDef(routeID);
1102  const RORoute* route = routeDef != nullptr ? routeDef->getFirstRoute() : nullptr;
1103  if (route == nullptr) {
1104  throw ProcessError("The route '" + routeID + "' for walk of person '" + myVehicleParameter->id + "' is not known.");
1105  }
1106  myActiveRoute = route->getEdgeVector();
1107  } else {
1108  myActiveRoute.clear();
1109  parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myVehicleParameter->id.c_str(), ok), myActiveRoute, " walk for person '" + myVehicleParameter->id + "'", ok);
1110  }
1111  const char* const objId = myVehicleParameter->id.c_str();
1112  const double duration = attrs.getOpt<double>(SUMO_ATTR_DURATION, objId, ok, -1);
1113  if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1114  throw ProcessError("Non-positive walking duration for '" + myVehicleParameter->id + "'.");
1115  }
1116  const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, objId, ok, -1.);
1117  if (attrs.hasAttribute(SUMO_ATTR_SPEED) && speed <= 0) {
1118  throw ProcessError("Non-positive walking speed for '" + myVehicleParameter->id + "'.");
1119  }
1120  double departPos = 0.;
1121  double arrivalPos = std::numeric_limits<double>::infinity();
1122  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
1123  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.");
1124  }
1125  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
1126  arrivalPos = SUMOVehicleParserHelper::parseWalkPos(SUMO_ATTR_ARRIVALPOS, myHardFail, objId, myActiveRoute.back()->getLength(), attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, objId, ok));
1127  }
1128  const std::string busStop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, objId, ok, "");
1129  if (ok) {
1130  myActivePerson->addWalk(myActiveRoute, duration, speed, departPos, arrivalPos, busStop);
1131  }
1132  } else {
1133  addPersonTrip(attrs);
1134  }
1135 }
1136 
1137 
1138 NamedRTree*
1140  if (myLaneTree == nullptr) {
1141  myLaneTree = new NamedRTree();
1142  for (const auto& edgeItem : myNet.getEdgeMap()) {
1143  for (ROLane* lane : edgeItem.second->getLanes()) {
1144  Boundary b = lane->getShape().getBoxBoundary();
1145  const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
1146  const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
1147  myLaneTree->Insert(cmin, cmax, lane);
1148  }
1149  }
1150  }
1151  return myLaneTree;
1152 }
1153 
1154 
1155 /****************************************************************************/
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:277
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:276
std::vector< const ROEdge * > ConstROEdgeVector
Definition: ROEdge.h:54
#define JUNCTION_TAZ_MISSING_HELP
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition: SUMOTime.cpp:45
#define SUMOTime_MAX
Definition: SUMOTime.h:32
#define TIME2STEPS(x)
Definition: SUMOTime.h:55
long long int SUMOTime
Definition: SUMOTime.h:31
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SVC_PASSENGER
vehicle is a passenger car (a "normal" car)
@ SVC_BICYCLE
vehicle is a bicycle
@ SVC_TAXI
vehicle is a taxi
@ SVC_BUS
vehicle is a bus
@ SVC_PEDESTRIAN
pedestrian
const double DEFAULT_VEH_PROB
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const int VEHPARS_TO_TAZ_SET
const int VEHPARS_FROM_TAZ_SET
@ DEPART_GIVEN
The time is given.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_TRANSHIP
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_STOP
stop for vehicles
@ SUMO_TAG_FLOW
a flow definitio nusing a from-to edges instead of a route (used by router)
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_TRANSPORT
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_RIDE
@ SUMO_TAG_PERSON
@ SUMO_TAG_PERSONFLOW
@ SUMO_TAG_TRIP
a single trip definition (used by router)
@ SUMO_ATTR_STARTPOS
@ SUMO_ATTR_LINES
@ SUMO_ATTR_LAST
@ SUMO_ATTR_LANE
@ SUMO_ATTR_REFID
@ SUMO_ATTR_VIALONLAT
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VIA
@ SUMO_ATTR_VIAXY
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_FROMJUNCTION
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_TOLONLAT
@ SUMO_ATTR_ROUTES
@ SUMO_ATTR_MODES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_DEPARTPOS
@ SUMO_ATTR_GROUP
@ SUMO_ATTR_COST
@ SUMO_ATTR_TO_TAZ
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_FROM_TAZ
@ SUMO_ATTR_VIAJUNCTIONS
@ SUMO_ATTR_FROMXY
@ SUMO_ATTR_PROB
@ SUMO_ATTR_FRIENDLY_POS
@ SUMO_ATTR_WALKFACTOR
@ SUMO_ATTR_TOXY
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_DURATION
@ SUMO_ATTR_FROMLONLAT
@ SUMO_ATTR_REPEAT
@ SUMO_ATTR_CYCLETIME
@ SUMO_ATTR_TOJUNCTION
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:25
int gPrecisionGeo
Definition: StdDefs.cpp:26
T MIN2(T a, T b)
Definition: StdDefs.h:73
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:77
double ymin() const
Returns minimum y-coordinate.
Definition: Boundary.cpp:129
double xmin() const
Returns minimum x-coordinate.
Definition: Boundary.cpp:117
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:299
double ymax() const
Returns maximum y-coordinate.
Definition: Boundary.cpp:135
double xmax() const
Returns maximum x-coordinate.
Definition: Boundary.cpp:123
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
bool x2cartesian_const(Position &from) const
Converts the given coordinate into a cartesian using the previous initialisation.
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:117
Allows to store the object; used as context while traveling the rtree in TraCI.
Definition: Named.h:89
Base class for objects which have an id.
Definition: Named.h:53
const std::string & getID() const
Returns the id.
Definition: Named.h:73
A RT-tree for efficient storing of SUMO's Named objects.
Definition: NamedRTree.h:60
void Insert(const float a_min[2], const float a_max[2], Named *const &a_data)
Insert entry.
Definition: NamedRTree.h:78
int Search(const float a_min[2], const float a_max[2], const Named::StoringVisitor &c) const
Find all within search rectangle.
Definition: NamedRTree.h:111
A storage for options typed value containers)
Definition: OptionsCont.h:89
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
An output device that encapsulates an ofstream.
std::string getString() const
Returns the current content as a string.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
double distanceSquaredTo2D(const Position &p2) const
returns the square of the distance to another position (Only using x and y positions)
Definition: Position.h:246
A list of positions.
double distance2D(const Position &p, bool perpendicular=false) const
closest 2D-distance to point p (or -1 if perpendicular is true and the point is beyond this vector)
A basic edge for routing applications.
Definition: ROEdge.h:70
const ROEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: ROEdge.cpp:265
bool isInternal() const
return whether this edge is an internal edge
Definition: ROEdge.h:145
const RONode * getFromJunction() const
Definition: ROEdge.h:504
const ROEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: ROEdge.cpp:361
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:210
const ROEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of incoming edges.
Definition: ROEdge.h:361
const RONode * getToJunction() const
Definition: ROEdge.h:508
A single lane the router may use.
Definition: ROLane.h:48
ROEdge & getEdge() const
Returns the lane's edge.
Definition: ROLane.h:92
const PositionVector & getShape() const
Definition: ROLane.h:114
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: ROLane.h:110
The router's network representation.
Definition: RONet.h:62
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition: RONet.cpp:334
const SUMOVehicleParameter::Stop * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Retrieves a stopping place from the network.
Definition: RONet.h:212
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
bool addRouteDef(RORouteDef *def)
Definition: RONet.cpp:264
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition: RONet.cpp:412
void addContainer(const SUMOTime depart, const std::string desc)
Definition: RONet.cpp:464
bool addPerson(ROPerson *person)
Definition: RONet.cpp:452
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition: RONet.cpp:389
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition: RONet.h:298
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter * > *vehTypeDistribution)
Adds a vehicle type distribution.
Definition: RONet.cpp:402
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition: RONet.cpp:438
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition: RONet.h:399
Base class for nodes used by the router.
Definition: RONode.h:43
const Position & getPosition() const
Returns the position of the node.
Definition: RONode.h:64
Every person has a plan comprising of multiple planItems.
Definition: ROPerson.h:79
virtual double getDestinationPos() const =0
A person as used by router.
Definition: ROPerson.h:49
void addRide(const ROEdge *const from, const ROEdge *const to, const std::string &lines, double arrivalPos, const std::string &destStop, const std::string &group)
Definition: ROPerson.cpp:112
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, const std::string &group)
Definition: ROPerson.cpp:60
std::vector< PlanItem * > & getPlan()
Definition: ROPerson.h:392
void addWalk(const ConstROEdgeVector &edges, const double duration, const double speed, const double departPos, const double arrivalPos, const std::string &busStop)
Definition: ROPerson.cpp:122
void addStop(const SUMOVehicleParameter::Stop &stopPar, const ROEdge *const stopEdge)
Definition: ROPerson.cpp:131
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Definition: RORoutable.h:71
const SUMOVTypeParameter * getType() const
Returns the type of the routable.
Definition: RORoutable.h:82
Base class for a vehicle's route definition.
Definition: RORouteDef.h:53
void addLoadedAlternative(RORoute *alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA.
Definition: RORouteDef.cpp:69
double getOverallProb() const
Returns the sum of the probablities of the contained routes.
Definition: RORouteDef.cpp:406
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
Definition: RORouteDef.cpp:75
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
Definition: RORouteDef.cpp:392
void closeTrip()
Ends the processing of a trip.
void closeRouteDistribution()
closes (ends) the building of a distribution
NamedRTree * myLaneTree
RTree for finding lanes.
void addStop(const SUMOSAXAttributes &attrs)
Processing of a stop.
const double myMapMatchingDistance
maximum distance when map-matching
std::string myCurrentVTypeDistributionID
The id of the currently parsed vehicle type distribution.
virtual ~RORouteHandler()
standard destructor
RORouteHandler(RONet &net, const std::string &file, const bool tryRepair, const bool emptyDestinationsAllowed, const bool ignoreErrors, const bool checkSchema)
standard constructor
void addTranship(const SUMOSAXAttributes &attrs)
Processing of a tranship.
void parseEdges(const std::string &desc, ConstROEdgeVector &into, const std::string &rid, bool &ok)
Parse edges from strings.
void closeVType()
Ends the processing of a vehicle type.
void addRide(const SUMOSAXAttributes &attrs)
Processing of a ride.
void addWalk(const SUMOSAXAttributes &attrs)
add a fully specified walk
RONet & myNet
The current route.
void addFlowPerson(SUMOTime depart, const std::string &baseID, int i)
Processing of a person from a personFlow.
NamedRTree * getLaneTree()
initialize lane-RTree
ConstROEdgeVector myActiveRoute
The current route.
const ROEdge * getJunctionTaz(const Position &pos, const ROEdge *closestEdge, SUMOVehicleClass vClass, bool isFrom)
find closest junction taz given the closest edge
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
const bool myTryRepair
Information whether routes shall be repaired.
OutputDevice_String * myActiveContainerPlan
The plan of the current container.
SUMOTime myActiveRoutePeriod
const SUMOTime myBegin
The begin time.
RandomDistributor< SUMOVTypeParameter * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability->vehicle type)
void closePersonFlow()
Ends the processing of a personFlow.
void closePerson()
Ends the processing of a person.
void openRouteDistribution(const SUMOSAXAttributes &attrs)
opens a route distribution for reading
int myActiveContainerPlanSize
The number of stages in myActiveContainerPlan.
const bool myKeepVTypeDist
whether to keep the the vtype distribution in output
void openRouteFlow(const SUMOSAXAttributes &attrs)
opens a route flow for reading
void openTrip(const SUMOSAXAttributes &attrs)
opens a trip for reading
void closeVehicle()
Ends the processing of a vehicle.
void addContainer(const SUMOSAXAttributes &attrs)
Processing of a container.
const bool myMapMatchJunctions
void addTransport(const SUMOSAXAttributes &attrs)
Processing of a transport.
void parseWalkPositions(const SUMOSAXAttributes &attrs, const std::string &personID, const ROEdge *fromEdge, const ROEdge *&toEdge, double &departPos, double &arrivalPos, std::string &busStopID, const ROPerson::PlanItem *const lastStage, bool &ok)
@ brief parse depart- and arrival positions of a walk
MsgHandler *const myErrorOutput
Depending on the "ignore-errors" option different outputs are used.
void closeRoute(const bool mayBeDisconnected=false)
closes (ends) the building of a route.
void closeFlow()
Ends the processing of a flow.
int myActiveRouteRepeat
number of repetitions of the active route
void closeContainer()
Ends the processing of a container.
void closeVehicleTypeDistribution()
closes (ends) the building of a distribution
void addPerson(const SUMOSAXAttributes &attrs)
Processing of a person.
void parseGeoEdges(const PositionVector &positions, bool geo, ConstROEdgeVector &into, const std::string &rid, bool isFrom, bool &ok)
Parse edges from coordinates.
RORouteDef * myCurrentAlternatives
The currently parsed route alternatives.
void openFlow(const SUMOSAXAttributes &attrs)
opens a flow for reading
void addPersonTrip(const SUMOSAXAttributes &attrs)
add a routing request for a walking or intermodal person
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs)
opens a type distribution for reading
ROPerson * myActivePerson
The plan of the current person.
const ROEdge * getClosestEdge(const Position &pos, double distance, SUMOVehicleClass vClass)
find closest edge within distance for the given position or nullptr
void openRoute(const SUMOSAXAttributes &attrs)
opens a route for reading
void parseFromViaTo(SumoXMLTag tag, const SUMOSAXAttributes &attrs, bool &ok)
Called for parsing from and to and the corresponding taz attributes.
A complete router's route.
Definition: RORoute.h:52
const ConstROEdgeVector & getEdgeVector() const
Returns the list of edges this route consists of.
Definition: RORoute.h:152
A vehicle as used by router.
Definition: ROVehicle.h:50
static double rand(std::mt19937 *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.h:51
double getOverallProb() const
Return the sum of the probabilites assigned to the members.
bool add(T val, double prob, bool checkDuplicates=true)
Adds a value with an assigned probability to the distribution.
Parser for routes during their loading.
bool parseStop(SUMOVehicleParameter::Stop &stop, const SUMOSAXAttributes &attrs, std::string errorSuffix, MsgHandler *const errorOutput)
parses attributes common to all stops
std::vector< SUMOVehicleParameter::Stop > myActiveRouteStops
List of the stops on the parsed route.
void registerLastDepart()
save last depart (only to be used if vehicle is not discarded)
double myCurrentCosts
The currently parsed route costs.
std::string myActiveRouteID
The id of the current route.
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, container or flow.
const bool myHardFail
flag to enable or disable hard fails
SUMOVTypeParameter * myCurrentVType
The currently parsed vehicle type.
static StopPos checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
double myActiveRouteProbability
The probability of the current route.
int myInsertStopEdgesAt
where stop edges can be inserted into the current route (-1 means no insertion)
std::string myActiveRouteRefID
The id of the route the current route references to.
const RGBColor * myActiveRouteColor
The currently parsed route's color.
Encapsulated SAX-Attributes.
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.
const std::vector< std::string > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
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.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
Structure representing possible vehicle parameter.
double defaultProbability
The probability when being added to a distribution without an explicit probability.
void cacheParamRestrictions(const std::vector< std::string > &restrictionKeys)
SUMOVehicleClass vehicleClass
The vehicle's class.
std::string id
The vehicle type's id.
Definition of vehicle stop (position and duration)
std::string edge
The edge to stop at (used only in NETEDIT)
std::string lane
The lane to stop at.
std::string parkingarea
(Optional) parking area if one is assigned to the stop
double startPos
The stopping position start.
double endPos
The stopping position end.
std::string busstop
(Optional) bus stop if one is assigned to the stop
std::string containerstop
(Optional) container stop if one is assigned to the stop
Structure representing possible vehicle parameter.
double repetitionProbability
The probability for emitting a vehicle per second.
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
int repetitionsDone
The number of times the vehicle was already inserted.
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
double departPos
(optional) The position the vehicle shall depart from
std::string routeid
The vehicle's route id.
std::string id
The vehicle's id.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
bool wasSet(int what) const
Returns whether the given parameter was set.
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
static double parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string &id, double maxPos, const std::string &val, std::mt19937 *rng=0)
parse departPos or arrivalPos for a walk
static std::string getEdgeIDFromLane(const std::string laneID)
return edge id when given the lane ID
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined