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