Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
RORouteHandler.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2026 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// ===========================================================================
49// method definitions
50// ===========================================================================
51RORouteHandler::RORouteHandler(RONet& net, const std::string& file,
52 const bool tryRepair,
53 const bool emptyDestinationsAllowed,
54 const bool ignoreErrors,
55 const bool checkSchema) :
56 SUMORouteHandler(file, checkSchema ? "routes" : "", true),
57 MapMatcher(OptionsCont::getOptions().getBool("mapmatch.junctions"),
58 OptionsCont::getOptions().getBool("mapmatch.taz"),
59 OptionsCont::getOptions().getFloat("mapmatch.distance"),
60 ignoreErrors ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
61 myNet(net),
62 myActiveRouteRepeat(0),
63 myActiveRoutePeriod(0),
64 myActivePlan(nullptr),
65 myActiveContainerPlan(nullptr),
66 myActiveContainerPlanSize(0),
67 myTryRepair(tryRepair),
68 myEmptyDestinationsAllowed(emptyDestinationsAllowed),
69 myErrorOutput(ignoreErrors ? MsgHandler::getWarningInstance() : MsgHandler::getErrorInstance()),
70 myBegin(string2time(OptionsCont::getOptions().getString("begin"))),
71 myKeepVTypeDist(OptionsCont::getOptions().getBool("keep-vtype-distributions")),
72 myUnsortedInput(OptionsCont::getOptions().exists("unsorted-input") && OptionsCont::getOptions().getBool("unsorted-input")),
73 myWriteFlows(OptionsCont::getOptions().exists("keep-flows") && OptionsCont::getOptions().getBool("keep-flows")),
74 myCurrentVTypeDistribution(nullptr),
75 myCurrentAlternatives(nullptr),
76 myUseTaz(OptionsCont::getOptions().getBool("with-taz")),
77 myWriteJunctions(OptionsCont::getOptions().exists("write-trips")
78 && OptionsCont::getOptions().getBool("write-trips")
79 && OptionsCont::getOptions().getBool("write-trips.junctions")) {
80 myActiveRoute.reserve(100);
81}
82
83
87
88
89void
91 if (myActivePlan != nullptr) {
92 for (ROPerson::PlanItem* const it : *myActivePlan) {
93 delete it;
94 }
95 delete myActivePlan;
96 myActivePlan = nullptr;
97 }
99 myActiveContainerPlan = nullptr;
100 delete myVehicleParameter;
101 myVehicleParameter = nullptr;
102}
103
104
105void
107 const std::string element = toString(tag);
108 myActiveRoute.clear();
109 bool useTaz = myUseTaz;
111 WRITE_WARNINGF(TL("Taz usage was requested but no taz present in % '%'!"), element, myVehicleParameter->id);
112 useTaz = false;
113 }
117 if (type != nullptr) {
118 vClass = type->vehicleClass;
119 }
120 }
121 // from-attributes
122 const std::string rid = "for " + element + " '" + myVehicleParameter->id + "'";
123 if ((useTaz || (!attrs.hasAttribute(SUMO_ATTR_FROM) && !attrs.hasAttribute(SUMO_ATTR_FROMXY) && !attrs.hasAttribute(SUMO_ATTR_FROMLONLAT))) &&
125 const bool useJunction = attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION);
126 const std::string tazType = useJunction ? "junction" : "taz";
127 const std::string tazID = attrs.get<std::string>(useJunction ? SUMO_ATTR_FROM_JUNCTION : SUMO_ATTR_FROM_TAZ, myVehicleParameter->id.c_str(), ok, true);
128 const ROEdge* fromTaz = myNet.getEdge(tazID + "-source");
129 if (fromTaz == nullptr) {
130 myErrorOutput->inform("Source " + tazType + " '" + tazID + "' not known for " + element + " '" + myVehicleParameter->id + "'!"
131 + (useJunction ? JUNCTION_TAZ_MISSING_HELP : ""));
132 ok = false;
133 } else if (fromTaz->getNumSuccessors() == 0 && tag != SUMO_TAG_PERSON) {
134 myErrorOutput->inform("Source " + tazType + " '" + tazID + "' has no outgoing edges for " + element + " '" + myVehicleParameter->id + "'!");
135 ok = false;
136 } else {
137 myActiveRoute.push_back(fromTaz);
138 if (useJunction && tag != SUMO_TAG_PERSON && !myWriteJunctions) {
141 }
142 }
143 } else if (attrs.hasAttribute(SUMO_ATTR_FROMXY)) {
144 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_FROMXY, myVehicleParameter->id.c_str(), ok), false, vClass, myActiveRoute, rid, true, ok);
145 if (myMapMatchTAZ && ok) {
146 myVehicleParameter->fromTaz = myActiveRoute.back()->getID();
148 }
149 } else if (attrs.hasAttribute(SUMO_ATTR_FROMLONLAT)) {
150 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_FROMLONLAT, myVehicleParameter->id.c_str(), ok), true, vClass, myActiveRoute, rid, true, ok);
151 if (myMapMatchTAZ && ok) {
152 myVehicleParameter->fromTaz = myActiveRoute.back()->getID();
154 }
155 } else {
156 parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_FROM, myVehicleParameter->id.c_str(), ok), myActiveRoute, rid, ok);
157 }
160 }
161
162 // via-attributes
163 ConstROEdgeVector viaEdges;
164 if (attrs.hasAttribute(SUMO_ATTR_VIAXY)) {
165 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_VIAXY, myVehicleParameter->id.c_str(), ok), false, vClass, viaEdges, rid, false, ok);
166 } else if (attrs.hasAttribute(SUMO_ATTR_VIALONLAT)) {
167 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_VIALONLAT, myVehicleParameter->id.c_str(), ok), true, vClass, viaEdges, rid, false, ok);
168 } else if (attrs.hasAttribute(SUMO_ATTR_VIAJUNCTIONS)) {
169 for (std::string junctionID : attrs.get<std::vector<std::string> >(SUMO_ATTR_VIAJUNCTIONS, myVehicleParameter->id.c_str(), ok)) {
170 const ROEdge* viaSink = myNet.getEdge(junctionID + "-sink");
171 if (viaSink == nullptr) {
172 myErrorOutput->inform("Junction-taz '" + junctionID + "' not found." + JUNCTION_TAZ_MISSING_HELP);
173 ok = false;
174 } else {
175 viaEdges.push_back(viaSink);
176 }
177 }
178 } else {
179 parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_VIA, myVehicleParameter->id.c_str(), ok, "", true), viaEdges, rid, ok);
180 }
181 for (const ROEdge* e : viaEdges) {
182 myActiveRoute.push_back(e);
183 myVehicleParameter->via.push_back(e->getID());
184 }
185
186 // to-attributes
187 if ((useTaz || (!attrs.hasAttribute(SUMO_ATTR_TO) && !attrs.hasAttribute(SUMO_ATTR_TOXY) && !attrs.hasAttribute(SUMO_ATTR_TOLONLAT))) &&
189 const bool useJunction = attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION);
190 const std::string tazType = useJunction ? "junction" : "taz";
191 const std::string tazID = attrs.get<std::string>(useJunction ? SUMO_ATTR_TO_JUNCTION : SUMO_ATTR_TO_TAZ, myVehicleParameter->id.c_str(), ok, true);
192 const ROEdge* toTaz = myNet.getEdge(tazID + "-sink");
193 if (toTaz == nullptr) {
194 myErrorOutput->inform("Sink " + tazType + " '" + tazID + "' not known for " + element + " '" + myVehicleParameter->id + "'!"
195 + (useJunction ? JUNCTION_TAZ_MISSING_HELP : ""));
196 ok = false;
197 } else if (toTaz->getNumPredecessors() == 0 && tag != SUMO_TAG_PERSON) {
198 myErrorOutput->inform("Sink " + tazType + " '" + tazID + "' has no incoming edges for " + element + " '" + myVehicleParameter->id + "'!");
199 ok = false;
200 } else {
201 myActiveRoute.push_back(toTaz);
202 if (useJunction && tag != SUMO_TAG_PERSON && !myWriteJunctions) {
203 myVehicleParameter->toTaz = tazID;
205 }
206 }
207 } else if (attrs.hasAttribute(SUMO_ATTR_TOXY)) {
208 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_TOXY, myVehicleParameter->id.c_str(), ok, true), false, vClass, myActiveRoute, rid, false, ok);
209 if (myMapMatchTAZ && ok) {
210 myVehicleParameter->toTaz = myActiveRoute.back()->getID();
212 }
213 } else if (attrs.hasAttribute(SUMO_ATTR_TOLONLAT)) {
214 parseGeoEdges(attrs.get<PositionVector>(SUMO_ATTR_TOLONLAT, myVehicleParameter->id.c_str(), ok, true), true, vClass, myActiveRoute, rid, false, ok);
215 if (myMapMatchTAZ && ok) {
216 myVehicleParameter->toTaz = myActiveRoute.back()->getID();
218 }
219 } else {
220 parseEdges(attrs.getOpt<std::string>(SUMO_ATTR_TO, myVehicleParameter->id.c_str(), ok, "", true), myActiveRoute, rid, ok);
221 }
223 if (myVehicleParameter->routeid == "") {
225 }
226}
227
228
229void
231 const SUMOSAXAttributes& attrs) {
232 try {
233 if (myActivePlan != nullptr && myActivePlan->empty() && myVehicleParameter->departProcedure == DepartDefinition::TRIGGERED && element != SUMO_TAG_RIDE && element != SUMO_TAG_PARAM) {
234 throw ProcessError(TLF("Triggered departure for person '%' requires starting with a ride.", myVehicleParameter->id));
236 throw ProcessError(TLF("Triggered departure for container '%' requires starting with a transport.", myVehicleParameter->id));
237 }
238 SUMORouteHandler::myStartElement(element, attrs);
239 bool ok = true;
240 switch (element) {
241 case SUMO_TAG_PERSON:
242 case SUMO_TAG_PERSONFLOW: {
243 myActivePlan = new std::vector<ROPerson::PlanItem*>();
244 break;
245 }
246 case SUMO_TAG_RIDE:
247 break; // handled in addRide, called from SUMORouteHandler::myStartElement
253 (*myActiveContainerPlan) << attrs;
254 break;
257 if (myActiveContainerPlan == nullptr) {
258 throw ProcessError(TLF("Found % outside container element", toString((SumoXMLTag)element)));
259 }
260 // copy container elements
262 (*myActiveContainerPlan) << attrs;
265 break;
266 case SUMO_TAG_FLOW:
268 parseFromViaTo((SumoXMLTag)element, attrs, ok);
269 break;
270 case SUMO_TAG_TRIP:
272 parseFromViaTo((SumoXMLTag)element, attrs, ok);
273 break;
274 default:
275 break;
276 }
277 } catch (ProcessError&) {
279 throw;
280 }
281}
282
283
284void
286 bool ok = true;
287 myCurrentVTypeDistributionID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
288 if (ok) {
290 if (attrs.hasAttribute(SUMO_ATTR_VTYPES)) {
291 std::vector<double> probs;
292 if (attrs.hasAttribute(SUMO_ATTR_PROBS)) {
293 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_PROBS, myCurrentVTypeDistributionID.c_str(), ok));
294 while (st.hasNext()) {
295 probs.push_back(StringUtils::toDoubleSecure(st.next(), 1.0));
296 }
297 }
298 const std::string vTypes = attrs.get<std::string>(SUMO_ATTR_VTYPES, myCurrentVTypeDistributionID.c_str(), ok);
299 StringTokenizer st(vTypes);
300 int probIndex = 0;
301 while (st.hasNext()) {
302 const std::string typeID = st.next();
304 if (dist != nullptr) {
305 const double distProb = ((int)probs.size() > probIndex ? probs[probIndex] : 1.) / dist->getOverallProb();
306 std::vector<double>::const_iterator probIt = dist->getProbs().begin();
307 for (SUMOVTypeParameter* const type : dist->getVals()) {
308 myCurrentVTypeDistribution->add(type, distProb * *probIt);
309 probIt++;
310 }
311 } else {
312 SUMOVTypeParameter* const type = myNet.getVehicleTypeSecure(typeID);
313 if (type == nullptr) {
314 myErrorOutput->inform("Unknown vehicle type '" + typeID + "' in distribution '" + myCurrentVTypeDistributionID + "'.");
315 } else {
316 const double prob = ((int)probs.size() > probIndex ? probs[probIndex] : type->defaultProbability);
317 myCurrentVTypeDistribution->add(type, prob);
318 }
319 }
320 probIndex++;
321 }
322 if (probs.size() > 0 && probIndex != (int)probs.size()) {
323 WRITE_WARNING("Got " + toString(probs.size()) + " probabilities for " + toString(probIndex) +
324 " types in vTypeDistribution '" + myCurrentVTypeDistributionID + "'");
325 }
326 }
327 }
328}
329
330
331void
333 if (myCurrentVTypeDistribution != nullptr) {
336 myErrorOutput->inform("Vehicle type distribution '" + myCurrentVTypeDistributionID + "' is empty.");
339 myErrorOutput->inform("Another vehicle type (or distribution) with the id '" + myCurrentVTypeDistributionID + "' exists.");
340 }
342 }
343}
344
345
346void
350 // check whether the id is really necessary
351 std::string rid;
352 if (myCurrentAlternatives != nullptr) {
354 rid = "distribution '" + myCurrentAlternatives->getID() + "'";
355 } else if (myVehicleParameter != nullptr) {
356 // ok, a vehicle is wrapping the route,
357 // we may use this vehicle's id as default
358 myVehicleParameter->routeid = myActiveRouteID = "!" + myVehicleParameter->id; // !!! document this
359 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
360 WRITE_WARNINGF(TL("Ids of internal routes are ignored (vehicle '%')."), myVehicleParameter->id);
361 }
362 } else {
363 bool ok = true;
364 myActiveRouteID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
365 if (!ok) {
366 return;
367 }
368 rid = "'" + myActiveRouteID + "'";
369 }
370 if (myVehicleParameter != nullptr) { // have to do this here for nested route distributions
371 rid = "for vehicle '" + myVehicleParameter->id + "'";
372 }
373 bool ok = true;
374 if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
375 parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myActiveRouteID.c_str(), ok), myActiveRoute, rid, ok);
376 }
377 myActiveRouteRefID = attrs.getOpt<std::string>(SUMO_ATTR_REFID, myActiveRouteID.c_str(), ok, "");
378 if (myActiveRouteRefID != "" && myNet.getRouteDef(myActiveRouteRefID) == nullptr) {
379 myErrorOutput->inform("Invalid reference to route '" + myActiveRouteRefID + "' in route " + rid + ".");
380 }
381 if (myCurrentAlternatives != nullptr && !attrs.hasAttribute(SUMO_ATTR_PROB)) {
382 WRITE_WARNINGF(TL("No probability for route %, using default."), rid);
383 }
385 if (ok && myActiveRouteProbability < 0) {
386 myErrorOutput->inform("Invalid probability for route '" + myActiveRouteID + "'.");
387 }
389 ok = true;
390 myActiveRouteRepeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, myActiveRouteID.c_str(), ok, 0);
392 if (myActiveRouteRepeat > 0) {
394 if (myVehicleParameter != nullptr) {
396 if (type != nullptr) {
397 vClass = type->vehicleClass;
398 }
399 }
400 if (myActiveRoute.size() > 0 && !myActiveRoute.back()->isConnectedTo(*myActiveRoute.front(), vClass)) {
401 myErrorOutput->inform("Disconnected route " + rid + " when repeating.");
402 }
403 }
404 myCurrentCosts = attrs.getOpt<double>(SUMO_ATTR_COST, myActiveRouteID.c_str(), ok, -1);
405 if (ok && myCurrentCosts != -1 && myCurrentCosts < 0) {
406 myErrorOutput->inform("Invalid cost for route '" + myActiveRouteID + "'.");
407 }
408}
409
410
411void
413 // currently unused
414}
415
416
417void
419 // currently unused
420}
421
422
423void
425 // currently unused
426}
427
428
429void
430RORouteHandler::closeRoute(const bool mayBeDisconnected) {
431 const bool mustReroute = myActiveRoute.size() == 0 && myActiveRouteStops.size() != 0;
432 if (mustReroute) {
433 // implicit route from stops
435 ROEdge* edge = myNet.getEdge(stop.edge);
436 myActiveRoute.push_back(edge);
437 }
438 }
439 if (myActiveRoute.size() == 0) {
440 if (myActiveRouteRefID != "" && myCurrentAlternatives != nullptr) {
442 myActiveRouteID = "";
444 return;
445 }
446 if (myVehicleParameter != nullptr) {
447 myErrorOutput->inform("The route for vehicle '" + myVehicleParameter->id + "' has no edges.");
448 } else {
449 myErrorOutput->inform("Route '" + myActiveRouteID + "' has no edges.");
450 }
451 myActiveRouteID = "";
452 myActiveRouteStops.clear();
453 return;
454 }
455 if (myActiveRoute.size() == 1 && myActiveRoute.front()->isTazConnector()) {
456 myErrorOutput->inform("The routing information for vehicle '" + myVehicleParameter->id + "' is insufficient.");
457 myActiveRouteID = "";
458 myActiveRouteStops.clear();
459 return;
460 }
461 if (!mayBeDisconnected && OptionsCont::getOptions().exists("no-internal-links") && !OptionsCont::getOptions().getBool("no-internal-links")) {
462 // fix internal edges which did not get parsed
463 const ROEdge* last = nullptr;
464 ConstROEdgeVector fullRoute;
465 for (const ROEdge* roe : myActiveRoute) {
466 if (last != nullptr) {
467 for (const ROEdge* intern : last->getSuccessors()) {
468 if (intern->isInternal() && intern->getSuccessors().size() == 1 && intern->getSuccessors().front() == roe) {
469 fullRoute.push_back(intern);
470 }
471 }
472 }
473 fullRoute.push_back(roe);
474 last = roe;
475 }
476 myActiveRoute = fullRoute;
477 }
478 if (myActiveRouteRepeat > 0) {
479 // duplicate route
481 auto tmpStops = myActiveRouteStops;
482 for (int i = 0; i < myActiveRouteRepeat; i++) {
483 myActiveRoute.insert(myActiveRoute.begin(), tmpEdges.begin(), tmpEdges.end());
484 for (SUMOVehicleParameter::Stop stop : tmpStops) {
485 if (stop.until > 0) {
486 if (myActiveRoutePeriod <= 0) {
487 const std::string description = myVehicleParameter != nullptr
488 ? "for vehicle '" + myVehicleParameter->id + "'"
489 : "'" + myActiveRouteID + "'";
490 throw ProcessError(TLF("Cannot repeat stops with 'until' in route % because no cycleTime is defined.", description));
491 }
492 stop.until += myActiveRoutePeriod * (i + 1);
493 stop.arrival += myActiveRoutePeriod * (i + 1);
494 }
495 myActiveRouteStops.push_back(stop);
496 }
497 }
498 }
499 std::shared_ptr<RORoute> route = std::make_shared<RORoute>(myActiveRouteID, myCurrentCosts, myActiveRouteProbability, myActiveRoute,
501 myActiveRoute.clear();
502 if (myCurrentAlternatives == nullptr) {
503 if (myNet.getRouteDef(myActiveRouteID) != nullptr) {
504 if (myVehicleParameter != nullptr) {
505 myErrorOutput->inform("Another route for vehicle '" + myVehicleParameter->id + "' exists.");
506 } else {
507 myErrorOutput->inform("Another route (or distribution) with the id '" + myActiveRouteID + "' exists.");
508 }
509 myActiveRouteID = "";
510 myActiveRouteStops.clear();
511 return;
512 } else {
513 myCurrentAlternatives = new RORouteDef(myActiveRouteID, 0, mayBeDisconnected || myTryRepair, mayBeDisconnected);
516 myCurrentAlternatives = nullptr;
517 }
518 } else {
520 }
521 myActiveRouteID = "";
522 myActiveRouteStops.clear();
523}
524
525
526void
528 // check whether the id is really necessary
529 bool ok = true;
530 std::string id;
531 if (myVehicleParameter != nullptr) {
532 // ok, a vehicle is wrapping the route,
533 // we may use this vehicle's id as default
534 myVehicleParameter->routeid = id = "!" + myVehicleParameter->id; // !!! document this
535 if (attrs.hasAttribute(SUMO_ATTR_ID)) {
536 WRITE_WARNINGF(TL("Ids of internal route distributions are ignored (vehicle '%')."), myVehicleParameter->id);
537 }
538 } else {
539 id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
540 if (!ok) {
541 return;
542 }
543 }
544 // try to get the index of the last element
545 int index = attrs.getOpt<int>(SUMO_ATTR_LAST, id.c_str(), ok, 0);
546 if (ok && index < 0) {
547 myErrorOutput->inform("Negative index of a route alternative (id='" + id + "').");
548 return;
549 }
550 // build the alternative cont
551 myCurrentAlternatives = new RORouteDef(id, index, myTryRepair, false);
552 if (attrs.hasAttribute(SUMO_ATTR_ROUTES)) {
553 ok = true;
554 StringTokenizer st(attrs.get<std::string>(SUMO_ATTR_ROUTES, id.c_str(), ok));
555 while (st.hasNext()) {
556 const std::string routeID = st.next();
557 const RORouteDef* route = myNet.getRouteDef(routeID);
558 if (route == nullptr) {
559 myErrorOutput->inform("Unknown route '" + routeID + "' in distribution '" + id + "'.");
560 } else {
562 }
563 }
564 }
565}
566
567
568void
570 if (myCurrentAlternatives != nullptr) {
572 myErrorOutput->inform("Route distribution '" + myCurrentAlternatives->getID() + "' is empty.");
575 myErrorOutput->inform("Another route (or distribution) with the id '" + myCurrentAlternatives->getID() + "' exists.");
577 } else {
578 if (myVehicleParameter != nullptr
579 && (myUseTaz || OptionsCont::getOptions().getBool("junction-taz"))
582 // we are loading a rou.alt.xml, permit rerouting between taz
583 bool ok = true;
584 ConstROEdgeVector edges;
585 if (myVehicleParameter->fromTaz != "") {
586 const std::string tazID = myVehicleParameter->fromTaz;
587 const ROEdge* fromTaz = myNet.getEdge(tazID + "-source");
588 if (fromTaz == nullptr) {
589 myErrorOutput->inform("Source taz '" + tazID + "' not known for vehicle '" + myVehicleParameter->id + "'!");
590 ok = false;
591 } else if (fromTaz->getNumSuccessors() == 0) {
592 myErrorOutput->inform("Source taz '" + tazID + "' has no outgoing edges for vehicle '" + myVehicleParameter->id + "'!");
593 ok = false;
594 } else {
595 edges.push_back(fromTaz);
596 }
597 } else {
598 edges.push_back(myCurrentAlternatives->getOrigin());
599 }
600 if (myVehicleParameter->toTaz != "") {
601 const std::string tazID = myVehicleParameter->toTaz;
602 const ROEdge* toTaz = myNet.getEdge(tazID + "-sink");
603 if (toTaz == nullptr) {
604 myErrorOutput->inform("Sink taz '" + tazID + "' not known for vehicle '" + myVehicleParameter->id + "'!");
605 ok = false;
606 } else if (toTaz->getNumPredecessors() == 0) {
607 myErrorOutput->inform("Sink taz '" + tazID + "' has no incoming edges for vehicle '" + myVehicleParameter->id + "'!");
608 ok = false;
609 } else {
610 edges.push_back(toTaz);
611 }
612 } else {
613 edges.push_back(myCurrentAlternatives->getDestination());
614 }
615 if (ok) {
616 // negative probability indicates that this route should not be written
617 myCurrentAlternatives->addLoadedAlternative(std::make_shared<RORoute>(myCurrentAlternatives->getID(), 0, -1, edges, nullptr, myActiveRouteStops));
618 }
619 }
620 }
621 myCurrentAlternatives = nullptr;
622 }
623}
624
625
626void
629 // get the vehicle id
632 return;
633 }
634 // get vehicle type
636 if (type == nullptr) {
637 myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for vehicle '" + myVehicleParameter->id + "' is not known.");
639 } else {
640 if (!myKeepVTypeDist) {
641 // fix the type id in case we used a distribution
643 }
644 }
645 if (type->vehicleClass == SVC_PEDESTRIAN) {
646 WRITE_WARNINGF(TL("Vehicle type '%' with vClass=pedestrian should only be used for persons and not for vehicle '%'."), type->id, myVehicleParameter->id);
647 }
648 // get the route
650 if (route == nullptr) {
651 myErrorOutput->inform("The route of the vehicle '" + myVehicleParameter->id + "' is not known.");
652 return;
653 }
654 if (MsgHandler::getErrorInstance()->wasInformed()) {
655 return;
656 }
657 const bool needCopy = route->getID()[0] != '!';
658 if (needCopy) {
659 route = route->copy("!" + myVehicleParameter->id, myVehicleParameter->depart);
660 }
661 // build the vehicle
662 ROVehicle* veh = new ROVehicle(*myVehicleParameter, route, type, &myNet, myErrorOutput);
665 } else if (needCopy) {
666 delete route;
667 }
668 delete myVehicleParameter;
669 myVehicleParameter = nullptr;
670}
671
672
673void
675 if (myCurrentVTypeRef.empty()) {
677 if (OptionsCont::getOptions().isSet("restriction-params")) {
678 const std::vector<std::string> paramKeys = OptionsCont::getOptions().getStringVector("restriction-params");
680 }
681 }
682 if (myCurrentVTypeDistribution != nullptr) {
683 if (myCurrentVTypeRef.empty()) {
685 } else {
687 if (dist != nullptr) {
688 const double distProb = (myCurrentVTypeProbability >= 0 ? myCurrentVTypeProbability : 1) / dist->getOverallProb();
689 std::vector<double>::const_iterator probIt = dist->getProbs().begin();
690 for (SUMOVTypeParameter* const type : dist->getVals()) {
691 myCurrentVTypeDistribution->add(type, distProb * *probIt);
692 probIt++;
693 }
694 } else {
697 myCurrentVTypeDistribution->add(type, probability);
698 }
699 }
700 }
701 myCurrentVType = nullptr;
702}
703
704
705void
708 if (type == nullptr) {
709 myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for person '" + myVehicleParameter->id + "' is not known.");
711 }
712 if (myActivePlan == nullptr || myActivePlan->empty()) {
713 WRITE_WARNINGF(TL("Discarding person '%' because her plan is empty"), myVehicleParameter->id);
715 ROPerson* person = new ROPerson(*myVehicleParameter, type);
716 for (ROPerson::PlanItem* item : *myActivePlan) {
717 person->getPlan().push_back(item);
718 }
719 myActivePlan->clear();
720 if (myNet.addPerson(person)) {
723 }
724 }
726}
727
728
729void
731 std::string typeID = DEFAULT_PEDTYPE_ID;
733 myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for personFlow '" + myVehicleParameter->id + "' is not known.");
734 } else {
735 typeID = myVehicleParameter->vtypeid;
736 }
737 if (myActivePlan == nullptr || myActivePlan->empty()) {
738 WRITE_WARNINGF(TL("Discarding personFlow '%' because their plan is empty"), myVehicleParameter->id);
739 } else {
741 // instantiate all persons of this flow
742 int i = 0;
743 std::string baseID = myVehicleParameter->id;
744 if (myWriteFlows) {
745 addFlowPerson(typeID, myVehicleParameter->depart, baseID, i);
748 throw ProcessError(TLF("probabilistic personFlow '%' must specify end time", myVehicleParameter->id));
749 } else {
752 addFlowPerson(typeID, t, baseID, i++);
753 }
754 }
755 }
756 } else {
758 // uniform sampling of departures from range is equivalent to poisson flow (encoded by negative offset)
759 if (OptionsCont::getOptions().getBool("randomize-flows") && myVehicleParameter->repetitionOffset >= 0) {
760 std::vector<SUMOTime> departures;
762 for (int j = 0; j < myVehicleParameter->repetitionNumber; ++j) {
763 departures.push_back(depart + RandHelper::rand(range));
764 }
765 std::sort(departures.begin(), departures.end());
766 std::reverse(departures.begin(), departures.end());
767 for (; i < myVehicleParameter->repetitionNumber; i++) {
768 addFlowPerson(typeID, departures[i], baseID, i);
770 }
771 } else {
774 // poisson: randomize first depart
776 }
778 addFlowPerson(typeID, depart + myVehicleParameter->repetitionTotalOffset, baseID, i);
781 }
782 }
783 }
784 }
785 }
787}
788
789
790void
791RORouteHandler::addFlowPerson(const std::string& typeID, SUMOTime depart, const std::string& baseID, int i) {
793 pars.id = baseID + "." + toString(i);
794 pars.depart = depart;
795 const SUMOVTypeParameter* const type = myNet.getVehicleTypeSecure(typeID);
796 if (!myKeepVTypeDist) {
797 pars.vtypeid = type->id;
798 }
799 ROPerson* person = new ROPerson(pars, type);
800 for (ROPerson::PlanItem* item : *myActivePlan) {
801 person->getPlan().push_back(item->clone());
802 }
803 if (myNet.addPerson(person)) {
804 if (i == 0) {
806 }
807 }
808}
809
810
811void
818 } else {
819 WRITE_WARNINGF(TL("Discarding container '%' because its plan is empty"), myVehicleParameter->id);
820 }
821 delete myVehicleParameter;
822 myVehicleParameter = nullptr;
824 myActiveContainerPlan = nullptr;
826}
827
828
835 } else {
836 WRITE_WARNINGF(TL("Discarding containerFlow '%' because its plan is empty"), myVehicleParameter->id);
837 }
838 delete myVehicleParameter;
839 myVehicleParameter = nullptr;
841 myActiveContainerPlan = nullptr;
843}
844
845
846void
849 // @todo: consider myScale?
851 delete myVehicleParameter;
852 myVehicleParameter = nullptr;
853 return;
854 }
855 // let's check whether vehicles had to depart before the simulation starts
857 const SUMOTime offsetToBegin = myBegin - myVehicleParameter->depart;
858 while (myVehicleParameter->repetitionTotalOffset < offsetToBegin) {
861 delete myVehicleParameter;
862 myVehicleParameter = nullptr;
863 return;
864 }
865 }
867 myErrorOutput->inform("The vehicle type '" + myVehicleParameter->vtypeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
868 }
869 if (myVehicleParameter->routeid[0] == '!' && myNet.getRouteDef(myVehicleParameter->routeid) == nullptr) {
870 closeRoute(true);
871 }
872 if (myNet.getRouteDef(myVehicleParameter->routeid) == nullptr) {
873 myErrorOutput->inform("The route '" + myVehicleParameter->routeid + "' for flow '" + myVehicleParameter->id + "' is not known.");
874 delete myVehicleParameter;
875 myVehicleParameter = nullptr;
876 return;
877 }
878 myActiveRouteID = "";
879 if (!MsgHandler::getErrorInstance()->wasInformed()) {
882 } else {
883 myErrorOutput->inform("Another flow with the id '" + myVehicleParameter->id + "' exists.");
884 delete myVehicleParameter;
885 }
886 } else {
887 delete myVehicleParameter;
888 }
889 myVehicleParameter = nullptr;
891}
892
893
894void
899
900
902RORouteHandler::retrieveStoppingPlace(const SUMOSAXAttributes& attrs, const std::string& errorSuffix, std::string& id, const SUMOVehicleParameter::Stop* stopParam) {
903 // dummy stop parameter to hold the attributes
905 if (stopParam != nullptr) {
906 stop = *stopParam;
907 } else {
908 bool ok = true;
909 stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
910 stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, nullptr, ok, stop.busstop); // alias
911 stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
912 stop.overheadWireSegment = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, nullptr, ok, "");
913 stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
914 stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
915 }
916 const SUMOVehicleParameter::Stop* toStop = nullptr;
917 if (stop.busstop != "") {
919 id = stop.busstop;
920 if (toStop == nullptr) {
921 WRITE_ERROR("The busStop '" + stop.busstop + "' is not known" + errorSuffix);
922 }
923 } else if (stop.containerstop != "") {
925 id = stop.containerstop;
926 if (toStop == nullptr) {
927 WRITE_ERROR("The containerStop '" + stop.containerstop + "' is not known" + errorSuffix);
928 }
929 } else if (stop.parkingarea != "") {
931 id = stop.parkingarea;
932 if (toStop == nullptr) {
933 WRITE_ERROR("The parkingArea '" + stop.parkingarea + "' is not known" + errorSuffix);
934 }
935 } else if (stop.chargingStation != "") {
936 // ok, we have a charging station
938 id = stop.chargingStation;
939 if (toStop == nullptr) {
940 WRITE_ERROR("The chargingStation '" + stop.chargingStation + "' is not known" + errorSuffix);
941 }
942 } else if (stop.overheadWireSegment != "") {
943 // ok, we have an overhead wire segment
945 id = stop.overheadWireSegment;
946 if (toStop == nullptr) {
947 WRITE_ERROR("The overhead wire segment '" + stop.overheadWireSegment + "' is not known" + errorSuffix);
948 }
949 }
950 return toStop;
951}
952
955 Parameterised* result = nullptr;
956 if (myActiveContainerPlan != nullptr) {
958 (*myActiveContainerPlan) << attrs;
961 return result;
962 }
963 std::string errorSuffix;
964 if (myActivePlan != nullptr) {
965 errorSuffix = " in person '" + myVehicleParameter->id + "'.";
966 } else if (myActiveContainerPlan != nullptr) {
967 errorSuffix = " in container '" + myVehicleParameter->id + "'.";
968 } else if (myVehicleParameter != nullptr) {
969 errorSuffix = " in vehicle '" + myVehicleParameter->id + "'.";
970 } else {
971 errorSuffix = " in route '" + myActiveRouteID + "'.";
972 }
974 bool ok = parseStop(stop, attrs, errorSuffix, myErrorOutput);
975 if (!ok) {
976 return result;
977 }
978 // try to parse the assigned bus stop
979 const ROEdge* edge = nullptr;
980 std::string stoppingPlaceID;
981 const SUMOVehicleParameter::Stop* stoppingPlace = retrieveStoppingPlace(attrs, errorSuffix, stoppingPlaceID, &stop);
982 bool hasPos = false;
983 if (stoppingPlace != nullptr) {
984 stop.lane = stoppingPlace->lane;
985 stop.endPos = stoppingPlace->endPos;
986 stop.startPos = stoppingPlace->startPos;
988 } else {
989 // no, the lane and the position should be given
990 stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, ok, "");
991 stop.edge = attrs.getOpt<std::string>(SUMO_ATTR_EDGE, nullptr, ok, "");
992 if (ok && stop.edge != "") {
993 edge = myNet.getEdge(stop.edge);
994 if (edge == nullptr) {
995 myErrorOutput->inform("The edge '" + stop.edge + "' for a stop is not known" + errorSuffix);
996 return result;
997 }
998 } else if (ok && stop.lane != "") {
1000 if (edge == nullptr) {
1001 myErrorOutput->inform("The lane '" + stop.lane + "' for a stop is not known" + errorSuffix);
1002 return result;
1003 }
1004 } else if (ok && ((attrs.hasAttribute(SUMO_ATTR_X) && attrs.hasAttribute(SUMO_ATTR_Y))
1005 || (attrs.hasAttribute(SUMO_ATTR_LON) && attrs.hasAttribute(SUMO_ATTR_LAT)))) {
1006 Position pos;
1007 bool geo = false;
1008 if (attrs.hasAttribute(SUMO_ATTR_X) && attrs.hasAttribute(SUMO_ATTR_Y)) {
1009 pos = Position(attrs.get<double>(SUMO_ATTR_X, myVehicleParameter->id.c_str(), ok), attrs.get<double>(SUMO_ATTR_Y, myVehicleParameter->id.c_str(), ok));
1010 } else {
1011 pos = Position(attrs.get<double>(SUMO_ATTR_LON, myVehicleParameter->id.c_str(), ok), attrs.get<double>(SUMO_ATTR_LAT, myVehicleParameter->id.c_str(), ok));
1012 geo = true;
1013 }
1014 PositionVector positions;
1015 positions.push_back(pos);
1016 ConstROEdgeVector geoEdges;
1020 if (type != nullptr) {
1021 vClass = type->vehicleClass;
1022 }
1023 }
1024 parseGeoEdges(positions, geo, vClass, geoEdges, myVehicleParameter->id, true, ok, true);
1025 if (ok) {
1026 edge = geoEdges.front();
1027 hasPos = true;
1028 if (geo) {
1030 }
1032 stop.endPos = edge->getLanes()[0]->getShape().nearest_offset_to_point2D(pos, false);
1033 } else {
1034 return result;
1035 }
1036 } else if (!ok || (stop.lane == "" && stop.edge == "")) {
1037 myErrorOutput->inform("A stop must be placed on a bus stop, a container stop, a parking area, an edge or a lane" + errorSuffix);
1038 return result;
1039 }
1040 if (!hasPos) {
1041 stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, ok, edge->getLength());
1042 }
1043 stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, ok, stop.endPos - 2 * POSITION_EPS);
1044 const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, !attrs.hasAttribute(SUMO_ATTR_STARTPOS) && !attrs.hasAttribute(SUMO_ATTR_ENDPOS));
1045 const double endPosOffset = edge->isInternal() ? edge->getNormalBefore()->getLength() : 0;
1046 if (!ok || (checkStopPos(stop.startPos, stop.endPos, edge->getLength() + endPosOffset, POSITION_EPS, friendlyPos) != SUMORouteHandler::StopPos::STOPPOS_VALID)) {
1047 myErrorOutput->inform("Invalid start or end position for stop" + errorSuffix);
1048 return result;
1049 }
1050 }
1051 stop.edge = edge->getID();
1052 if (myActivePlan != nullptr) {
1053 ROPerson::addStop(*myActivePlan, stop, edge);
1054 result = myActivePlan->back()->getStopParameters();
1055 } else if (myVehicleParameter != nullptr) {
1056 myVehicleParameter->stops.push_back(stop);
1057 result = &myVehicleParameter->stops.back();
1058 } else {
1059 myActiveRouteStops.push_back(stop);
1060 result = &myActiveRouteStops.back();
1061 }
1062 if (myInsertStopEdgesAt >= 0) {
1063 myActiveRoute.insert(myActiveRoute.begin() + myInsertStopEdgesAt, edge);
1065 }
1066 return result;
1067}
1068
1069
1070void
1072 bool ok = true;
1073 std::vector<ROPerson::PlanItem*>& plan = *myActivePlan;
1074 const std::string pid = myVehicleParameter->id;
1075
1076 const ROEdge* from = nullptr;
1077 const ROEdge* to = nullptr;
1078 parseFromViaTo(SUMO_TAG_PERSON, attrs, ok);
1081 if (ok) {
1082 from = myActiveRoute.front();
1083 }
1084 } else if (plan.empty()) {
1085 myErrorOutput->inform("The start edge for person '" + pid + "' is not known.");
1086 return;
1087 }
1088 std::string stoppingPlaceID;
1089 const SUMOVehicleParameter::Stop* stop = retrieveStoppingPlace(attrs, " for ride of person '" + myVehicleParameter->id + "'", stoppingPlaceID);
1090 if (stop != nullptr) {
1092 } else {
1095 to = myActiveRoute.back();
1096 } else {
1097 myErrorOutput->inform("The to edge is missing within a ride of '" + myVehicleParameter->id + "'.");
1098 return;
1099 }
1100 }
1101 double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, myVehicleParameter->id.c_str(), ok,
1102 stop == nullptr ? std::numeric_limits<double>::infinity() : stop->endPos);
1103 const std::string lines = attrs.getOpt<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok, LINE_ANY);
1104 const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, pid.c_str(), ok, "");
1105
1107 StringTokenizer st(lines);
1108 if (st.size() != 1 || st.get(0) == LINE_ANY) {
1109 myErrorOutput->inform("Triggered departure for person '" + pid + "' requires a unique lines value.");
1110 return;
1111 }
1112 const std::string vehID = st.front();
1113 if (myNet.knowsVehicle(vehID)) {
1114 const SUMOTime vehDepart = myNet.getDeparture(vehID);
1115 if (vehDepart == -1) {
1116 myErrorOutput->inform("Cannot use triggered vehicle '" + vehID + "' in triggered departure for person '" + pid + "'.");
1117 return;
1118 }
1119 myVehicleParameter->depart = vehDepart + 1; // write person after vehicle
1120 } else {
1121 if (mySkippedVehicles.count(vehID) == 0) {
1122 myErrorOutput->inform("Unknown vehicle '" + vehID + "' in triggered departure for person '" + pid + "'.");
1123 return;
1124 }
1125 myVehicleParameter->departProcedure = DepartDefinition::GIVEN; // make sure the person gets skipped due to depart time
1126 }
1127 }
1128 ROPerson::addRide(plan, from, to, lines, arrivalPos, stoppingPlaceID, group);
1129}
1130
1131
1132void
1135 bool ok = true;
1136 const std::string pid = myVehicleParameter->id;
1137 const std::string desc = attrs.get<std::string>(SUMO_ATTR_LINES, pid.c_str(), ok);
1138 StringTokenizer st(desc);
1139 if (st.size() != 1) {
1140 throw ProcessError(TLF("Triggered departure for container '%' requires a unique lines value.", pid));
1141 }
1142 const std::string vehID = st.front();
1143 if (!myNet.knowsVehicle(vehID)) {
1144 if (mySkippedVehicles.count(vehID) == 0) {
1145 throw ProcessError("Unknown vehicle '" + vehID + "' in triggered departure for container '" + pid + "'.");
1146 }
1147 return;
1148 }
1149 SUMOTime vehDepart = myNet.getDeparture(vehID);
1150 if (vehDepart == -1) {
1151 throw ProcessError("Cannot use triggered vehicle '" + vehID + "' in triggered departure for container '" + pid + "'.");
1152 }
1153 myVehicleParameter->depart = vehDepart + 1; // write container after vehicle
1154 }
1155}
1156
1157
1158void
1161
1162
1163void
1164RORouteHandler::parseEdges(const std::string& desc, ConstROEdgeVector& into,
1165 const std::string& rid, bool& ok) {
1166 for (StringTokenizer st(desc); st.hasNext();) {
1167 const std::string id = st.next();
1168 const ROEdge* edge = myNet.getEdge(id);
1169 if (edge == nullptr) {
1170 myErrorOutput->inform("The edge '" + id + "' within the route " + rid + " is not known.");
1171 ok = false;
1172 } else {
1173 into.push_back(edge);
1174 }
1175 }
1176}
1177
1178
1179void
1180RORouteHandler::parseWalkPositions(const SUMOSAXAttributes& attrs, const std::string& personID,
1181 const ROEdge* /*fromEdge*/, const ROEdge*& toEdge,
1182 double& departPos, double& arrivalPos, std::string& busStopID,
1183 const ROPerson::PlanItem* const lastStage, bool& ok) {
1184 const std::string description = "walk or personTrip of '" + personID + "'.";
1185 if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
1186 WRITE_WARNING(TL("The attribute departPos is no longer supported for walks, please use the person attribute, the arrivalPos of the previous step or explicit stops."));
1187 }
1188 departPos = myVehicleParameter->departPos;
1189 if (lastStage != nullptr) {
1190 departPos = lastStage->getDestinationPos();
1191 }
1192
1193 busStopID = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
1194
1195 const SUMOVehicleParameter::Stop* bs = retrieveStoppingPlace(attrs, description, busStopID);
1196 if (bs != nullptr) {
1198 arrivalPos = (bs->startPos + bs->endPos) / 2;
1199 }
1200 if (toEdge != nullptr) {
1203 myHardFail, description, toEdge->getLength(),
1204 attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, description.c_str(), ok));
1205 }
1206 } else {
1207 throw ProcessError(TLF("No destination edge for %.", description));
1208 }
1209}
1210
1211
1212void
1214 bool ok = true;
1215 const char* const id = myVehicleParameter->id.c_str();
1216 assert(!attrs.hasAttribute(SUMO_ATTR_EDGES));
1217 const ROEdge* from = nullptr;
1218 const ROEdge* to = nullptr;
1219 parseFromViaTo(SUMO_TAG_PERSON, attrs, ok);
1223 if (ok) {
1224 from = myActiveRoute.front();
1225 }
1226 } else if (myActivePlan->empty()) {
1227 throw ProcessError(TLF("Start edge not defined for person '%'.", myVehicleParameter->id));
1228 } else {
1229 from = myActivePlan->back()->getDestination();
1230 }
1233 to = myActiveRoute.back();
1234 } // else, to may also be derived from stopping place
1235
1236 const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, id, ok, -1);
1237 if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1238 throw ProcessError(TLF("Non-positive walking duration for '%'.", myVehicleParameter->id));
1239 }
1240
1241 double departPos = 0;
1242 double arrivalPos = std::numeric_limits<double>::infinity();
1243 std::string busStopID;
1244 const ROPerson::PlanItem* const lastStage = myActivePlan->empty() ? nullptr : myActivePlan->back();
1245 parseWalkPositions(attrs, myVehicleParameter->id, from, to, departPos, arrivalPos, busStopID, lastStage, ok);
1246
1247 const std::string modes = attrs.getOpt<std::string>(SUMO_ATTR_MODES, id, ok, "");
1248 const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, id, ok, "");
1249 SVCPermissions modeSet = 0;
1250 for (StringTokenizer st(modes); st.hasNext();) {
1251 const std::string mode = st.next();
1252 if (mode == "car") {
1253 modeSet |= SVC_PASSENGER;
1254 } else if (mode == "taxi") {
1255 modeSet |= SVC_TAXI;
1256 } else if (mode == "bicycle") {
1257 modeSet |= SVC_BICYCLE;
1258 } else if (mode == "public") {
1259 modeSet |= SVC_BUS;
1260 } else {
1261 throw InvalidArgument("Unknown person mode '" + mode + "'.");
1262 }
1263 }
1264 const std::string types = attrs.getOpt<std::string>(SUMO_ATTR_VTYPES, id, ok, "");
1265 double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, id, ok, OptionsCont::getOptions().getFloat("persontrip.walkfactor"));
1266 if (ok) {
1267 const std::string originStopID = myActivePlan->empty() ? "" : myActivePlan->back()->getStopDest();
1268 ROPerson::addTrip(*myActivePlan, myVehicleParameter->id, from, to, modeSet, types,
1269 departPos, originStopID, arrivalPos, busStopID, walkFactor, group);
1270 myParamStack.push_back(myActivePlan->back());
1271 }
1272}
1273
1274
1275void
1277 // parse walks from->to as person trips
1279 // XXX allow --repair?
1280 bool ok = true;
1281 if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
1282 const std::string routeID = attrs.get<std::string>(SUMO_ATTR_ROUTE, myVehicleParameter->id.c_str(), ok);
1283 RORouteDef* routeDef = myNet.getRouteDef(routeID);
1284 const std::shared_ptr<const RORoute> route = routeDef != nullptr ? routeDef->getFirstRoute() : nullptr;
1285 if (route == nullptr) {
1286 throw ProcessError("The route '" + routeID + "' for walk of person '" + myVehicleParameter->id + "' is not known.");
1287 }
1288 myActiveRoute = route->getEdgeVector();
1289 } else {
1290 myActiveRoute.clear();
1291 parseEdges(attrs.get<std::string>(SUMO_ATTR_EDGES, myVehicleParameter->id.c_str(), ok), myActiveRoute, " walk for person '" + myVehicleParameter->id + "'", ok);
1292 }
1293 const char* const objId = myVehicleParameter->id.c_str();
1294 const double duration = attrs.getOpt<double>(SUMO_ATTR_DURATION, objId, ok, -1);
1295 if (attrs.hasAttribute(SUMO_ATTR_DURATION) && duration <= 0) {
1296 throw ProcessError(TLF("Non-positive walking duration for '%'.", myVehicleParameter->id));
1297 }
1298 const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, objId, ok, -1.);
1299 if (attrs.hasAttribute(SUMO_ATTR_SPEED) && speed <= 0) {
1300 throw ProcessError(TLF("Non-positive walking speed for '%'.", myVehicleParameter->id));
1301 }
1302 double departPos = 0.;
1303 double arrivalPos = std::numeric_limits<double>::infinity();
1304 if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
1305 WRITE_WARNING(TL("The attribute departPos is no longer supported for walks, please use the person attribute, the arrivalPos of the previous step or explicit stops."));
1306 }
1308 arrivalPos = SUMOVehicleParserHelper::parseWalkPos(SUMO_ATTR_ARRIVALPOS, myHardFail, objId, myActiveRoute.back()->getLength(), attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, objId, ok));
1309 }
1310 std::string stoppingPlaceID;
1311 const std::string errorSuffix = " for walk of person '" + myVehicleParameter->id + "'";
1312 retrieveStoppingPlace(attrs, errorSuffix, stoppingPlaceID);
1313 if (ok) {
1314 ROPerson::addWalk(*myActivePlan, myActiveRoute, duration, speed, departPos, arrivalPos, stoppingPlaceID);
1315 myParamStack.push_back(myActivePlan->back());
1316 }
1317 } else {
1318 addPersonTrip(attrs);
1319 }
1320}
1321
1322
1323void
1325 for (const auto& edgeItem : myNet.getEdgeMap()) {
1326 for (ROLane* lane : edgeItem.second->getLanes()) {
1327 Boundary b = lane->getShape().getBoxBoundary();
1328 const float cmin[2] = {(float) b.xmin(), (float) b.ymin()};
1329 const float cmax[2] = {(float) b.xmax(), (float) b.ymax()};
1330 tree->Insert(cmin, cmax, lane);
1331 }
1332 }
1333}
1334
1335
1336ROEdge*
1337RORouteHandler::retrieveEdge(const std::string& id) {
1338 return myNet.getEdge(id);
1339}
1340
1341
1342const SUMOVTypeParameter*
1343RORouteHandler::getVTypeParameter(const std::string& refid) {
1344 if (refid == "") {
1345 return nullptr;
1346 }
1347 if (!myNet.knowsVType(refid)) {
1348 myErrorOutput->inform(TLF("Unknown vehicle type '%'.", refid));
1349 return nullptr;
1350 }
1351 return myNet.getVehicleTypeSecure(refid);
1352}
1353
1354
1355bool
1357 if (!myUnsortedInput) {
1359 }
1360 return true;
1361}
1362
1363
1364/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define JUNCTION_TAZ_MISSING_HELP
Definition MapMatcher.h:30
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
std::vector< const ROEdge * > ConstROEdgeVector
Definition ROEdge.h:57
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
Definition SUMOTime.cpp:46
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define TIME2STEPS(x)
Definition SUMOTime.h:60
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
const double DEFAULT_VEH_PROB
const std::string DEFAULT_PEDTYPE_ID
const std::string DEFAULT_VTYPE_ID
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 std::string LINE_ANY
const long long int VEHPARS_TO_TAZ_SET
const long long int VEHPARS_FROM_TAZ_SET
const int STOP_END_SET
@ GIVEN
The time is given.
@ TRIGGERED
The departure is person triggered.
SumoXMLTag
Numbers representing SUMO-XML - element names.
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_TAG_TRANSHIP
@ SUMO_TAG_CONTAINER_STOP
A container stop.
@ SUMO_TAG_CONTAINERFLOW
@ SUMO_TAG_BUS_STOP
A bus stop.
@ SUMO_TAG_STOP
stop for vehicles
@ SUMO_TAG_FLOW
a flow definition using from and to edges or a route
@ SUMO_TAG_PARKING_AREA
A parking area.
@ SUMO_TAG_TRANSPORT
@ SUMO_TAG_CONTAINER
@ SUMO_TAG_RIDE
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_TAG_PARAM
parameter associated to a certain key
@ 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_LON
@ SUMO_ATTR_REFID
@ SUMO_ATTR_FROM_JUNCTION
@ SUMO_ATTR_VIALONLAT
@ SUMO_ATTR_SPEED
@ SUMO_ATTR_VIA
@ SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_PARKING_AREA
@ SUMO_ATTR_VIAXY
@ SUMO_ATTR_Y
@ SUMO_ATTR_EDGE
@ SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_TRAIN_STOP
@ SUMO_ATTR_ENDPOS
@ SUMO_ATTR_TO_JUNCTION
@ SUMO_ATTR_X
@ SUMO_ATTR_ARRIVALPOS
@ SUMO_ATTR_PROBS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_TOLONLAT
@ SUMO_ATTR_CHARGING_STATION
@ SUMO_ATTR_ROUTES
@ SUMO_ATTR_MODES
@ SUMO_ATTR_VTYPES
@ SUMO_ATTR_OVERHEAD_WIRE_SEGMENT
@ 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_LAT
@ 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
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:127
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:115
PositionVector getShape(const bool closeShape) const
get position vector (shape) based on this boundary
Definition Boundary.cpp:444
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:133
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:121
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.
Provides utility functions for matching locations to edges (during route parsing)
Definition MapMatcher.h:45
void parseGeoEdges(const PositionVector &positions, bool geo, SUMOVehicleClass vClass, std::vector< const ROEdge * > &into, const std::string &rid, bool isFrom, bool &ok, bool forceEdge=false)
Definition MapMatcher.h:48
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
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:61
void Insert(const float a_min[2], const float a_max[2], Named *const &a_data)
Insert entry.
Definition NamedRTree.h:79
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 exists(const std::string &name) const
Returns the information whether the named option is known.
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.
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.
An upper class for objects with additional parameters.
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
A list of positions.
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
A basic edge for routing applications.
Definition ROEdge.h:73
const ROEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition ROEdge.cpp:292
bool isInternal() const
return whether this edge is an internal edge
Definition ROEdge.h:160
int getNumSuccessors() const
Returns the number of edges this edge is connected to.
Definition ROEdge.cpp:274
const ROEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition ROEdge.cpp:389
int getNumPredecessors() const
Returns the number of edges connected to this edge.
Definition ROEdge.cpp:283
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition ROEdge.h:558
double getLength() const
Returns the length of the edge.
Definition ROEdge.h:225
A single lane the router may use.
Definition ROLane.h:48
The router's network representation.
Definition RONet.h:63
bool knowsVType(const std::string &id) const
returns whether a vehicle type or distribution with the given id was already loaded
Definition RONet.cpp:540
SUMOVTypeParameter * getVehicleTypeSecure(const std::string &id)
Retrieves the named vehicle type.
Definition RONet.cpp:410
const RandomDistributor< SUMOVTypeParameter * > * getVTypeDistribution(const std::string &id)
Retrieves the named vehicle type distribution.
Definition RONet.h:302
bool addRouteDef(RORouteDef *def)
Definition RONet.cpp:335
bool knowsVehicle(const std::string &id) const
returns whether a vehicle with the given id was already loaded
Definition RONet.cpp:534
virtual bool addVehicle(const std::string &id, ROVehicle *veh)
Definition RONet.cpp:512
SUMOTime getDeparture(const std::string &vehID) const
returns departure time for the given vehicle id
Definition RONet.cpp:546
const SUMOVehicleParameter::Stop * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Retrieves a stopping place from the network.
Definition RONet.h:238
void addContainer(const SUMOTime depart, const std::string desc)
Definition RONet.cpp:591
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition RONet.h:179
bool addPerson(ROPerson *person)
Definition RONet.cpp:579
RORouteDef * getRouteDef(const std::string &name) const
Returns the named route definition.
Definition RONet.h:340
virtual bool addVehicleType(SUMOVTypeParameter *type)
Adds a read vehicle type definition to the network.
Definition RONet.cpp:488
bool addVTypeDistribution(const std::string &id, RandomDistributor< SUMOVTypeParameter * > *vehTypeDistribution)
Adds a vehicle type distribution.
Definition RONet.cpp:501
const NamedObjectCont< ROEdge * > & getEdgeMap() const
Definition RONet.h:447
bool addFlow(SUMOVehicleParameter *flow, const bool randomize)
Definition RONet.cpp:557
Every person has a plan comprising of multiple planItems.
Definition ROPerson.h:83
virtual double getDestinationPos() const =0
A person as used by router.
Definition ROPerson.h:50
static void addTrip(std::vector< PlanItem * > &plan, const std::string &id, const ROEdge *const from, const ROEdge *const to, const SVCPermissions modeSet, const std::string &vTypes, const double departPos, const std::string &stopOrigin, const double arrivalPos, const std::string &busStop, double walkFactor, const std::string &group)
Definition ROPerson.cpp:62
static void addStop(std::vector< PlanItem * > &plan, const SUMOVehicleParameter::Stop &stopPar, const ROEdge *const stopEdge)
Definition ROPerson.cpp:134
static void addRide(std::vector< PlanItem * > &plan, 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:117
static void addWalk(std::vector< PlanItem * > &plan, const ConstROEdgeVector &edges, const double duration, const double speed, const double departPos, const double arrivalPos, const std::string &busStop)
Definition ROPerson.cpp:125
std::vector< PlanItem * > & getPlan()
Definition ROPerson.h:440
Base class for a vehicle's route definition.
Definition RORouteDef.h:54
const ROEdge * getOrigin() const
double getOverallProb() const
Returns the sum of the probablities of the contained routes.
std::shared_ptr< const RORoute > getFirstRoute() const
Definition RORouteDef.h:108
void addAlternativeDef(const RORouteDef *alternative)
Adds an alternative loaded from the file.
void addLoadedAlternative(std::shared_ptr< RORoute > alternative)
Adds a single alternative loaded from the file An alternative may also be generated during DUA.
Definition RORouteDef.h:71
const ROEdge * getDestination() const
RORouteDef * copy(const std::string &id, const SUMOTime stopOffset) const
Returns a deep copy of the route definition.
const SUMOVTypeParameter * getVTypeParameter(const std::string &refid) override
void openVehicleTypeDistribution(const SUMOSAXAttributes &attrs) override
opens a type distribution for reading
const SUMOVehicleParameter::Stop * retrieveStoppingPlace(const SUMOSAXAttributes &attrs, const std::string &errorSuffix, std::string &id, const SUMOVehicleParameter::Stop *stopParam=nullptr)
retrieve stopping place element
bool myUseTaz
cached options
void addTransport(const SUMOSAXAttributes &attrs) override
Processing of a transport.
void deleteActivePlanAndVehicleParameter()
void openRoute(const SUMOSAXAttributes &attrs) override
opens a route for reading
std::string myCurrentVTypeDistributionID
The id of the currently parsed vehicle type distribution.
void addFlowPerson(const std::string &typeID, SUMOTime depart, const std::string &baseID, int i)
Processing of a person from a personFlow.
void closeContainerFlow() override
Ends the processing of a containerFlow.
RORouteHandler(RONet &net, const std::string &file, const bool tryRepair, const bool emptyDestinationsAllowed, const bool ignoreErrors, const bool checkSchema)
standard constructor
void parseEdges(const std::string &desc, ConstROEdgeVector &into, const std::string &rid, bool &ok)
Parse edges from strings.
RONet & myNet
The current route.
void addRide(const SUMOSAXAttributes &attrs) override
Processing of a ride.
ConstROEdgeVector myActiveRoute
The current route.
void closeRouteDistribution() override
closes (ends) the building of a distribution
void addTranship(const SUMOSAXAttributes &attrs) override
Processing of a tranship.
void closeContainer() override
Ends the processing of a container.
std::vector< ROPerson::PlanItem * > * myActivePlan
The plan of the current person.
const bool myWriteFlows
whether flows shall not be expanded
const bool myTryRepair
Information whether routes shall be repaired.
bool checkLastDepart() override
Checks whether the route file is sorted by departure time if needed.
OutputDevice_String * myActiveContainerPlan
The plan of the current container.
void closeVehicle() override
Ends the processing of a vehicle.
SUMOTime myActiveRoutePeriod
const SUMOTime myBegin
The begin time.
void closeRoute(const bool mayBeDisconnected=false) override
closes (ends) the building of a route.
Parameterised * addStop(const SUMOSAXAttributes &attrs) override
Processing of a stop.
RandomDistributor< SUMOVTypeParameter * > * myCurrentVTypeDistribution
The currently parsed distribution of vehicle types (probability->vehicle type)
void closePersonFlow() override
Ends the processing of a personFlow.
void openRouteDistribution(const SUMOSAXAttributes &attrs) override
opens a route distribution for reading
int myActiveContainerPlanSize
The number of stages in myActiveContainerPlan.
const bool myKeepVTypeDist
whether to keep the vtype distribution in output
void openTrip(const SUMOSAXAttributes &attrs) override
opens a trip for reading
const bool myUnsortedInput
whether input is read all at once (no sorting check is necessary)
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.
int myActiveRouteRepeat
number of repetitions of the active route
void closeFlow() override
Ends the processing of a flow.
ROEdge * retrieveEdge(const std::string &id) override
void addPersonTrip(const SUMOSAXAttributes &attrs) override
add a routing request for a walking or intermodal person
void closePerson() override
Ends the processing of a person.
~RORouteHandler() override
standard destructor
RORouteDef * myCurrentAlternatives
The currently parsed route alternatives.
void myStartElement(int element, const SUMOSAXAttributes &attrs) override
Called on the opening of a tag;.
void addWalk(const SUMOSAXAttributes &attrs) override
add a fully specified walk
void initLaneTree(NamedRTree *tree) override
void openRouteFlow(const SUMOSAXAttributes &attrs) override
opens a route flow for reading
void closeTrip() override
Ends the processing of a trip.
void openFlow(const SUMOSAXAttributes &attrs) override
opens a flow for reading
void closeVType() override
Ends the processing of a vehicle type.
void closeVehicleTypeDistribution() override
closes (ends) the building of a distribution
void parseFromViaTo(SumoXMLTag tag, const SUMOSAXAttributes &attrs, bool &ok)
Called for parsing from and to and the corresponding taz attributes.
A vehicle as used by router.
Definition ROVehicle.h:51
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Represents a generic random distribution.
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.
const std::vector< T > & getVals() const
Returns the members of the distribution.
void clear()
Clears the distribution.
const std::vector< double > & getProbs() const
Returns the probabilities assigned to the members of 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::set< std::string > mySkippedVehicles
IDs of skipped vehicles to suppress errors for the triggered transportables within.
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.
std::vector< Parameterised * > myParamStack
The stack of currently parsed parameterised objects.
SUMOVehicleParameter * myVehicleParameter
Parameter of the current vehicle, trip, person, container or flow.
const bool myHardFail
flag to enable or disable hard fails
StopParVector myActiveRouteStops
List of the stops on the parsed route.
std::string myCurrentVTypeRef
if the currently parsed vType is only a reference to an existing type, store the refId
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.
double myCurrentVTypeProbability
if the currently parsed vType is only a reference, store the probability here
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.
virtual bool checkLastDepart()
Checks whether the route file is sorted by departure time if needed.
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue=T(), bool report=true) const
Tries to read given attribute assuming it is an int.
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.
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.
std::string chargingStation
(Optional) charging station if one is assigned to the stop
std::string overheadWireSegment
(Optional) overhead line segment if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
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.
void incrementFlow(double scale, SumoRNG *rng=nullptr)
increment flow
std::string vtypeid
The vehicle's type id.
SUMOTime repetitionOffset
The time offset between vehicle reinsertions.
long long int repetitionsDone
The number of times the vehicle was already inserted.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
SUMOTime repetitionTotalOffset
The offset between depart and the time for the next vehicle insertions.
long long int parametersSet
Information for the router which parameter were set, TraCI may modify this (when changing color)
SUMOTime repetitionEnd
The time at which the flow ends (only needed when using repetitionProbability)
bool wasSet(long long int what) const
Returns whether the given parameter was set.
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.
std::string toTaz
The vehicle's destination zone (district)
DepartDefinition departProcedure
Information how the vehicle shall choose the depart time.
std::string fromTaz
The vehicle's origin zone (district)
static double parseWalkPos(SumoXMLAttr attr, const bool hardFail, const std::string &id, double maxPos, const std::string &val, SumoRNG *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
std::string front()
returns the first substring without moving the iterator
int size() const
returns the number of existing substrings
std::string get(int pos) const
returns the item at the given position
bool hasNext()
returns the information whether further substrings exist
std::string next()
returns the next substring when it exists. Otherwise the behaviour is undefined
static double toDoubleSecure(const std::string &sData, const double def)
converts a string into the integer value described by it