Line data Source code
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 : /****************************************************************************/
14 : /// @file RouteHandler.cpp
15 : /// @author Pablo Alvarez Lopez
16 : /// @date Jun 2021
17 : ///
18 : // The XML-Handler for route elements loading
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <utils/common/FileBucket.h>
23 : #include <utils/common/MsgHandler.h>
24 : #include <utils/common/RGBColor.h>
25 : #include <utils/common/SUMOVehicleClass.h>
26 : #include <utils/options/OptionsCont.h>
27 : #include <utils/shapes/Shape.h>
28 : #include <utils/vehicle/SUMOVehicleParserHelper.h>
29 : #include <utils/xml/NamespaceIDs.h>
30 : #include <utils/xml/SUMOSAXHandler.h>
31 : #include <utils/xml/XMLSubSys.h>
32 :
33 : #include "RouteHandler.h"
34 :
35 :
36 : // ===========================================================================
37 : // method definitions
38 : // ===========================================================================
39 :
40 0 : RouteHandler::RouteHandler(FileBucket* fileBucket, const bool hardFail) :
41 : CommonHandler(fileBucket),
42 0 : myHardFail(hardFail),
43 0 : myFlowBeginDefault(string2time(OptionsCont::getOptions().getString("begin"))),
44 0 : myFlowEndDefault(string2time(OptionsCont::getOptions().getString("end"))) {
45 0 : }
46 :
47 :
48 0 : RouteHandler::~RouteHandler() {}
49 :
50 :
51 : bool
52 0 : RouteHandler::beginParseAttributes(SumoXMLTag tag, const SUMOSAXAttributes& attrs) {
53 : // open SUMOBaseOBject
54 0 : myCommonXMLStructure.openSUMOBaseOBject();
55 : // check tag
56 : try {
57 0 : switch (tag) {
58 : // vTypes
59 0 : case SUMO_TAG_VTYPE:
60 : // continue depeding if we're parsing a vType or a reference
61 0 : if ((myCommonXMLStructure.getSumoBaseObjectRoot()->getTag() == SUMO_TAG_VTYPE_DISTRIBUTION) &&
62 0 : attrs.hasAttribute(SUMO_ATTR_REFID)) {
63 0 : parseVTypeRef(attrs);
64 : } else {
65 0 : parseVType(attrs);
66 : }
67 : break;
68 0 : case SUMO_TAG_VTYPE_DISTRIBUTION:
69 0 : parseVTypeDistribution(attrs);
70 : break;
71 : // routes
72 0 : case SUMO_TAG_ROUTE: {
73 : // continue depeding if we're parsing a basic route, an embedded route, or a distribution ref
74 0 : const auto parentTag = myCommonXMLStructure.getSumoBaseObjectRoot()->getTag();
75 : // this is temporal, until #16476
76 0 : if (parentTag != SUMO_TAG_ERROR) {
77 0 : if ((parentTag == SUMO_TAG_VEHICLE) || (parentTag == SUMO_TAG_FLOW)) {
78 0 : parseRouteEmbedded(attrs);
79 0 : } else if ((parentTag == SUMO_TAG_ROUTE_DISTRIBUTION) && attrs.hasAttribute(SUMO_ATTR_REFID)) {
80 0 : parseRouteRef(attrs);
81 : } else {
82 0 : parseRoute(attrs);
83 : }
84 : }
85 : break;
86 : }
87 0 : case SUMO_TAG_ROUTE_DISTRIBUTION:
88 0 : parseRouteDistribution(attrs);
89 : break;
90 : // vehicles
91 0 : case SUMO_TAG_TRIP:
92 0 : parseTrip(attrs);
93 : break;
94 0 : case SUMO_TAG_VEHICLE:
95 0 : parseVehicle(attrs);
96 : break;
97 : // flows
98 0 : case SUMO_TAG_FLOW:
99 0 : parseFlow(attrs);
100 : break;
101 : // stop
102 0 : case SUMO_TAG_STOP:
103 0 : parseStop(attrs);
104 : break;
105 : // persons
106 0 : case SUMO_TAG_PERSON:
107 0 : parsePerson(attrs);
108 : break;
109 0 : case SUMO_TAG_PERSONFLOW:
110 0 : parsePersonFlow(attrs);
111 : break;
112 : // person plans
113 0 : case SUMO_TAG_PERSONTRIP:
114 0 : parsePersonTrip(attrs);
115 : break;
116 0 : case SUMO_TAG_RIDE:
117 0 : parseRide(attrs);
118 : break;
119 0 : case SUMO_TAG_WALK:
120 0 : parseWalk(attrs);
121 : break;
122 : // container
123 0 : case SUMO_TAG_CONTAINER:
124 0 : parseContainer(attrs);
125 : break;
126 0 : case SUMO_TAG_CONTAINERFLOW:
127 0 : parseContainerFlow(attrs);
128 : break;
129 : // container plans
130 0 : case SUMO_TAG_TRANSPORT:
131 0 : parseTransport(attrs);
132 : break;
133 0 : case SUMO_TAG_TRANSHIP:
134 0 : parseTranship(attrs);
135 : break;
136 : // parameters
137 0 : case SUMO_TAG_PARAM:
138 0 : parseParameters(attrs);
139 : break;
140 : // other
141 0 : case SUMO_TAG_INTERVAL: {
142 0 : parseInterval(attrs);
143 : break;
144 : }
145 0 : default:
146 : // get vehicle type Base object
147 0 : const auto vTypeObject = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject();
148 : // parse embedded car following model information
149 0 : if (vTypeObject && (vTypeObject->getTag() == SUMO_TAG_VTYPE)) {
150 : // nested CFM attributes
151 0 : return parseNestedCFM(tag, attrs, vTypeObject);
152 : } else {
153 : // tag cannot be parsed in routeHandler
154 0 : myCommonXMLStructure.abortSUMOBaseOBject();
155 : return false;
156 : }
157 : }
158 0 : } catch (InvalidArgument& e) {
159 0 : WRITE_ERROR(e.what());
160 0 : }
161 : return true;
162 : }
163 :
164 :
165 : void
166 0 : RouteHandler::endParseAttributes() {
167 : // get last inserted object
168 0 : CommonXMLStructure::SumoBaseObject* obj = myCommonXMLStructure.getCurrentSumoBaseObject();
169 : // check tag
170 0 : if (obj) {
171 : // close SUMOBaseOBject
172 0 : myCommonXMLStructure.closeSUMOBaseOBject();
173 0 : switch (obj->getTag()) {
174 0 : case SUMO_TAG_ROUTE:
175 : // special case, because embedded and distribution routes are created within other elements
176 0 : if (obj->getParentSumoBaseObject() == nullptr) {
177 : // parse object and all their childrens
178 0 : parseSumoBaseObject(obj);
179 : // delete object (and all of their childrens)
180 0 : delete obj;
181 : }
182 : break;
183 0 : case SUMO_TAG_ROUTE_DISTRIBUTION:
184 : // parse object and all their childrens
185 0 : parseSumoBaseObject(obj);
186 : // delete object (and all of their childrens)
187 0 : delete obj;
188 : break;
189 0 : case SUMO_TAG_VTYPE_DISTRIBUTION:
190 : // parse object and all their childrens
191 0 : parseSumoBaseObject(obj);
192 : // delete object (and all of their childrens)
193 0 : delete obj;
194 : break;
195 0 : case SUMO_TAG_VTYPE:
196 : // special case, because embedded and distribution routes are created within other elements
197 0 : if (obj->getParentSumoBaseObject() == nullptr) {
198 : // parse object and all their childrens
199 0 : parseSumoBaseObject(obj);
200 : // delete object (and all of their childrens)
201 0 : delete obj;
202 : }
203 : break;
204 0 : case SUMO_TAG_TRIP:
205 : case SUMO_TAG_VEHICLE:
206 : case SUMO_TAG_FLOW:
207 : case SUMO_TAG_PERSON:
208 : case SUMO_TAG_PERSONFLOW:
209 : case SUMO_TAG_CONTAINER:
210 : case SUMO_TAG_CONTAINERFLOW:
211 : // parse object and all their childrens
212 0 : parseSumoBaseObject(obj);
213 : // delete object (and all of their childrens)
214 0 : delete obj;
215 : break;
216 : default:
217 : break;
218 : }
219 : }
220 0 : }
221 :
222 :
223 : void
224 0 : RouteHandler::parseSumoBaseObject(CommonXMLStructure::SumoBaseObject* obj) {
225 : // check if loading was aborted
226 0 : if (!myAbortLoading) {
227 : // switch tag
228 0 : switch (obj->getTag()) {
229 : // vTypes
230 0 : case SUMO_TAG_VTYPE:
231 : // check if parse vType or Ref
232 0 : if (obj->hasStringAttribute(SUMO_ATTR_REFID)) {
233 0 : if (buildVTypeRef(obj,
234 : obj->getStringAttribute(SUMO_ATTR_REFID),
235 : obj->getDoubleAttribute(SUMO_ATTR_PROB))) {
236 0 : obj->markAsCreated();
237 : }
238 : } else {
239 0 : if (buildVType(obj,
240 : obj->getVehicleTypeParameter())) {
241 0 : obj->markAsCreated();
242 : }
243 : }
244 : break;
245 0 : case SUMO_TAG_VTYPE_DISTRIBUTION:
246 0 : if (buildVTypeDistribution(obj,
247 : obj->getStringAttribute(SUMO_ATTR_ID),
248 : obj->getIntAttribute(SUMO_ATTR_DETERMINISTIC))) {
249 0 : obj->markAsCreated();
250 : }
251 : break;
252 : // route
253 0 : case SUMO_TAG_ROUTE:
254 : // embedded routes are created in build<Vehicle/Flow>EmbeddedRoute
255 0 : if (obj->hasStringAttribute(SUMO_ATTR_REFID)) {
256 0 : if (buildRouteRef(obj,
257 : obj->getStringAttribute(SUMO_ATTR_REFID),
258 : obj->getDoubleAttribute(SUMO_ATTR_PROB))) {
259 0 : obj->markAsCreated();
260 : }
261 0 : } else if (obj->hasStringAttribute(SUMO_ATTR_ID)) {
262 0 : if (buildRoute(obj,
263 : obj->getStringAttribute(SUMO_ATTR_ID),
264 : obj->getVClass(),
265 : obj->getStringListAttribute(SUMO_ATTR_EDGES),
266 : obj->getColorAttribute(SUMO_ATTR_COLOR),
267 : obj->getIntAttribute(SUMO_ATTR_REPEAT),
268 : obj->getTimeAttribute(SUMO_ATTR_CYCLETIME),
269 : obj->getDoubleAttribute(SUMO_ATTR_PROB),
270 0 : obj->getParameters())) {
271 0 : obj->markAsCreated();
272 : }
273 : }
274 : break;
275 0 : case SUMO_TAG_ROUTE_DISTRIBUTION:
276 0 : if (buildRouteDistribution(obj,
277 : obj->getStringAttribute(SUMO_ATTR_ID))) {
278 0 : obj->markAsCreated();
279 : }
280 : break;
281 : // vehicles
282 0 : case SUMO_TAG_TRIP:
283 0 : if (checkVehicleParents(obj)) {
284 0 : if (isOverFromToEdges(obj)) {
285 : // build trip with from-to edges
286 0 : if (buildTrip(obj,
287 : obj->getVehicleParameter(),
288 0 : obj->hasStringAttribute(SUMO_ATTR_FROM) ? obj->getStringAttribute(SUMO_ATTR_FROM) : "",
289 0 : obj->hasStringAttribute(SUMO_ATTR_TO) ? obj->getStringAttribute(SUMO_ATTR_TO) : "")) {
290 0 : obj->markAsCreated();
291 : }
292 0 : } else if (isOverFromToJunctions(obj)) {
293 : // build trip with from-to junctions
294 0 : if (buildTripJunctions(obj,
295 : obj->getVehicleParameter(),
296 : obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
297 : obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION))) {
298 0 : obj->markAsCreated();
299 : }
300 0 : } else if (isOverFromToTAZs(obj)) {
301 : // build trip with from-to TAZs
302 0 : if (buildTripTAZs(obj,
303 : obj->getVehicleParameter(),
304 : obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
305 : obj->getStringAttribute(SUMO_ATTR_TO_TAZ))) {
306 0 : obj->markAsCreated();
307 : }
308 : }
309 : }
310 : break;
311 0 : case SUMO_TAG_VEHICLE:
312 0 : if (checkVehicleParents(obj)) {
313 0 : if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
314 : // build vehicle over route
315 0 : if (buildVehicleOverRoute(obj,
316 : obj->getVehicleParameter())) {
317 0 : obj->markAsCreated();
318 : }
319 : } else {
320 0 : const auto embeddedRoute = getEmbeddedRoute(obj);
321 0 : if (embeddedRoute) {
322 : // build vehicle with embedded route
323 0 : if (buildVehicleEmbeddedRoute(obj,
324 : obj->getVehicleParameter(),
325 : embeddedRoute->getStringListAttribute(SUMO_ATTR_EDGES),
326 : embeddedRoute->getColorAttribute(SUMO_ATTR_COLOR),
327 : embeddedRoute->getIntAttribute(SUMO_ATTR_REPEAT),
328 : embeddedRoute->getTimeAttribute(SUMO_ATTR_CYCLETIME),
329 0 : embeddedRoute->getParameters())) {
330 0 : obj->markAsCreated();
331 : }
332 : }
333 : }
334 : }
335 : break;
336 : // flows
337 0 : case SUMO_TAG_FLOW:
338 0 : if (checkVehicleParents(obj)) {
339 0 : if (obj->hasStringAttribute(SUMO_ATTR_ROUTE)) {
340 : // build flow over route
341 0 : if (buildFlowOverRoute(obj,
342 : obj->getVehicleParameter())) {
343 0 : obj->markAsCreated();
344 : }
345 0 : } else if (isOverFromToEdges(obj)) {
346 : // build flow with from-to edges
347 0 : if (buildFlow(obj,
348 : obj->getVehicleParameter(),
349 : obj->getStringAttribute(SUMO_ATTR_FROM),
350 : obj->getStringAttribute(SUMO_ATTR_TO))) {
351 0 : obj->markAsCreated();
352 : }
353 0 : } else if (isOverFromToJunctions(obj)) {
354 : // build flow with from-to junctions
355 0 : if (buildFlowJunctions(obj,
356 : obj->getVehicleParameter(),
357 : obj->getStringAttribute(SUMO_ATTR_FROM_JUNCTION),
358 : obj->getStringAttribute(SUMO_ATTR_TO_JUNCTION))) {
359 0 : obj->markAsCreated();
360 : }
361 0 : } else if (isOverFromToTAZs(obj)) {
362 : // build flow with from-to TAZs
363 0 : if (buildFlowTAZs(obj,
364 : obj->getVehicleParameter(),
365 : obj->getStringAttribute(SUMO_ATTR_FROM_TAZ),
366 : obj->getStringAttribute(SUMO_ATTR_TO_TAZ))) {
367 0 : obj->markAsCreated();
368 : }
369 :
370 : } else {
371 0 : const auto embeddedRoute = getEmbeddedRoute(obj);
372 0 : if (embeddedRoute) {
373 : // build flow with embedded route
374 0 : if (buildFlowEmbeddedRoute(obj,
375 : obj->getVehicleParameter(),
376 : embeddedRoute->getStringListAttribute(SUMO_ATTR_EDGES),
377 : embeddedRoute->getColorAttribute(SUMO_ATTR_COLOR),
378 : embeddedRoute->getIntAttribute(SUMO_ATTR_REPEAT),
379 : embeddedRoute->getTimeAttribute(SUMO_ATTR_CYCLETIME),
380 0 : embeddedRoute->getParameters())) {
381 0 : obj->markAsCreated();
382 : }
383 : }
384 : }
385 : }
386 : break;
387 : // persons
388 0 : case SUMO_TAG_PERSON:
389 0 : if (buildPerson(obj,
390 : obj->getVehicleParameter())) {
391 0 : obj->markAsCreated();
392 : }
393 : break;
394 0 : case SUMO_TAG_PERSONFLOW:
395 0 : if (buildPersonFlow(obj,
396 : obj->getVehicleParameter())) {
397 0 : obj->markAsCreated();
398 : }
399 : break;
400 : // person plans
401 0 : case SUMO_TAG_PERSONTRIP:
402 0 : if (checkPersonPlanParents(obj)) {
403 0 : if (buildPersonTrip(obj,
404 : obj->getPlanParameters(),
405 : obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
406 : obj->getStringListAttribute(SUMO_ATTR_VTYPES),
407 : obj->getStringListAttribute(SUMO_ATTR_MODES),
408 : obj->getStringListAttribute(SUMO_ATTR_LINES),
409 : obj->getDoubleAttribute(SUMO_ATTR_WALKFACTOR),
410 : obj->getStringAttribute(SUMO_ATTR_GROUP))) {
411 0 : obj->markAsCreated();
412 : }
413 : }
414 : break;
415 0 : case SUMO_TAG_RIDE:
416 0 : if (checkPersonPlanParents(obj)) {
417 0 : if (buildRide(obj,
418 : obj->getPlanParameters(),
419 : obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
420 : obj->getStringListAttribute(SUMO_ATTR_LINES),
421 : obj->getStringAttribute(SUMO_ATTR_GROUP))) {
422 0 : obj->markAsCreated();
423 : }
424 : }
425 : break;
426 0 : case SUMO_TAG_WALK:
427 0 : if (checkPersonPlanParents(obj)) {
428 0 : if (buildWalk(obj,
429 : obj->getPlanParameters(),
430 : obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
431 : obj->getDoubleAttribute(SUMO_ATTR_SPEED),
432 : obj->getTimeAttribute(SUMO_ATTR_DURATION))) {
433 0 : obj->markAsCreated();
434 : }
435 : }
436 : break;
437 : // container
438 0 : case SUMO_TAG_CONTAINER:
439 0 : if (buildContainer(obj,
440 : obj->getVehicleParameter())) {
441 0 : obj->markAsCreated();
442 : }
443 : break;
444 0 : case SUMO_TAG_CONTAINERFLOW:
445 0 : if (buildContainerFlow(obj,
446 : obj->getVehicleParameter())) {
447 0 : obj->markAsCreated();
448 : }
449 : break;
450 : // container plans
451 0 : case SUMO_TAG_TRANSPORT:
452 0 : if (checkContainerPlanParents(obj)) {
453 0 : if (buildTransport(obj,
454 : obj->getPlanParameters(),
455 : obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
456 : obj->getStringListAttribute(SUMO_ATTR_LINES),
457 : obj->getStringAttribute(SUMO_ATTR_GROUP))) {
458 0 : obj->markAsCreated();
459 : }
460 : }
461 : break;
462 0 : case SUMO_TAG_TRANSHIP:
463 0 : if (checkContainerPlanParents(obj)) {
464 0 : if (buildTranship(obj,
465 : obj->getPlanParameters(),
466 : obj->getDoubleAttribute(SUMO_ATTR_ARRIVALPOS),
467 : obj->getDoubleAttribute(SUMO_ATTR_DEPARTPOS),
468 : obj->getDoubleAttribute(SUMO_ATTR_SPEED),
469 : obj->getTimeAttribute(SUMO_ATTR_DURATION))) {
470 0 : obj->markAsCreated();
471 : }
472 : }
473 : break;
474 : // stops
475 0 : case SUMO_TAG_STOP:
476 0 : if (checkStopParents(obj)) {
477 0 : if (buildStop(obj,
478 : obj->getPlanParameters(),
479 : obj->getStopParameter())) {
480 0 : obj->markAsCreated();
481 : }
482 : }
483 : break;
484 : default:
485 : break;
486 : }
487 : // now iterate over childrens
488 0 : for (const auto& child : obj->getSumoBaseObjectChildren()) {
489 : // call this function recursively
490 0 : parseSumoBaseObject(child);
491 : }
492 : }
493 0 : }
494 :
495 :
496 : void
497 0 : RouteHandler::parseVType(const SUMOSAXAttributes& attrs) {
498 : // parse vehicleType
499 0 : SUMOVTypeParameter* vehicleTypeParameter = SUMOVehicleParserHelper::beginVTypeParsing(attrs, myHardFail, myFileBucket->getFilename());
500 0 : if (vehicleTypeParameter) {
501 : // set tag
502 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE);
503 : // add all attributes
504 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleTypeParameter(vehicleTypeParameter);
505 : // delete vehicleType parameter (because in XMLStructure we have a copy)
506 0 : delete vehicleTypeParameter;
507 : } else {
508 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
509 : }
510 0 : }
511 :
512 :
513 : void
514 0 : RouteHandler::parseVTypeRef(const SUMOSAXAttributes& attrs) {
515 : // declare Ok Flag
516 0 : bool parsedOk = true;
517 : // special case for ID
518 0 : const std::string refId = attrs.get<std::string>(SUMO_ATTR_REFID, "", parsedOk);
519 0 : const double probability = attrs.getOpt<double>(SUMO_ATTR_PROB, refId.c_str(), parsedOk, INVALID_DOUBLE);
520 0 : if (parsedOk) {
521 : // set tag
522 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE);
523 : // add all attributes
524 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_REFID, refId);
525 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probability);
526 : } else {
527 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
528 : }
529 0 : }
530 :
531 :
532 : void
533 0 : RouteHandler::parseVTypeDistribution(const SUMOSAXAttributes& attrs) {
534 : // declare Ok Flag
535 0 : bool parsedOk = true;
536 : // needed attributes
537 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
538 : // optional attributes
539 0 : const int deterministic = attrs.getOpt<int>(SUMO_ATTR_DETERMINISTIC, id.c_str(), parsedOk, -1);
540 0 : std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, id.c_str(), parsedOk);
541 0 : std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
542 : // adjust sizes and probabilities
543 0 : adjustTypesAndProbabilities(vTypes, probabilities);
544 : // continue if all was parsed ok
545 0 : if (parsedOk) {
546 : // set tag
547 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE_DISTRIBUTION);
548 : // add all attributes
549 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
550 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_DETERMINISTIC, deterministic);
551 : // add references
552 0 : for (int i = 0; i < (int)vTypes.size(); i++) {
553 : // open SUMOBaseOBject
554 0 : myCommonXMLStructure.openSUMOBaseOBject();
555 : // set tag
556 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VTYPE);
557 : // add all attributes
558 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_REFID, vTypes.at(i));
559 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probabilities.at(i));
560 : // close SUMOBaseOBject
561 0 : myCommonXMLStructure.closeSUMOBaseOBject();
562 : }
563 : } else {
564 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
565 : }
566 0 : }
567 :
568 :
569 : void
570 0 : RouteHandler::parseRoute(const SUMOSAXAttributes& attrs) {
571 : // declare Ok Flag
572 0 : bool parsedOk = true;
573 : // needed attributes
574 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
575 0 : const std::vector<std::string> edges = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, id.c_str(), parsedOk);
576 : // optional attributes
577 0 : SUMOVehicleClass vClass = SUMOVehicleParserHelper::parseVehicleClass(attrs, id);
578 0 : const RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, id.c_str(), parsedOk, RGBColor::INVISIBLE);
579 0 : const int repeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, id.c_str(), parsedOk, 0);
580 0 : const SUMOTime cycleTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CYCLETIME, id.c_str(), parsedOk, 0);
581 0 : const double probability = attrs.getOpt<double>(SUMO_ATTR_PROB, id.c_str(), parsedOk, 1.0);
582 : // check attributes
583 0 : if (!checkNegative(SUMO_TAG_ROUTE, id, SUMO_ATTR_CYCLETIME, cycleTime, true)) {
584 0 : parsedOk = false;
585 : }
586 0 : if (!checkNegative(SUMO_TAG_ROUTE, id, SUMO_ATTR_REPEAT, repeat, true)) {
587 0 : parsedOk = false;
588 : }
589 0 : if (parsedOk) {
590 : // set tag
591 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
592 : // add all attributes
593 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
594 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVClass(vClass);
595 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_EDGES, edges);
596 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addColorAttribute(SUMO_ATTR_COLOR, color);
597 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_REPEAT, repeat);
598 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_CYCLETIME, cycleTime);
599 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probability);
600 : } else {
601 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
602 : }
603 0 : }
604 :
605 :
606 : void
607 0 : RouteHandler::parseRouteRef(const SUMOSAXAttributes& attrs) {
608 : // declare Ok Flag
609 0 : bool parsedOk = true;
610 : // special case for ID
611 0 : const std::string refId = attrs.get<std::string>(SUMO_ATTR_REFID, "", parsedOk);
612 0 : const double probability = attrs.getOpt<double>(SUMO_ATTR_PROB, refId.c_str(), parsedOk, INVALID_DOUBLE);
613 0 : if (parsedOk) {
614 : // set tag
615 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
616 : // add all attributes
617 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_REFID, refId);
618 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probability);
619 : } else {
620 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
621 : }
622 0 : }
623 :
624 :
625 : void
626 0 : RouteHandler::parseRouteEmbedded(const SUMOSAXAttributes& attrs) {
627 : // first check if this is an embedded route
628 0 : if (attrs.hasAttribute(SUMO_ATTR_ID)) {
629 0 : writeError(TL("an embedded route cannot have their own ID"));
630 : } else {
631 : // declare Ok Flag
632 0 : bool parsedOk = true;
633 : // special case for ID
634 0 : const std::string vehicleID = myCommonXMLStructure.getCurrentSumoBaseObject()->getParentSumoBaseObject()->getVehicleParameter().id;
635 : // needed attributes
636 0 : const std::vector<std::string> edges = attrs.get<std::vector<std::string> >(SUMO_ATTR_EDGES, vehicleID.c_str(), parsedOk);
637 : // optional attributes
638 0 : SUMOVehicleClass vClass = SUMOVehicleParserHelper::parseVehicleClass(attrs, vehicleID);
639 0 : const RGBColor color = attrs.getOpt<RGBColor>(SUMO_ATTR_COLOR, vehicleID.c_str(), parsedOk, RGBColor::INVISIBLE);
640 0 : const int repeat = attrs.getOpt<int>(SUMO_ATTR_REPEAT, vehicleID.c_str(), parsedOk, 0);
641 0 : const SUMOTime cycleTime = attrs.getOptSUMOTimeReporting(SUMO_ATTR_CYCLETIME, vehicleID.c_str(), parsedOk, 0);
642 : // check attributes
643 0 : if (!checkNegative(SUMO_TAG_ROUTE, vehicleID, SUMO_ATTR_CYCLETIME, cycleTime, true)) {
644 0 : parsedOk = false;
645 : }
646 0 : if (!checkNegative(SUMO_TAG_ROUTE, vehicleID, SUMO_ATTR_REPEAT, repeat, true)) {
647 0 : parsedOk = false;
648 : }
649 0 : if (parsedOk) {
650 : // set tag
651 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
652 : // add all attributes
653 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVClass(vClass);
654 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_EDGES, edges);
655 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addColorAttribute(SUMO_ATTR_COLOR, color);
656 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addIntAttribute(SUMO_ATTR_REPEAT, repeat);
657 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_CYCLETIME, cycleTime);
658 : } else {
659 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
660 : }
661 0 : }
662 0 : }
663 :
664 :
665 : void
666 0 : RouteHandler::parseRouteDistribution(const SUMOSAXAttributes& attrs) {
667 : // declare Ok Flag
668 0 : bool parsedOk = true;
669 : // needed attributes
670 0 : const std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "", parsedOk);
671 : // optional attributes
672 0 : std::vector<std::string> routes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_ROUTES, id.c_str(), parsedOk);
673 0 : std::vector<double> probabilities = attrs.getOpt<std::vector<double> >(SUMO_ATTR_PROBS, id.c_str(), parsedOk);
674 : // adjust sizes and probabilities
675 0 : adjustTypesAndProbabilities(routes, probabilities);
676 : // continue if all was parsed ok
677 0 : if (parsedOk) {
678 : // set tag
679 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE_DISTRIBUTION);
680 : // add all attributes
681 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ID, id);
682 : // add references
683 0 : for (int i = 0; i < (int)routes.size(); i++) {
684 : // open SUMOBaseOBject
685 0 : myCommonXMLStructure.openSUMOBaseOBject();
686 : // set tag
687 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ROUTE);
688 : // add all attributes
689 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_REFID, routes.at(i));
690 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_PROB, probabilities.at(i));
691 : // close SUMOBaseOBject
692 0 : myCommonXMLStructure.closeSUMOBaseOBject();
693 : }
694 : } else {
695 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
696 : }
697 0 : }
698 :
699 :
700 : void
701 0 : RouteHandler::parseTrip(const SUMOSAXAttributes& attrs) {
702 : // declare Ok Flag
703 0 : bool parsedOk = true;
704 : // parse vehicle
705 0 : SUMOVehicleParameter* tripParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_TRIP, attrs, myHardFail);
706 0 : if (tripParameter) {
707 : // check from/to edge/junction
708 0 : if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
709 0 : writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
710 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
711 0 : } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
712 0 : writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
713 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
714 0 : } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
715 : // from-to attributes
716 0 : const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_JUNCTION, tripParameter->id.c_str(), parsedOk);
717 0 : const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_JUNCTION, tripParameter->id.c_str(), parsedOk);
718 0 : if (parsedOk) {
719 : // set tag
720 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
721 : // set vehicle parameters
722 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
723 : // add other attributes
724 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
725 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
726 : } else {
727 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
728 : }
729 0 : } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
730 : // from-to attributes
731 0 : const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, tripParameter->id.c_str(), parsedOk);
732 0 : const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, tripParameter->id.c_str(), parsedOk);
733 0 : if (parsedOk) {
734 : // set tag
735 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
736 : // set vehicle parameters
737 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
738 : // add other attributes
739 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_TAZ, fromJunction);
740 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
741 : } else {
742 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
743 : }
744 : } else {
745 : // from-to attributes
746 0 : const std::string from = attrs.getOpt<std::string>(SUMO_ATTR_FROM, tripParameter->id.c_str(), parsedOk, "");
747 0 : const std::string to = attrs.getOpt<std::string>(SUMO_ATTR_TO, tripParameter->id.c_str(), parsedOk, "");
748 : // optional attributes
749 0 : const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, tripParameter->id.c_str(), parsedOk);
750 0 : if (parsedOk) {
751 : // set tag
752 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRIP);
753 : // set vehicle parameters
754 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(tripParameter);
755 : // add other attributes
756 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
757 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
758 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
759 : } else {
760 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
761 : }
762 0 : }
763 : // delete trip parameter (because in XMLStructure we have a copy)
764 0 : delete tripParameter;
765 : } else {
766 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
767 : }
768 0 : }
769 :
770 :
771 : void
772 0 : RouteHandler::parseVehicle(const SUMOSAXAttributes& attrs) {
773 : // first parse vehicle
774 0 : SUMOVehicleParameter* vehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_VEHICLE, attrs, myHardFail);
775 0 : if (vehicleParameter) {
776 : // set tag
777 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_VEHICLE);
778 : // set vehicle parameters
779 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(vehicleParameter);
780 : // delete vehicle parameter (because in XMLStructure we have a copy)
781 0 : delete vehicleParameter;
782 : } else {
783 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
784 : }
785 0 : }
786 :
787 :
788 : void
789 0 : RouteHandler::parseFlow(const SUMOSAXAttributes& attrs) {
790 : // declare Ok Flag
791 0 : bool parsedOk = true;
792 : // first parse flow
793 0 : SUMOVehicleParameter* flowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_FLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
794 0 : if (flowParameter) {
795 : // set vehicle parameters
796 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(flowParameter);
797 : // check from/to edge/junction
798 0 : if ((attrs.hasAttribute(SUMO_ATTR_FROM) + attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_FROM_TAZ)) > 1) {
799 0 : writeError(TL("Attributes 'from', 'fromJunction' and 'fromTaz' cannot be defined together"));
800 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
801 0 : } else if ((attrs.hasAttribute(SUMO_ATTR_TO) + attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION) + attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) > 1) {
802 0 : writeError(TL("Attributes 'to', 'toJunction' and 'toTaz' cannot be defined together"));
803 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
804 0 : } else if (attrs.hasAttribute(SUMO_ATTR_FROM) && attrs.hasAttribute(SUMO_ATTR_TO)) {
805 : // from-to attributes
806 0 : const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, flowParameter->id.c_str(), parsedOk);
807 0 : const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, flowParameter->id.c_str(), parsedOk);
808 : // optional attributes
809 0 : const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, flowParameter->id.c_str(), parsedOk);
810 0 : if (parsedOk) {
811 : // set tag
812 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
813 : // add other attributes
814 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM, from);
815 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO, to);
816 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VIA, via);
817 : } else {
818 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
819 : }
820 0 : } else if (attrs.hasAttribute(SUMO_ATTR_FROM_JUNCTION) && attrs.hasAttribute(SUMO_ATTR_TO_JUNCTION)) {
821 : // from-to attributes
822 0 : const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_JUNCTION, flowParameter->id.c_str(), parsedOk);
823 0 : const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_JUNCTION, flowParameter->id.c_str(), parsedOk);
824 0 : if (parsedOk) {
825 : // set tag
826 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
827 : // add other attributes
828 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_JUNCTION, fromJunction);
829 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_JUNCTION, toJunction);
830 : } else {
831 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
832 : }
833 0 : } else if (attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) && attrs.hasAttribute(SUMO_ATTR_TO_TAZ)) {
834 : // from-to attributes
835 0 : const std::string fromJunction = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, flowParameter->id.c_str(), parsedOk);
836 0 : const std::string toJunction = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, flowParameter->id.c_str(), parsedOk);
837 0 : if (parsedOk) {
838 : // set tag
839 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
840 : // add other attributes
841 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_FROM_TAZ, fromJunction);
842 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_TO_TAZ, toJunction);
843 : } else {
844 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
845 : }
846 0 : } else if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
847 : // from-to attributes
848 0 : const std::string route = attrs.get<std::string>(SUMO_ATTR_ROUTE, flowParameter->id.c_str(), parsedOk);
849 0 : if (parsedOk) {
850 : // set tag
851 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
852 : // add other attributes
853 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_ROUTE, route);
854 : } else {
855 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
856 : }
857 : } else {
858 : // set tag
859 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_FLOW);
860 : }
861 : // delete flow parameter (because in XMLStructure we have a copy)
862 0 : delete flowParameter;
863 : } else {
864 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
865 : }
866 0 : }
867 :
868 :
869 : void
870 0 : RouteHandler::parseStop(const SUMOSAXAttributes& attrs) {
871 : // declare Ok Flag
872 0 : bool parsedOk = true;
873 : // declare stop
874 0 : SUMOVehicleParameter::Stop stop;
875 : // plan parameters
876 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
877 : // get parents
878 : std::vector<SumoXMLTag> stopParents;
879 0 : stopParents.insert(stopParents.end(), NamespaceIDs::routes.begin(), NamespaceIDs::routes.end());
880 0 : stopParents.insert(stopParents.end(), NamespaceIDs::vehicles.begin(), NamespaceIDs::vehicles.end());
881 0 : stopParents.insert(stopParents.end(), NamespaceIDs::persons.begin(), NamespaceIDs::persons.end());
882 0 : stopParents.insert(stopParents.end(), NamespaceIDs::containers.begin(), NamespaceIDs::containers.end());
883 : // check parents
884 0 : checkParsedParent(SUMO_TAG_STOP, stopParents, parsedOk);
885 : // parse stop
886 0 : if (parsedOk && parseStopParameters(stop, attrs)) {
887 : // set tag
888 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_STOP);
889 : // add stop attributes
890 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
891 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setStopParameter(stop);
892 : } else {
893 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
894 : }
895 0 : }
896 :
897 :
898 : void
899 0 : RouteHandler::parsePerson(const SUMOSAXAttributes& attrs) {
900 : // first parse vehicle
901 0 : SUMOVehicleParameter* personParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_PERSON, attrs, myHardFail);
902 0 : if (personParameter) {
903 : // set tag
904 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSON);
905 : // set vehicle parameter
906 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personParameter);
907 : // delete person parameter (because in XMLStructure we have a copy)
908 0 : delete personParameter;
909 : } else {
910 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
911 : }
912 0 : }
913 :
914 :
915 : void
916 0 : RouteHandler::parsePersonFlow(const SUMOSAXAttributes& attrs) {
917 : // first parse flow
918 0 : SUMOVehicleParameter* personFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_PERSONFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
919 0 : if (personFlowParameter) {
920 : // set tag
921 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONFLOW);
922 : // set vehicle parameter
923 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(personFlowParameter);
924 : // delete person flow parameter (because in XMLStructure we have a copy)
925 0 : delete personFlowParameter;
926 : } else {
927 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
928 : }
929 0 : }
930 :
931 :
932 : void
933 0 : RouteHandler::parsePersonTrip(const SUMOSAXAttributes& attrs) {
934 : // declare Ok Flag
935 0 : bool parsedOk = true;
936 : // plan parameters
937 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
938 : // optional attributes
939 0 : const std::vector<std::string> via = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VIA, "", parsedOk);
940 0 : const std::vector<std::string> vTypes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_VTYPES, "", parsedOk);
941 0 : const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
942 0 : std::vector<std::string> modes = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_MODES, "", parsedOk);
943 0 : const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
944 0 : const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
945 0 : const double walkFactor = attrs.getOpt<double>(SUMO_ATTR_WALKFACTOR, "", parsedOk, 0);
946 0 : const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
947 : // check modes
948 : SVCPermissions dummyModeSet;
949 : std::string dummyError;
950 0 : if (!SUMOVehicleParameter::parsePersonModes(toString(modes), toString(SUMO_TAG_PERSONTRIP), "", dummyModeSet, dummyError)) {
951 0 : WRITE_WARNING(dummyError);
952 : modes.clear();
953 : }
954 : // check parents
955 0 : checkParsedParent(SUMO_TAG_PERSONTRIP, NamespaceIDs::persons, parsedOk);
956 0 : if (parsedOk) {
957 : // set tag
958 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_PERSONTRIP);
959 : // add all attributes
960 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
961 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_VTYPES, vTypes);
962 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_MODES, modes);
963 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
964 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
965 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
966 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_WALKFACTOR, walkFactor);
967 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
968 : } else {
969 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
970 : }
971 0 : }
972 :
973 :
974 : void
975 0 : RouteHandler::parseWalk(const SUMOSAXAttributes& attrs) {
976 0 : if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
977 0 : writeError(TL("Speed and duration attributes cannot be defined together in walks"));
978 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
979 : } else {
980 : // declare Ok Flag
981 0 : bool parsedOk = true;
982 : // plan parameters
983 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
984 : // optional attributes
985 0 : const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
986 0 : const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
987 0 : const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
988 0 : const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
989 : // check parents
990 0 : checkParsedParent(SUMO_TAG_WALK, NamespaceIDs::persons, parsedOk);
991 0 : if (parsedOk) {
992 : // set tag
993 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_WALK);
994 : // add all attributes
995 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
996 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
997 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
998 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
999 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
1000 : } else {
1001 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1002 : }
1003 0 : }
1004 0 : }
1005 :
1006 :
1007 : void
1008 0 : RouteHandler::parseRide(const SUMOSAXAttributes& attrs) {
1009 : // declare Ok Flag
1010 0 : bool parsedOk = true;
1011 : // plan parameters
1012 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
1013 : // optional attributes
1014 0 : const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
1015 0 : const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
1016 0 : const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
1017 : // check parents
1018 0 : checkParsedParent(SUMO_TAG_RIDE, NamespaceIDs::persons, parsedOk);
1019 0 : if (parsedOk) {
1020 : // set tag
1021 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_RIDE);
1022 : // add all attributes
1023 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
1024 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
1025 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
1026 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
1027 : } else {
1028 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1029 : }
1030 0 : }
1031 :
1032 :
1033 : void
1034 0 : RouteHandler::parseContainer(const SUMOSAXAttributes& attrs) {
1035 : // first parse container
1036 0 : SUMOVehicleParameter* containerParameter = SUMOVehicleParserHelper::parseVehicleAttributes(SUMO_TAG_CONTAINER, attrs, myHardFail);
1037 0 : if (containerParameter) {
1038 : // set tag
1039 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINER);
1040 : // set vehicle parameter
1041 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerParameter);
1042 : // delete container parameter (because in XMLStructure we have a copy)
1043 0 : delete containerParameter;
1044 : } else {
1045 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1046 : }
1047 0 : }
1048 :
1049 :
1050 : void
1051 0 : RouteHandler::parseContainerFlow(const SUMOSAXAttributes& attrs) {
1052 : // first parse flow
1053 0 : SUMOVehicleParameter* containerFlowParameter = SUMOVehicleParserHelper::parseFlowAttributes(SUMO_TAG_CONTAINERFLOW, attrs, myHardFail, true, myFlowBeginDefault, myFlowEndDefault);
1054 0 : if (containerFlowParameter) {
1055 : // set tag
1056 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_CONTAINERFLOW);
1057 : // set vehicle parameter
1058 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setVehicleParameter(containerFlowParameter);
1059 : // delete container flow parameter (because in XMLStructure we have a copy)
1060 0 : delete containerFlowParameter;
1061 : } else {
1062 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1063 : }
1064 0 : }
1065 :
1066 :
1067 : void
1068 0 : RouteHandler::parseTransport(const SUMOSAXAttributes& attrs) {
1069 : // declare Ok Flag
1070 0 : bool parsedOk = true;
1071 : // plan parameters
1072 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
1073 : // optional attributes
1074 0 : const std::vector<std::string> lines = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_LINES, "", parsedOk);
1075 0 : const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
1076 0 : const std::string group = attrs.getOpt<std::string>(SUMO_ATTR_GROUP, "", parsedOk, "");
1077 : // check parents
1078 0 : checkParsedParent(SUMO_TAG_TRANSPORT, NamespaceIDs::containers, parsedOk);
1079 0 : if (parsedOk) {
1080 : // set tag
1081 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSPORT);
1082 : // add all attributes
1083 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
1084 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringListAttribute(SUMO_ATTR_LINES, lines);
1085 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
1086 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addStringAttribute(SUMO_ATTR_GROUP, group);
1087 : } else {
1088 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1089 : }
1090 0 : }
1091 :
1092 :
1093 : void
1094 0 : RouteHandler::parseTranship(const SUMOSAXAttributes& attrs) {
1095 0 : if (attrs.hasAttribute(SUMO_ATTR_SPEED) && attrs.hasAttribute(SUMO_ATTR_DURATION)) {
1096 0 : writeError(TL("Speed and duration attributes cannot be defined together in tranships"));
1097 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1098 : } else {
1099 : // declare Ok Flag
1100 0 : bool parsedOk = true;
1101 : // plan parameters
1102 0 : const auto planParameters = CommonXMLStructure::PlanParameters(myCommonXMLStructure.getCurrentSumoBaseObject(), attrs, parsedOk);
1103 : // optional attributes
1104 0 : const double arrivalPos = attrs.getOpt<double>(SUMO_ATTR_ARRIVALPOS, "", parsedOk, -1);
1105 0 : const double departPos = attrs.getOpt<double>(SUMO_ATTR_DEPARTPOS, "", parsedOk, -1);
1106 0 : const double speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, "", parsedOk, 1.39);
1107 0 : const SUMOTime duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, "", parsedOk, 0);
1108 : // check parents
1109 0 : checkParsedParent(SUMO_TAG_TRANSHIP, NamespaceIDs::containers, parsedOk);
1110 0 : if (parsedOk) {
1111 : // set tag
1112 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_TRANSHIP);
1113 : // add all attributes
1114 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setPlanParameters(planParameters);
1115 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_ARRIVALPOS, arrivalPos);
1116 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_DEPARTPOS, departPos);
1117 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addDoubleAttribute(SUMO_ATTR_SPEED, speed);
1118 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->addTimeAttribute(SUMO_ATTR_DURATION, duration);
1119 : } else {
1120 0 : myCommonXMLStructure.getCurrentSumoBaseObject()->setTag(SUMO_TAG_ERROR);
1121 : }
1122 0 : }
1123 0 : }
1124 :
1125 :
1126 : void
1127 0 : RouteHandler::parseInterval(const SUMOSAXAttributes& attrs) {
1128 : // declare Ok Flag
1129 0 : bool parsedOk = true;
1130 : // just parse begin and end default
1131 0 : myFlowBeginDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, nullptr, parsedOk);
1132 0 : myFlowEndDefault = attrs.getSUMOTimeReporting(SUMO_ATTR_END, nullptr, parsedOk);
1133 0 : }
1134 :
1135 :
1136 : bool
1137 0 : RouteHandler::parseNestedCFM(const SumoXMLTag tag, const SUMOSAXAttributes& attrs, CommonXMLStructure::SumoBaseObject* vTypeObject) {
1138 : // write warning info
1139 0 : WRITE_WARNINGF(TL("Defining car-following parameters in a nested element is deprecated in vType '%', use attributes instead!"), vTypeObject->getStringAttribute(SUMO_ATTR_ID));
1140 : // get vType to modify it
1141 0 : auto vType = vTypeObject->getVehicleTypeParameter();
1142 : // parse nested CFM attributes
1143 0 : if (SUMOVehicleParserHelper::parseCFMParams(&vType, tag, attrs, true)) {
1144 0 : vTypeObject->setVehicleTypeParameter(&vType);
1145 : return true;
1146 0 : } else if (myHardFail) {
1147 0 : throw ProcessError(TL("Invalid parsing embedded VType"));
1148 : } else {
1149 0 : return writeError(TL("Invalid parsing embedded VType"));
1150 : }
1151 0 : }
1152 :
1153 :
1154 : bool
1155 0 : RouteHandler::parseStopParameters(SUMOVehicleParameter::Stop& stop, const SUMOSAXAttributes& attrs) {
1156 : // check stop parameters
1157 0 : if (attrs.hasAttribute(SUMO_ATTR_ARRIVAL)) {
1158 0 : stop.parametersSet |= STOP_ARRIVAL_SET;
1159 : }
1160 0 : if (attrs.hasAttribute(SUMO_ATTR_DURATION)) {
1161 0 : stop.parametersSet |= STOP_DURATION_SET;
1162 : }
1163 0 : if (attrs.hasAttribute(SUMO_ATTR_UNTIL)) {
1164 0 : stop.parametersSet |= STOP_UNTIL_SET;
1165 : }
1166 0 : if (attrs.hasAttribute(SUMO_ATTR_STARTED)) {
1167 0 : stop.parametersSet |= STOP_STARTED_SET;
1168 : }
1169 0 : if (attrs.hasAttribute(SUMO_ATTR_ENDED)) {
1170 0 : stop.parametersSet |= STOP_ENDED_SET;
1171 : }
1172 0 : if (attrs.hasAttribute(SUMO_ATTR_EXTENSION)) {
1173 0 : stop.parametersSet |= STOP_EXTENSION_SET;
1174 : }
1175 0 : if (attrs.hasAttribute(SUMO_ATTR_ENDPOS)) {
1176 0 : stop.parametersSet |= STOP_END_SET;
1177 : }
1178 0 : if (attrs.hasAttribute(SUMO_ATTR_STARTPOS)) {
1179 0 : stop.parametersSet |= STOP_START_SET;
1180 : }
1181 0 : if (attrs.hasAttribute(SUMO_ATTR_POSITION_LAT)) {
1182 0 : stop.parametersSet |= STOP_POSLAT_SET;
1183 : }
1184 0 : if (attrs.hasAttribute(SUMO_ATTR_TRIGGERED)) {
1185 0 : stop.parametersSet |= STOP_TRIGGER_SET;
1186 : }
1187 : // legacy attribute
1188 0 : if (attrs.hasAttribute(SUMO_ATTR_CONTAINER_TRIGGERED)) {
1189 0 : if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
1190 0 : WRITE_WARNING(TLF("Attributes '%' and '%' cannot be loaded simultaneously. Ignoring '%'", toString(SUMO_ATTR_SPEED), toString(SUMO_ATTR_CONTAINER_TRIGGERED), toString(SUMO_ATTR_CONTAINER_TRIGGERED)));
1191 : } else {
1192 0 : stop.parametersSet |= STOP_TRIGGER_SET;
1193 : }
1194 : }
1195 0 : if (attrs.hasAttribute(SUMO_ATTR_PARKING)) {
1196 0 : stop.parametersSet |= STOP_PARKING_SET;
1197 : }
1198 0 : if (attrs.hasAttribute(SUMO_ATTR_EXPECTED)) {
1199 0 : stop.parametersSet |= STOP_EXPECTED_SET;
1200 : }
1201 0 : if (attrs.hasAttribute(SUMO_ATTR_PERMITTED)) {
1202 0 : stop.parametersSet |= STOP_PERMITTED_SET;
1203 : }
1204 0 : if (attrs.hasAttribute(SUMO_ATTR_EXPECTED_CONTAINERS)) {
1205 0 : stop.parametersSet |= STOP_EXPECTED_CONTAINERS_SET;
1206 : }
1207 0 : if (attrs.hasAttribute(SUMO_ATTR_TRIP_ID)) {
1208 0 : stop.parametersSet |= STOP_TRIP_ID_SET;
1209 : }
1210 0 : if (attrs.hasAttribute(SUMO_ATTR_SPLIT)) {
1211 0 : stop.parametersSet |= STOP_SPLIT_SET;
1212 : }
1213 0 : if (attrs.hasAttribute(SUMO_ATTR_JOIN)) {
1214 0 : stop.parametersSet |= STOP_JOIN_SET;
1215 : }
1216 0 : if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
1217 0 : stop.parametersSet |= STOP_LINE_SET;
1218 : }
1219 0 : if (attrs.hasAttribute(SUMO_ATTR_SPEED)) {
1220 0 : stop.parametersSet |= STOP_SPEED_SET;
1221 : }
1222 0 : if (attrs.hasAttribute(SUMO_ATTR_ONDEMAND)) {
1223 0 : stop.parametersSet |= STOP_ONDEMAND_SET;
1224 : }
1225 0 : if (attrs.hasAttribute(SUMO_ATTR_JUMP)) {
1226 0 : stop.parametersSet |= STOP_JUMP_SET;
1227 : }
1228 0 : if (attrs.hasAttribute(SUMO_ATTR_JUMP_UNTIL)) {
1229 0 : stop.parametersSet |= STOP_JUMP_UNTIL_SET;
1230 : }
1231 : // get parameters
1232 0 : bool ok = true;
1233 : // edge/lane
1234 0 : stop.edge = attrs.getOpt<std::string>(SUMO_ATTR_EDGE, nullptr, ok, "");
1235 0 : stop.lane = attrs.getOpt<std::string>(SUMO_ATTR_LANE, nullptr, ok, stop.busstop);
1236 : // check errors
1237 0 : if (!stop.edge.empty() && !stop.lane.empty()) {
1238 0 : return writeError(TL("A stop must be defined either with an edge or with an lane, not both"));
1239 : }
1240 : // stopping places
1241 0 : stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, nullptr, ok, "");
1242 0 : if (stop.busstop.empty()) {
1243 0 : stop.busstop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, nullptr, ok, stop.busstop);
1244 : }
1245 0 : stop.chargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, nullptr, ok, "");
1246 0 : stop.overheadWireSegment = attrs.getOpt<std::string>(SUMO_ATTR_OVERHEAD_WIRE_SEGMENT, nullptr, ok, "");
1247 0 : stop.containerstop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, nullptr, ok, "");
1248 0 : stop.parkingarea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, nullptr, ok, "");
1249 : //check stopping places
1250 0 : const int numStoppingPlaces = !stop.busstop.empty() + !stop.chargingStation.empty() + !stop.overheadWireSegment.empty() +
1251 0 : !stop.containerstop.empty() + !stop.parkingarea.empty();
1252 0 : if (numStoppingPlaces > 1) {
1253 0 : return writeError(TL("A stop must be defined only in a StoppingPlace"));
1254 0 : } else if ((numStoppingPlaces == 0) && stop.edge.empty() && stop.lane.empty()) {
1255 0 : return writeError(TL("A stop must be defined in an edge, a lane, or in a StoppingPlace"));
1256 : }
1257 : // declare error suffix
1258 : std::string errorSuffix;
1259 0 : if (stop.busstop != "") {
1260 0 : errorSuffix = " at '" + stop.busstop + "'" + errorSuffix;
1261 0 : } else if (stop.chargingStation != "") {
1262 0 : errorSuffix = " at '" + stop.chargingStation + "'" + errorSuffix;
1263 0 : } else if (stop.overheadWireSegment != "") {
1264 0 : errorSuffix = " at '" + stop.overheadWireSegment + "'" + errorSuffix;
1265 0 : } else if (stop.containerstop != "") {
1266 0 : errorSuffix = " at '" + stop.containerstop + "'" + errorSuffix;
1267 0 : } else if (stop.parkingarea != "") {
1268 0 : errorSuffix = " at '" + stop.parkingarea + "'" + errorSuffix;
1269 0 : } else if (stop.edge != "") {
1270 0 : errorSuffix = " at '" + stop.edge + "'" + errorSuffix;
1271 : } else {
1272 0 : errorSuffix = " on lane '" + stop.lane + "'" + errorSuffix;
1273 : }
1274 : // speed for counting as stopped
1275 0 : stop.speed = attrs.getOpt<double>(SUMO_ATTR_SPEED, nullptr, ok, 0);
1276 0 : if (stop.speed < 0) {
1277 0 : return writeError("Speed cannot be negative for stop" + errorSuffix);
1278 : }
1279 : // get the standing duration
1280 0 : bool expectTrigger = !attrs.hasAttribute(SUMO_ATTR_DURATION) && !attrs.hasAttribute(SUMO_ATTR_UNTIL) && !attrs.hasAttribute(SUMO_ATTR_SPEED);
1281 0 : std::vector<std::string> triggers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_TRIGGERED, nullptr, ok);
1282 : // legacy
1283 0 : if (attrs.getOpt<bool>(SUMO_ATTR_CONTAINER_TRIGGERED, nullptr, ok, false) && !attrs.hasAttribute(SUMO_ATTR_SPEED)) {
1284 0 : triggers.push_back(toString(SUMO_TAG_CONTAINER));
1285 : };
1286 0 : SUMOVehicleParameter::parseStopTriggers(triggers, expectTrigger, stop);
1287 0 : stop.startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, nullptr, ok, 0);
1288 0 : stop.endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, nullptr, ok, 0);
1289 0 : stop.friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, nullptr, ok, false);
1290 0 : stop.arrival = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ARRIVAL, nullptr, ok, -1);
1291 0 : stop.duration = attrs.getOptSUMOTimeReporting(SUMO_ATTR_DURATION, nullptr, ok, -1);
1292 0 : stop.until = attrs.getOptSUMOTimeReporting(SUMO_ATTR_UNTIL, nullptr, ok, -1);
1293 0 : if (!expectTrigger && (!ok || (stop.duration < 0 && stop.until < 0 && stop.speed == 0))) {
1294 0 : return writeError("Invalid duration or end time is given for a stop" + errorSuffix);
1295 : }
1296 0 : stop.extension = attrs.getOptSUMOTimeReporting(SUMO_ATTR_EXTENSION, nullptr, ok, -1);
1297 0 : const bool defaultParking = (stop.triggered || stop.containerTriggered || stop.parkingarea != "");
1298 0 : stop.parking = attrs.getOpt<ParkingType>(SUMO_ATTR_PARKING, nullptr, ok, defaultParking ? ParkingType::OFFROAD : ParkingType::ONROAD);
1299 0 : if ((stop.parkingarea != "") && (stop.parking == ParkingType::ONROAD)) {
1300 0 : WRITE_WARNING("Stop at parkingarea overrides attribute 'parking' for stop" + errorSuffix);
1301 0 : stop.parking = ParkingType::OFFROAD;
1302 : }
1303 0 : if (!ok) {
1304 0 : return writeError("Invalid bool for 'triggered', 'containerTriggered' or 'parking' for stop" + errorSuffix);
1305 : }
1306 : // expected persons
1307 0 : const std::vector<std::string>& expected = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED, nullptr, ok);
1308 : stop.awaitedPersons.insert(expected.begin(), expected.end());
1309 0 : if (stop.awaitedPersons.size() > 0 && (stop.parametersSet & STOP_TRIGGER_SET) == 0) {
1310 0 : stop.triggered = true;
1311 0 : if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
1312 0 : stop.parking = ParkingType::OFFROAD;
1313 : }
1314 : }
1315 : // permitted transportables
1316 0 : const std::vector<std::string>& permitted = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_PERMITTED, nullptr, ok);
1317 : stop.permitted.insert(permitted.begin(), permitted.end());
1318 : // expected containers
1319 0 : const std::vector<std::string>& expectedContainers = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EXPECTED_CONTAINERS, nullptr, ok);
1320 : stop.awaitedContainers.insert(expectedContainers.begin(), expectedContainers.end());
1321 0 : if (stop.awaitedContainers.size() > 0 && (stop.parametersSet & STOP_CONTAINER_TRIGGER_SET) == 0) {
1322 0 : stop.containerTriggered = true;
1323 0 : if ((stop.parametersSet & STOP_PARKING_SET) == 0) {
1324 0 : stop.parking = ParkingType::OFFROAD;
1325 : }
1326 : }
1327 : // public transport trip id
1328 0 : stop.tripId = attrs.getOpt<std::string>(SUMO_ATTR_TRIP_ID, nullptr, ok, "");
1329 0 : stop.split = attrs.getOpt<std::string>(SUMO_ATTR_SPLIT, nullptr, ok, "");
1330 0 : stop.join = attrs.getOpt<std::string>(SUMO_ATTR_JOIN, nullptr, ok, "");
1331 0 : stop.line = attrs.getOpt<std::string>(SUMO_ATTR_LINE, nullptr, ok, "");
1332 : // index
1333 0 : const std::string idx = attrs.getOpt<std::string>(SUMO_ATTR_INDEX, nullptr, ok, "end");
1334 0 : if (idx == "end") {
1335 0 : stop.index = STOP_INDEX_END;
1336 0 : } else if (idx == "fit") {
1337 0 : stop.index = STOP_INDEX_FIT;
1338 : } else {
1339 0 : stop.index = attrs.get<int>(SUMO_ATTR_INDEX, nullptr, ok);
1340 0 : if (!ok || stop.index < 0) {
1341 0 : return writeError("Invalid 'index' for stop" + errorSuffix);
1342 : }
1343 : }
1344 0 : stop.started = attrs.getOptSUMOTimeReporting(SUMO_ATTR_STARTED, nullptr, ok, -1);
1345 0 : stop.ended = attrs.getOptSUMOTimeReporting(SUMO_ATTR_ENDED, nullptr, ok, -1);
1346 0 : stop.posLat = attrs.getOpt<double>(SUMO_ATTR_POSITION_LAT, nullptr, ok, INVALID_DOUBLE);
1347 0 : stop.actType = attrs.getOpt<std::string>(SUMO_ATTR_ACTTYPE, nullptr, ok, "");
1348 0 : stop.onDemand = attrs.getOpt<bool>(SUMO_ATTR_ONDEMAND, nullptr, ok, false);
1349 0 : stop.jump = attrs.getOptSUMOTimeReporting(SUMO_ATTR_JUMP, nullptr, ok, -1);
1350 0 : stop.jumpUntil = attrs.getOptSUMOTimeReporting(SUMO_ATTR_JUMP_UNTIL, nullptr, ok, -1);
1351 0 : return true;
1352 0 : }
1353 :
1354 :
1355 : bool
1356 0 : RouteHandler::isOverFromToEdges(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
1357 0 : return sumoBaseObject->hasStringAttribute(SUMO_ATTR_FROM) && sumoBaseObject->hasStringAttribute(SUMO_ATTR_TO);
1358 : }
1359 :
1360 :
1361 : bool
1362 0 : RouteHandler::isOverFromToJunctions(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
1363 0 : return sumoBaseObject->hasStringAttribute(SUMO_ATTR_FROM_JUNCTION) && sumoBaseObject->hasStringAttribute(SUMO_ATTR_TO_JUNCTION);
1364 : }
1365 :
1366 :
1367 : bool
1368 0 : RouteHandler::isOverFromToTAZs(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
1369 0 : return sumoBaseObject->hasStringAttribute(SUMO_ATTR_FROM_TAZ) && sumoBaseObject->hasStringAttribute(SUMO_ATTR_TO_TAZ);
1370 : }
1371 :
1372 :
1373 : void
1374 0 : RouteHandler::adjustTypesAndProbabilities(std::vector<std::string>& vTypes, std::vector<double>& probabilities) {
1375 : // add more probabilities
1376 0 : for (size_t i = probabilities.size(); i < vTypes.size(); i++) {
1377 0 : probabilities.push_back(INVALID_DOUBLE);
1378 : }
1379 : // reduce number of probabilities
1380 0 : while (vTypes.size() < probabilities.size()) {
1381 : probabilities.pop_back();
1382 : }
1383 0 : }
1384 :
1385 : /****************************************************************************/
|