Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/vehicle/SUMORouteHandler.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file SUMORouteHandler.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Sascha Krieg
18
/// @author Michael Behrisch
19
/// @date Mon, 9 Jul 2001
20
///
21
// Parser for routes during their loading
22
/****************************************************************************/
23
#include <config.h>
24
25
#include <utils/common/MsgHandler.h>
26
#include <utils/common/FileHelpers.h>
27
#include <utils/options/OptionsCont.h>
28
#include <utils/vehicle/SUMOVTypeParameter.h>
29
#include <utils/vehicle/SUMOVehicleParserHelper.h>
30
#include <utils/xml/XMLSubSys.h>
31
32
#include "SUMORouteHandler.h"
33
34
35
// ===========================================================================
36
// method definitions
37
// ===========================================================================
38
39
SUMORouteHandler::SUMORouteHandler(const std::string& file, const std::string& expectedRoot, const bool hardFail) :
40
SUMOSAXHandler(file, expectedRoot),
41
myHardFail(hardFail),
42
myVehicleParameter(nullptr),
43
myLastDepart(-1),
44
myActiveRouteColor(nullptr),
45
myCurrentCosts(0.),
46
myCurrentVType(nullptr),
47
myBeginDefault(OptionsCont::getOptions().exists("begin") ? string2time(OptionsCont::getOptions().getString("begin")) : 0),
48
myEndDefault(OptionsCont::getOptions().exists("end") ? string2time(OptionsCont::getOptions().getString("end")) : -1),
49
myFirstDepart(-1),
50
myInsertStopEdgesAt(-1),
51
myAllowInternalRoutes(false) {
52
}
53
54
55
SUMORouteHandler::~SUMORouteHandler() {
56
delete myVehicleParameter;
57
delete myCurrentVType;
58
}
59
60
61
bool
62
SUMORouteHandler::checkLastDepart() {
63
if (myVehicleParameter->departProcedure == DepartDefinition::GIVEN) {
64
if (myVehicleParameter->depart < myLastDepart) {
65
WRITE_WARNINGF(TL("Route file should be sorted by departure time, ignoring '%'!"), myVehicleParameter->id);
66
return false;
67
}
68
}
69
return true;
70
}
71
72
73
void
74
SUMORouteHandler::registerLastDepart() {
75
// register only non public transport to parse all public transport lines in advance
76
if (myVehicleParameter && myVehicleParameter->line == "" && myVehicleParameter->departProcedure == DepartDefinition::GIVEN) {
77
myLastDepart = myVehicleParameter->depart;
78
if (myFirstDepart == -1) {
79
myFirstDepart = myLastDepart;
80
}
81
}
82
// else: we don't know when this vehicle will depart. keep the previous known depart time
83
}
84
85
86
void
87
SUMORouteHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) {
88
myElementStack.push_back(element);
89
switch (element) {
90
case SUMO_TAG_VEHICLE:
91
case SUMO_TAG_PERSON:
92
case SUMO_TAG_CONTAINER:
93
// if myVehicleParameter is nullptr this will do nothing
94
delete myVehicleParameter;
95
// we set to nullptr to have a consistent state if the parsing fails
96
myVehicleParameter = nullptr;
97
myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(element, attrs, myHardFail, false, false, myAllowInternalRoutes);
98
myParamStack.push_back(myVehicleParameter);
99
if (element != SUMO_TAG_VEHICLE) {
100
addTransportable(attrs, element == SUMO_TAG_PERSON);
101
}
102
break;
103
case SUMO_TAG_FLOW:
104
// delete if myVehicleParameter isn't null
105
if (myVehicleParameter) {
106
delete myVehicleParameter;
107
myVehicleParameter = nullptr;
108
}
109
// parse vehicle parameters
110
// might be called to parse vehicles from additional file in the
111
// context of quickReload. In this case, rerouter flows must be ignored
112
if (myElementStack.size() == 1 || myElementStack[myElementStack.size() - 2] != SUMO_TAG_CALIBRATOR) {
113
myVehicleParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, myHardFail, true, myBeginDefault, myEndDefault, myAllowInternalRoutes);
114
}
115
// check if myVehicleParameter was successfully created
116
if (myVehicleParameter) {
117
// check tag
118
if (myVehicleParameter->routeid.empty()) {
119
// open a route flow (It could be a flow with embedded route)
120
openFlow(attrs);
121
} else {
122
// open a route flow
123
openRouteFlow(attrs);
124
}
125
myParamStack.push_back(myVehicleParameter);
126
}
127
break;
128
case SUMO_TAG_PERSONFLOW:
129
case SUMO_TAG_CONTAINERFLOW:
130
// delete if myVehicleParameter isn't null
131
if (myVehicleParameter) {
132
delete myVehicleParameter;
133
myVehicleParameter = nullptr;
134
}
135
// create a new flow
136
myVehicleParameter = SUMOVehicleParserHelper::parseFlowAttributes((SumoXMLTag)element, attrs, myHardFail, true, myBeginDefault, myEndDefault, myAllowInternalRoutes);
137
myParamStack.push_back(myVehicleParameter);
138
break;
139
case SUMO_TAG_VTYPE:
140
// delete if myCurrentVType isn't null
141
if (myCurrentVType != nullptr) {
142
delete myCurrentVType;
143
myCurrentVType = nullptr;
144
}
145
// create a new vType
146
myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs, myHardFail, getFileName());
147
myParamStack.push_back(myCurrentVType);
148
break;
149
case SUMO_TAG_VTYPE_DISTRIBUTION:
150
openVehicleTypeDistribution(attrs);
151
break;
152
case SUMO_TAG_ROUTE:
153
openRoute(attrs);
154
break;
155
case SUMO_TAG_ROUTE_DISTRIBUTION:
156
openRouteDistribution(attrs);
157
break;
158
case SUMO_TAG_STOP:
159
myParamStack.push_back(addStop(attrs));
160
break;
161
case SUMO_TAG_TRIP: {
162
// delete if myVehicleParameter isn't null
163
if (myVehicleParameter) {
164
delete myVehicleParameter;
165
myVehicleParameter = nullptr;
166
}
167
// parse vehicle parameters
168
myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(element, attrs, myHardFail, false, false, myAllowInternalRoutes);
169
// check if myVehicleParameter was successfully created
170
if (myVehicleParameter) {
171
myVehicleParameter->parametersSet |= VEHPARS_FORCE_REROUTE;
172
myActiveRouteID = "!" + myVehicleParameter->id;
173
// open trip
174
openTrip(attrs);
175
myParamStack.push_back(myVehicleParameter);
176
}
177
break;
178
}
179
case SUMO_TAG_PERSONTRIP:
180
addPersonTrip(attrs);
181
break;
182
case SUMO_TAG_WALK:
183
addWalk(attrs);
184
break;
185
case SUMO_TAG_INTERVAL: {
186
bool ok;
187
myBeginDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, ok);
188
myEndDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, ok);
189
break;
190
}
191
case SUMO_TAG_RIDE:
192
addRide(attrs);
193
break;
194
case SUMO_TAG_TRANSPORT:
195
addTransport(attrs);
196
break;
197
case SUMO_TAG_TRANSHIP:
198
addTranship(attrs);
199
break;
200
case SUMO_TAG_PARAM:
201
addParam(attrs);
202
break;
203
default:
204
// parse embedded car following model information
205
if (myCurrentVType != nullptr) {
206
WRITE_WARNINGF(TL("Defining car-following parameters in a nested element is deprecated in vType '%', use attributes instead!"), myCurrentVType->id);
207
if (!SUMOVehicleParserHelper::parseCFMParams(myCurrentVType, (SumoXMLTag)element, attrs, true)) {
208
if (myHardFail) {
209
throw ProcessError(TL("Invalid parsing embedded VType"));
210
} else {
211
WRITE_ERROR(TL("Invalid parsing embedded VType"));
212
}
213
}
214
}
215
break;
216
}
217
}
218
219
220
void
221
SUMORouteHandler::myEndElement(int element) {
222
switch (element) {
223
case SUMO_TAG_STOP:
224
myParamStack.pop_back();
225
break;
226
case SUMO_TAG_ROUTE:
227
closeRoute();
228
break;
229
case SUMO_TAG_VTYPE:
230
closeVType();
231
delete myCurrentVType;
232
myCurrentVType = nullptr;
233
myParamStack.pop_back();
234
break;
235
case SUMO_TAG_PERSON:
236
closePerson();
237
delete myVehicleParameter;
238
myVehicleParameter = nullptr;
239
myParamStack.pop_back();
240
break;
241
case SUMO_TAG_PERSONFLOW:
242
closePersonFlow();
243
delete myVehicleParameter;
244
myVehicleParameter = nullptr;
245
myParamStack.pop_back();
246
break;
247
case SUMO_TAG_CONTAINER:
248
closeContainer();
249
delete myVehicleParameter;
250
myVehicleParameter = nullptr;
251
myParamStack.pop_back();
252
break;
253
case SUMO_TAG_CONTAINERFLOW:
254
closeContainerFlow();
255
delete myVehicleParameter;
256
myVehicleParameter = nullptr;
257
myParamStack.pop_back();
258
break;
259
case SUMO_TAG_VEHICLE:
260
if (myVehicleParameter == nullptr) {
261
break;
262
}
263
if (myVehicleParameter->repetitionNumber > 0) {
264
myVehicleParameter->repetitionNumber++; // for backwards compatibility
265
// it is a flow, thus no break here
266
FALLTHROUGH;
267
} else {
268
closeVehicle();
269
delete myVehicleParameter;
270
myVehicleParameter = nullptr;
271
myParamStack.pop_back();
272
break;
273
}
274
case SUMO_TAG_FLOW:
275
if (myVehicleParameter) {
276
closeFlow();
277
delete myVehicleParameter;
278
myParamStack.pop_back();
279
}
280
myVehicleParameter = nullptr;
281
myInsertStopEdgesAt = -1;
282
break;
283
case SUMO_TAG_TRIP:
284
closeTrip();
285
delete myVehicleParameter;
286
myVehicleParameter = nullptr;
287
myParamStack.pop_back();
288
myInsertStopEdgesAt = -1;
289
break;
290
case SUMO_TAG_VTYPE_DISTRIBUTION:
291
closeVehicleTypeDistribution();
292
break;
293
case SUMO_TAG_ROUTE_DISTRIBUTION:
294
closeRouteDistribution();
295
break;
296
case SUMO_TAG_PERSONTRIP:
297
case SUMO_TAG_RIDE:
298
case SUMO_TAG_TRANSPORT:
299
case SUMO_TAG_TRANSHIP:
300
case SUMO_TAG_WALK:
301
if (myParamStack.size() == 2) {
302
myParamStack.pop_back();
303
}
304
break;
305
case SUMO_TAG_INTERVAL:
306
myBeginDefault = string2time(OptionsCont::getOptions().getString("begin"));
307
myEndDefault = string2time(OptionsCont::getOptions().getString("end"));
308
break;
309
default:
310
break;
311
}
312
myElementStack.pop_back();
313
}
314
315
316
SUMORouteHandler::StopPos
317
SUMORouteHandler::checkStopPos(double& startPos, double& endPos, const double laneLength, const double minLength, const bool friendlyPos) {
318
if (minLength > laneLength) {
319
return STOPPOS_INVALID_LANELENGTH;
320
}
321
if (startPos < 0) {
322
startPos += laneLength;
323
}
324
if (endPos < 0) {
325
endPos += laneLength;
326
}
327
if ((endPos < minLength) || (endPos > laneLength)) {
328
if (!friendlyPos) {
329
return STOPPOS_INVALID_ENDPOS;
330
}
331
if (endPos < minLength) {
332
endPos = minLength;
333
}
334
if (endPos > laneLength) {
335
endPos = laneLength;
336
}
337
}
338
if ((startPos < 0) || (startPos > (endPos - minLength))) {
339
if (!friendlyPos) {
340
return STOPPOS_INVALID_STARTPOS;
341
}
342
if (startPos < 0) {
343
startPos = 0;
344
}
345
if (startPos > (endPos - minLength)) {
346
startPos = endPos - minLength;
347
}
348
}
349
return STOPPOS_VALID;
350
}
351
352
353
bool
354
SUMORouteHandler::isStopPosValid(const double startPos, const double endPos, const double laneLength, const double minLength, const bool friendlyPos) {
355
// declare dummy start and end positions
356
double dummyStartPos = startPos;
357
double dummyEndPos = endPos;
358
// return checkStopPos
359
return (checkStopPos(dummyStartPos, dummyEndPos, laneLength, minLength, friendlyPos) == STOPPOS_VALID);
360
}
361
362
363
SUMOTime
364
SUMORouteHandler::getFirstDepart() const {
365
return myFirstDepart;
366
}
367
368
369
SUMOTime
370
SUMORouteHandler::getLastDepart() const {
371
return myLastDepart;
372
}
373
374
375
void
376
SUMORouteHandler::addParam(const SUMOSAXAttributes& attrs) {
377
bool ok = true;
378
const std::string key = attrs.get<std::string>(SUMO_ATTR_KEY, nullptr, ok);
379
// only continue if key isn't empty
380
if (ok && (key.size() > 0)) {
381
// circumventing empty string test
382
std::string val = attrs.hasAttribute(SUMO_ATTR_VALUE) ? attrs.getString(SUMO_ATTR_VALUE) : "";
383
// check special params that must be interpreted as relative paths
384
if ((myVehicleParameter != nullptr || myCurrentVType != nullptr)
385
&& (key == "device.toc.file" || key == "device.ssm.file")) {
386
val = FileHelpers::checkForRelativity(val, getFileName());
387
}
388
// add parameter in current created element
389
if (!myParamStack.empty()) {
390
myParamStack.back()->setParameter(key, val);
391
}
392
}
393
}
394
395
396
bool
397
SUMORouteHandler::parseStop(SUMOVehicleParameter::Stop& stop, const SUMOSAXAttributes& attrs, std::string errorSuffix, MsgHandler* const errorOutput) {
398
stop.parametersSet = 0;
399
if (attrs.hasAttribute(SUMO_ATTR_ARRIVAL)) {
400
stop.parametersSet |= STOP_ARRIVAL_SET;
401
}
402
if (attrs.hasAttribute(SUMO_ATTR_DURATION)) {
403
stop.parametersSet |= STOP_DURATION_SET;
404
}
405
if (attrs.hasAttribute(SUMO_ATTR_UNTIL)) {
406
stop.parametersSet |= STOP_UNTIL_SET;
407
}
408
if (attrs.hasAttribute(SUMO_ATTR_STARTED)) {
409
stop.parametersSet |= STOP_STARTED_SET;
410
}
411
if (attrs.hasAttribute(SUMO_ATTR_ENDED)) {
412
stop.parametersSet |= STOP_ENDED_SET;
413
}
414
if (attrs.hasAttribute(SUMO_ATTR_EXTENSION)) {
415
stop.parametersSet |= STOP_EXTENSION_SET;
416
}
417
if (attrs.hasAttribute(SUMO_ATTR_ENDPOS)) {
418
stop.parametersSet |= STOP_END_SET;
419
}
420
if (attrs.hasAttribute(SUMO_ATTR_STARTPOS)) {
421
stop.parametersSet |= STOP_START_SET;
422
}
423
if (attrs.hasAttribute(SUMO_ATTR_POSITION_LAT)) {
424
stop.parametersSet |= STOP_POSLAT_SET;
425
}
426
if (attrs.hasAttribute(SUMO_ATTR_TRIGGERED)) {
427
stop.parametersSet |= STOP_TRIGGER_SET;
428
}
429
// legacy attribute
430
if (attrs.hasAttribute(SUMO_ATTR_CONTAINER_TRIGGERED)) {
431
stop.parametersSet |= STOP_TRIGGER_SET;
432
}
433
if (attrs.hasAttribute(SUMO_ATTR_PARKING)) {
434
stop.parametersSet |= STOP_PARKING_SET;
435
}
436
if (attrs.hasAttribute(SUMO_ATTR_EXPECTED)) {
437
stop.parametersSet |= STOP_EXPECTED_SET;
438
}
439
if (attrs.hasAttribute(SUMO_ATTR_PERMITTED)) {
440
stop.parametersSet |= STOP_PERMITTED_SET;
441
}
442
if (attrs.hasAttribute(SUMO_ATTR_EXPECTED_CONTAINERS)) {
443
stop.parametersSet |= STOP_EXPECTED_CONTAINERS_SET;
444
}
445
if (attrs.hasAttribute(SUMO_ATTR_TRIP_ID)) {
446
stop.parametersSet |= STOP_TRIP_ID_SET;
447
}
448
if (attrs.hasAttribute(SUMO_ATTR_SPLIT)) {
449
stop.parametersSet |= STOP_SPLIT_SET;
450
}
451
if (attrs.hasAttribute(SUMO_ATTR_JOIN)) {
452
stop.parametersSet |= STOP_JOIN_SET;
453
}
454
if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
455
stop.parametersSet |= STOP_LINE_SET;
456
}
457
if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
458
stop.parametersSet |= STOP_SPEED_SET;
459
}
460
if (attrs.hasAttribute(SUMO_ATTR_ONDEMAND)) {
461
stop.parametersSet |= STOP_ONDEMAND_SET;
462
}
463
if (attrs.hasAttribute(SUMO_ATTR_PRIORITY)) {
464
stop.parametersSet |= STOP_PRIORITY_SET;
465
}
466
if (attrs.hasAttribute(SUMO_ATTR_JUMP)) {
467
stop.parametersSet |= STOP_JUMP_SET;
468
}
469
if (attrs.hasAttribute(SUMO_ATTR_JUMP_UNTIL)) {
470
stop.parametersSet |= STOP_JUMP_UNTIL_SET;
471
}
472
bool ok = true;
473
stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
474
stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, nullptr, ok, stop.busstop);
475
stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
476
stop.overheadWireSegment = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, nullptr, ok, "");
477
stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
478
stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
479
if (stop.busstop != "") {
480
errorSuffix = " at '" + stop.busstop + "'" + errorSuffix;
481
} else if (stop.chargingStation != "") {
482
errorSuffix = " at '" + stop.chargingStation + "'" + errorSuffix;
483
} else if (stop.overheadWireSegment != "") {
484
errorSuffix = " at '" + stop.overheadWireSegment + "'" + errorSuffix;
485
} else if (stop.containerstop != "") {
486
errorSuffix = " at '" + stop.containerstop + "'" + errorSuffix;
487
} else if (stop.parkingarea != "") {
488
errorSuffix = " at '" + stop.parkingarea + "'" + errorSuffix;
489
} else if (attrs.hasAttribute(SUMO_ATTR_LANE)) {
490
errorSuffix = " on lane '" + attrs.get<std::string>(SUMO_ATTR_LANE, nullptr, ok) + "'" + errorSuffix;
491
} else if (attrs.hasAttribute(SUMO_ATTR_EDGE)) {
492
errorSuffix = " on edge '" + attrs.get<std::string>(SUMO_ATTR_EDGE, nullptr, ok) + "'" + errorSuffix;
493
} else {
494
errorSuffix = " at undefined location" + errorSuffix;
495
}
496
// speed for counting as stopped
497
stop.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, 0);
498
if (stop.speed < 0) {
499
errorOutput->inform(TLF("Speed cannot be negative for stop%.", errorSuffix));
500
return false;
501
}
502
503
// get the standing duration
504
bool expectTrigger = !attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL) && !attrs.hasAttribute(SUMO_ATTR_SPEED);
505
std::vector<std::string> triggers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_TRIGGERED, nullptr, ok);
506
// legacy
507
if (attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, false)) {
508
triggers.push_back(toString(SUMO_TAG_CONTAINER));
509
}
510
SUMOVehicleParameter::parseStopTriggers(triggers, expectTrigger, stop);
511
stop.arrival = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ARRIVAL, nullptr, ok, -1);
512
stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, nullptr, ok, -1);
513
stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, -1);
514
if (!expectTrigger && (!ok || (stop.duration < 0 && stop.until < 0 && stop.speed == 0))) {
515
errorOutput->inform(TLF("Invalid duration or end time is given for a stop%.", errorSuffix));
516
return false;
517
}
518
if (triggers.size() > 0 && stop.speed > 0) {
519
errorOutput->inform(TLF("Triggers and waypoints cannot be combined%.", errorSuffix));
520
return false;
521
}
522
stop.extension = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EXTENSION, nullptr, ok, -1);
523
const bool defaultParking = (stop.triggered || stop.containerTriggered || stop.parkingarea != "");
524
stop.parking = attrs.getOpt<ParkingType>(SUMO_ATTR_PARKING, nullptr, ok, defaultParking ? ParkingType::OFFROAD : ParkingType::ONROAD);
525
if ((stop.parkingarea != "") && (stop.parking == ParkingType::ONROAD)) {
526
WRITE_WARNINGF(TL("Stop at parkingArea overrides attribute 'parking' for stop%."), errorSuffix);
527
stop.parking = ParkingType::OFFROAD;
528
}
529
530
// expected persons
531
const std::vector<std::string>& expected = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED, nullptr, ok);
532
stop.awaitedPersons.insert(expected.begin(), expected.end());
533
if (stop.awaitedPersons.size() > 0) {
534
stop.triggered = true;
535
if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
536
stop.parking = ParkingType::OFFROAD;
537
}
538
}
539
540
// permitted transportables
541
const std::vector<std::string>& permitted = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_PERMITTED, nullptr, ok);
542
stop.permitted.insert(permitted.begin(), permitted.end());
543
544
// expected containers
545
const std::vector<std::string>& expectedContainers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED_CONTAINERS, nullptr, ok);
546
stop.awaitedContainers.insert(expectedContainers.begin(), expectedContainers.end());
547
if (stop.awaitedContainers.size() > 0) {
548
stop.containerTriggered = true;
549
if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
550
stop.parking = ParkingType::OFFROAD;
551
}
552
}
553
// public transport trip id
554
stop.tripId = attrs.getOpt<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok, "");
555
stop.split = attrs.getOpt<std::string>(SUMO_ATTR_SPLIT, nullptr, ok, "");
556
stop.join = attrs.getOpt<std::string>(SUMO_ATTR_JOIN, nullptr, ok, "");
557
stop.line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, nullptr, ok, "");
558
559
const std::string idx = attrs.getOpt<std::string>(SUMO_ATTR_INDEX, nullptr, ok, "end");
560
if (idx == "end") {
561
stop.index = STOP_INDEX_END;
562
} else if (idx == "fit") {
563
stop.index = STOP_INDEX_FIT;
564
} else {
565
stop.index = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
566
if (!ok || stop.index < 0) {
567
errorOutput->inform(TLF("Invalid 'index' for stop%.", errorSuffix));
568
return false;
569
}
570
}
571
stop.started = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STARTED, nullptr, ok, -1);
572
stop.ended = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ENDED, nullptr, ok, -1);
573
stop.posLat = attrs.getOpt<double>(SUMO_ATTR_POSITION_LAT, nullptr, ok, INVALID_DOUBLE);
574
stop.actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, nullptr, ok, "");
575
stop.onDemand = attrs.getOpt<bool>(SUMO_ATTR_ONDEMAND, nullptr, ok, false);
576
stop.priority = attrs.getOpt<double>(SUMO_ATTR_PRIORITY, nullptr, ok, -1);
577
stop.jump = attrs.getOptSUMOTimeReporting(SUMO_ATTR_JUMP, nullptr, ok, -1);
578
stop.jumpUntil = attrs.getOptSUMOTimeReporting(SUMO_ATTR_JUMP_UNTIL, nullptr, ok, -1);
579
stop.collision = attrs.getOpt<bool>(SUMO_ATTR_COLLISION, nullptr, ok, false);
580
return true;
581
}
582
583
584
/****************************************************************************/
585
586