Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 CommonXMLStructure.cpp
15 : /// @author Pablo Alvarez Lopez
16 : /// @date May 2021
17 : ///
18 : // Structure for common XML Parsing
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <utils/common/MsgHandler.h>
23 : #include <utils/common/StringTokenizer.h>
24 : #include <utils/xml/SUMOSAXHandler.h>
25 :
26 : #include "CommonXMLStructure.h"
27 :
28 :
29 : // ===========================================================================
30 : // method definitions
31 : // ===========================================================================
32 :
33 : // ---------------------------------------------------------------------------
34 : // CommonXMLStructure::PlanParameters - methods
35 : // ---------------------------------------------------------------------------
36 :
37 0 : CommonXMLStructure::PlanParameters::PlanParameters() {}
38 :
39 :
40 0 : CommonXMLStructure::PlanParameters::PlanParameters(const CommonXMLStructure::SumoBaseObject* sumoBaseObject,
41 0 : const SUMOSAXAttributes& attrs, bool& parsedOk) {
42 0 : if (sumoBaseObject->getParentSumoBaseObject() != nullptr) {
43 : // get plan parent ID (first check if exist!)
44 0 : const auto planParentID = sumoBaseObject->getParentSumoBaseObject()->hasStringAttribute(SUMO_ATTR_ID) ?
45 0 : sumoBaseObject->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID).c_str() : "";
46 : // edges
47 0 : fromEdge = attrs.getOpt<std::string>(SUMO_ATTR_FROM, planParentID, parsedOk, "");
48 0 : toEdge = attrs.getOpt<std::string>(SUMO_ATTR_TO, planParentID, parsedOk, "");
49 0 : if (toEdge.empty()) {
50 0 : toEdge = attrs.getOpt<std::string>(SUMO_ATTR_EDGE, planParentID, parsedOk, "");
51 : }
52 0 : consecutiveEdges = attrs.getOpt<std::vector<std::string> >(SUMO_ATTR_EDGES, planParentID, parsedOk);
53 : // junctions
54 0 : fromJunction = attrs.getOpt<std::string>(SUMO_ATTR_FROM_JUNCTION, planParentID, parsedOk, "");
55 0 : toJunction = attrs.getOpt<std::string>(SUMO_ATTR_TO_JUNCTION, planParentID, parsedOk, "");
56 : // TAZs
57 0 : fromTAZ = attrs.getOpt<std::string>(SUMO_ATTR_FROM_TAZ, planParentID, parsedOk, "");
58 0 : toTAZ = attrs.getOpt<std::string>(SUMO_ATTR_TO_TAZ, planParentID, parsedOk, "");
59 : // bus stops
60 0 : fromBusStop = attrs.getOpt<std::string>(GNE_ATTR_FROM_BUSSTOP, planParentID, parsedOk, "");
61 0 : toBusStop = attrs.getOpt<std::string>(SUMO_ATTR_BUS_STOP, planParentID, parsedOk, "");
62 : // train stops
63 0 : fromTrainStop = attrs.getOpt<std::string>(GNE_ATTR_FROM_TRAINSTOP, planParentID, parsedOk, "");
64 0 : toTrainStop = attrs.getOpt<std::string>(SUMO_ATTR_TRAIN_STOP, planParentID, parsedOk, "");
65 : // container stops
66 0 : fromContainerStop = attrs.getOpt<std::string>(GNE_ATTR_FROM_CONTAINERSTOP, planParentID, parsedOk, "");
67 0 : toContainerStop = attrs.getOpt<std::string>(SUMO_ATTR_CONTAINER_STOP, planParentID, parsedOk, "");
68 : // charging stations
69 0 : fromChargingStation = attrs.getOpt<std::string>(GNE_ATTR_FROM_CHARGINGSTATION, planParentID, parsedOk, "");
70 0 : toChargingStation = attrs.getOpt<std::string>(SUMO_ATTR_CHARGING_STATION, planParentID, parsedOk, "");
71 : // parking areas
72 0 : fromParkingArea = attrs.getOpt<std::string>(GNE_ATTR_FROM_PARKINGAREA, planParentID, parsedOk, "");
73 0 : toParkingArea = attrs.getOpt<std::string>(SUMO_ATTR_PARKING_AREA, planParentID, parsedOk, "");
74 : // routes
75 0 : fromRoute = attrs.getOpt<std::string>(GNE_ATTR_FROM_ROUTE, planParentID, parsedOk, "");
76 0 : toRoute = attrs.getOpt<std::string>(SUMO_ATTR_ROUTE, planParentID, parsedOk, "");
77 : // update from attributes
78 0 : updateFromAttributes(sumoBaseObject);
79 : }
80 0 : }
81 :
82 :
83 : void
84 0 : CommonXMLStructure::PlanParameters::clear() {
85 : fromJunction.clear();
86 : toJunction.clear();
87 : fromEdge.clear();
88 : toEdge.clear();
89 : fromTAZ.clear();
90 : toTAZ.clear();
91 : fromBusStop.clear();
92 : toBusStop.clear();
93 : fromTrainStop.clear();
94 : toTrainStop.clear();
95 : fromContainerStop.clear();
96 : toContainerStop.clear();
97 : fromChargingStation.clear();
98 : toChargingStation.clear();
99 : fromParkingArea.clear();
100 : toParkingArea.clear();
101 : consecutiveEdges.clear();
102 : fromRoute.clear();
103 : toRoute.clear();
104 0 : }
105 :
106 :
107 : bool
108 0 : CommonXMLStructure::PlanParameters::isSingleEdgePlan() const {
109 0 : if (fromEdge.empty()) {
110 : return false;
111 : } else {
112 0 : return getNumberOfDefinedParameters() == 1;
113 : }
114 : }
115 :
116 :
117 : int
118 0 : CommonXMLStructure::PlanParameters::getNumberOfDefinedParameters() const {
119 0 : return (int)consecutiveEdges.size() +
120 0 : (fromJunction.empty() ? 0 : 1) +
121 0 : (toJunction.empty() ? 0 : 1) +
122 0 : (fromEdge.empty() ? 0 : 1) +
123 0 : (toEdge.empty() ? 0 : 1) +
124 0 : (fromTAZ.empty() ? 0 : 1) +
125 0 : (toTAZ.empty() ? 0 : 1) +
126 0 : (fromBusStop.empty() ? 0 : 1) +
127 0 : (toBusStop.empty() ? 0 : 1) +
128 0 : (fromTrainStop.empty() ? 0 : 1) +
129 0 : (toTrainStop.empty() ? 0 : 1) +
130 0 : (fromContainerStop.empty() ? 0 : 1) +
131 0 : (toContainerStop.empty() ? 0 : 1) +
132 0 : (fromChargingStation.empty() ? 0 : 1) +
133 0 : (toChargingStation.empty() ? 0 : 1) +
134 0 : (fromParkingArea.empty() ? 0 : 1) +
135 0 : (toParkingArea.empty() ? 0 : 1) +
136 0 : (fromRoute.empty() ? 0 : 1) +
137 0 : (toRoute.empty() ? 0 : 1);
138 : }
139 :
140 :
141 : const CommonXMLStructure::SumoBaseObject*
142 0 : CommonXMLStructure::PlanParameters::getPreviousPlanObj(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) const {
143 : // first check if object exist
144 0 : if (sumoBaseObject == nullptr) {
145 : return nullptr;
146 : }
147 : // check if object has parent
148 0 : const CommonXMLStructure::SumoBaseObject* parentObject = sumoBaseObject->getParentSumoBaseObject();
149 0 : if (parentObject == nullptr) {
150 : return nullptr;
151 : }
152 : // check number of children
153 0 : if (parentObject->getSumoBaseObjectChildren().size() < 2) {
154 : return nullptr;
155 : }
156 : // search position of the given plan obj in the parent children
157 0 : const auto objIterator = std::find(parentObject->getSumoBaseObjectChildren().begin(), parentObject->getSumoBaseObjectChildren().end(), sumoBaseObject);
158 : // if obj is the first plan of person/container parent, then return null. If not, return previous object
159 0 : if (objIterator == parentObject->getSumoBaseObjectChildren().begin()) {
160 : return nullptr;
161 : } else {
162 0 : return *(objIterator - 1);
163 : }
164 : }
165 :
166 :
167 : void
168 0 : CommonXMLStructure::PlanParameters::updateFromAttributes(const CommonXMLStructure::SumoBaseObject* sumoBaseObject) {
169 : // check if previous plan object was defined but not the from
170 0 : const auto previousPlanObj = getPreviousPlanObj(sumoBaseObject);
171 0 : if (previousPlanObj) {
172 : // ge previous plan parameters
173 0 : const auto previousPlanParameters = previousPlanObj->getPlanParameters();
174 0 : if (!previousPlanParameters.toEdge.empty()) {
175 : // edge (to)
176 0 : resetPreviousFromAttributes(previousPlanObj, "edge", previousPlanParameters.toEdge);
177 0 : fromEdge = previousPlanParameters.toEdge;
178 0 : } else if (!previousPlanParameters.consecutiveEdges.empty()) {
179 : // consecutive edge
180 0 : resetPreviousFromAttributes(previousPlanObj, "consecutive edge", previousPlanParameters.consecutiveEdges.back());
181 0 : fromEdge = previousPlanParameters.consecutiveEdges.back();
182 0 : } else if (!previousPlanParameters.toRoute.empty()) {
183 : // route
184 0 : resetPreviousFromAttributes(previousPlanObj, "route edge", previousPlanParameters.toRoute);
185 0 : fromRoute = previousPlanParameters.toRoute;
186 0 : } else if (!previousPlanParameters.toJunction.empty()) {
187 : // junction
188 0 : resetPreviousFromAttributes(previousPlanObj, "junction", previousPlanParameters.toJunction);
189 0 : fromJunction = previousPlanParameters.toJunction;
190 0 : } else if (!previousPlanParameters.toTAZ.empty()) {
191 : // TAZ
192 0 : resetPreviousFromAttributes(previousPlanObj, "TAZ", previousPlanParameters.toTAZ);
193 0 : fromTAZ = previousPlanParameters.toTAZ;
194 0 : } else if (!previousPlanParameters.toBusStop.empty()) {
195 : // busStop
196 0 : resetPreviousFromAttributes(previousPlanObj, "bus stop", previousPlanParameters.toBusStop);
197 0 : fromBusStop = previousPlanParameters.toBusStop;
198 0 : } else if (!previousPlanParameters.toTrainStop.empty()) {
199 : // trainStop
200 0 : resetPreviousFromAttributes(previousPlanObj, "train stop", previousPlanParameters.toTrainStop);
201 0 : fromTrainStop = previousPlanParameters.toTrainStop;
202 0 : } else if (!previousPlanParameters.toContainerStop.empty()) {
203 : // containerStop
204 0 : resetPreviousFromAttributes(previousPlanObj, "container stop", previousPlanParameters.toContainerStop);
205 0 : fromContainerStop = previousPlanParameters.toContainerStop;
206 0 : } else if (!previousPlanParameters.toChargingStation.empty()) {
207 : // chargingStation
208 0 : resetPreviousFromAttributes(previousPlanObj, "charging station", previousPlanParameters.toChargingStation);
209 0 : fromChargingStation = previousPlanParameters.toChargingStation;
210 0 : } else if (!previousPlanParameters.toParkingArea.empty()) {
211 : // parkingArea
212 0 : resetPreviousFromAttributes(previousPlanObj, "parking area", previousPlanParameters.toParkingArea);
213 0 : fromParkingArea = previousPlanParameters.toParkingArea;
214 : }
215 0 : }
216 0 : }
217 :
218 :
219 : void
220 0 : CommonXMLStructure::PlanParameters::resetPreviousFromAttributes(const CommonXMLStructure::SumoBaseObject* previousPlanObj,
221 : const std::string& newType, const std::string& newId) const {
222 0 : if (!fromEdge.empty()) {
223 0 : writeIgnoringMessage(previousPlanObj, "edge", fromEdge, newType, newId);
224 : }
225 0 : if (!fromJunction.empty()) {
226 0 : writeIgnoringMessage(previousPlanObj, "junction", fromJunction, newType, newId);
227 : }
228 0 : if (!fromTAZ.empty()) {
229 0 : writeIgnoringMessage(previousPlanObj, "TAZ", fromTAZ, newType, newId);
230 : }
231 0 : if (!fromBusStop.empty()) {
232 0 : writeIgnoringMessage(previousPlanObj, "bus stop", fromBusStop, newType, newId);
233 : }
234 0 : if (!fromTrainStop.empty()) {
235 0 : writeIgnoringMessage(previousPlanObj, "train stop", fromTrainStop, newType, newId);
236 : }
237 0 : if (!fromContainerStop.empty()) {
238 0 : writeIgnoringMessage(previousPlanObj, "container stop", fromContainerStop, newType, newId);
239 : }
240 0 : if (!fromChargingStation.empty()) {
241 0 : writeIgnoringMessage(previousPlanObj, "charging station", fromChargingStation, newType, newId);
242 : }
243 0 : if (!fromParkingArea.empty()) {
244 0 : writeIgnoringMessage(previousPlanObj, "parking area", fromParkingArea, newType, newId);
245 : }
246 0 : }
247 :
248 :
249 : void
250 0 : CommonXMLStructure::PlanParameters::writeIgnoringMessage(const CommonXMLStructure::SumoBaseObject* previousPlanObj,
251 : const std::string& oldType, const std::string& oldId, const std::string& newType, const std::string& newId) const {
252 0 : WRITE_WARNING(TLF("Ignoring from % '%' used in % '%' and using instead the previous end element % '%'",
253 : oldType, oldId,
254 : toString(previousPlanObj->getParentSumoBaseObject()->getTag()),
255 : previousPlanObj->getParentSumoBaseObject()->getStringAttribute(SUMO_ATTR_ID),
256 : newType, newId));
257 0 : }
258 :
259 : // ---------------------------------------------------------------------------
260 : // CommonXMLStructure::SumoBaseObject - methods
261 : // ---------------------------------------------------------------------------
262 :
263 0 : CommonXMLStructure::SumoBaseObject::SumoBaseObject(SumoBaseObject* parent) :
264 0 : mySumoBaseObjectParent(parent),
265 0 : myVehicleTypeParameter("") {
266 : // add this SumoBaseObject into parent children
267 0 : if (mySumoBaseObjectParent) {
268 0 : mySumoBaseObjectParent->addSumoBaseObjectChild(this);
269 : }
270 0 : }
271 :
272 :
273 0 : CommonXMLStructure::SumoBaseObject::~SumoBaseObject() {
274 : // remove this SumoBaseObject from parent children
275 0 : if (mySumoBaseObjectParent) {
276 0 : mySumoBaseObjectParent->removeSumoBaseObjectChild(this);
277 : }
278 : // delete all SumoBaseObjectChildrens
279 0 : while (mySumoBaseObjectChildren.size() > 0) {
280 0 : delete mySumoBaseObjectChildren.back();
281 : }
282 0 : }
283 :
284 :
285 : void
286 0 : CommonXMLStructure::SumoBaseObject::clear() {
287 : // reset tag
288 0 : myTag = SUMO_TAG_NOTHING;
289 : // reset vClass
290 0 : myVClass = SVC_IGNORING;
291 : // clear containers
292 : myStringAttributes.clear();
293 : myIntAttributes.clear();
294 : myDoubleAttributes.clear();
295 : myBoolAttributes.clear();
296 : myPositionAttributes.clear();
297 : myTimeAttributes.clear();
298 : myColorAttributes.clear();
299 : myStringListAttributes.clear();
300 : myDoubleListAttributes.clear();
301 : myPositionVectorAttributes.clear();
302 : myParameters.clear();
303 : mySumoBaseObjectChildren.clear();
304 : // reset flags
305 0 : myDefinedVehicleTypeParameter = false;
306 0 : myDefinedVehicleParameter = false;
307 0 : myDefinedStopParameter = false;
308 : // delete all SumoBaseObjectChildrens
309 0 : while (mySumoBaseObjectChildren.size() > 0) {
310 0 : delete mySumoBaseObjectChildren.back();
311 : }
312 0 : }
313 :
314 :
315 : void
316 0 : CommonXMLStructure::SumoBaseObject::setTag(const SumoXMLTag tag) {
317 0 : myTag = tag;
318 0 : }
319 :
320 :
321 : void
322 0 : CommonXMLStructure::SumoBaseObject::markAsCreated() {
323 0 : myWasCreated = true;
324 0 : }
325 :
326 :
327 : SumoXMLTag
328 0 : CommonXMLStructure::SumoBaseObject::getTag() const {
329 0 : return myTag;
330 : }
331 :
332 :
333 : bool
334 0 : CommonXMLStructure::SumoBaseObject::wasCreated() const {
335 0 : return myWasCreated;
336 : }
337 :
338 :
339 : CommonXMLStructure::SumoBaseObject*
340 0 : CommonXMLStructure::SumoBaseObject::getParentSumoBaseObject() const {
341 0 : return mySumoBaseObjectParent;
342 : }
343 :
344 :
345 : std::map<std::string, std::string>
346 0 : CommonXMLStructure::SumoBaseObject::getAllAttributes() const {
347 : std::map<std::string, std::string> result;
348 0 : for (const auto& attr : myStringAttributes) {
349 0 : result[toString(attr.first)] = attr.second;
350 : }
351 0 : for (const auto& attr : myIntAttributes) {
352 0 : result[toString(attr.first)] = toString(attr.second);
353 : }
354 0 : for (const auto& attr : myDoubleAttributes) {
355 0 : result[toString(attr.first)] = toString(attr.second);
356 : }
357 0 : for (const auto& attr : myBoolAttributes) {
358 0 : result[toString(attr.first)] = toString(attr.second);
359 : }
360 0 : for (const auto& attr : myPositionAttributes) {
361 0 : result[toString(attr.first)] = toString(attr.second);
362 : }
363 0 : for (const auto& attr : myTimeAttributes) {
364 0 : result[toString(attr.first)] = time2string(attr.second);
365 : }
366 0 : for (const auto& attr : myColorAttributes) {
367 0 : result[toString(attr.first)] = toString(attr.second);
368 : }
369 0 : for (const auto& attr : myStringListAttributes) {
370 0 : result[toString(attr.first)] = toString(attr.second);
371 : }
372 0 : for (const auto& attr : myDoubleListAttributes) {
373 0 : result[toString(attr.first)] = toString(attr.second);
374 : }
375 0 : for (const auto& attr : myPositionVectorAttributes) {
376 0 : result[toString(attr.first)] = toString(attr.second);
377 : }
378 0 : return result;
379 : }
380 :
381 :
382 : const std::string&
383 0 : CommonXMLStructure::SumoBaseObject::getStringAttribute(const SumoXMLAttr attr) const {
384 0 : if (hasStringAttribute(attr)) {
385 0 : return myStringAttributes.at(attr);
386 : } else {
387 0 : handleAttributeError(attr, "string");
388 0 : throw ProcessError();
389 : }
390 : }
391 :
392 :
393 : int
394 0 : CommonXMLStructure::SumoBaseObject::getIntAttribute(const SumoXMLAttr attr) const {
395 0 : if (hasIntAttribute(attr)) {
396 0 : return myIntAttributes.at(attr);
397 : } else {
398 0 : handleAttributeError(attr, "int");
399 0 : throw ProcessError();
400 : }
401 : }
402 :
403 :
404 : double
405 0 : CommonXMLStructure::SumoBaseObject::getDoubleAttribute(const SumoXMLAttr attr) const {
406 0 : if (hasDoubleAttribute(attr)) {
407 0 : return myDoubleAttributes.at(attr);
408 : } else {
409 0 : handleAttributeError(attr, "double");
410 0 : throw ProcessError();
411 : }
412 : }
413 :
414 :
415 : bool
416 0 : CommonXMLStructure::SumoBaseObject::getBoolAttribute(const SumoXMLAttr attr) const {
417 0 : if (hasBoolAttribute(attr)) {
418 0 : return myBoolAttributes.at(attr);
419 : } else {
420 0 : handleAttributeError(attr, "bool");
421 0 : throw ProcessError();
422 : }
423 : }
424 :
425 :
426 : const Position&
427 0 : CommonXMLStructure::SumoBaseObject::getPositionAttribute(const SumoXMLAttr attr) const {
428 0 : if (hasPositionAttribute(attr)) {
429 0 : return myPositionAttributes.at(attr);
430 : } else {
431 0 : handleAttributeError(attr, "position");
432 0 : throw ProcessError();
433 : }
434 : }
435 :
436 :
437 : SUMOTime
438 0 : CommonXMLStructure::SumoBaseObject::getTimeAttribute(const SumoXMLAttr attr) const {
439 0 : if (hasTimeAttribute(attr)) {
440 0 : return myTimeAttributes.at(attr);
441 : } else {
442 0 : handleAttributeError(attr, "time");
443 0 : throw ProcessError();
444 : }
445 : }
446 :
447 :
448 : SUMOTime
449 0 : CommonXMLStructure::SumoBaseObject::getPeriodAttribute() const {
450 0 : SumoXMLAttr attr = SUMO_ATTR_PERIOD;
451 0 : if (hasTimeAttribute(attr)) {
452 0 : return myTimeAttributes.at(attr);
453 : } else {
454 : // try 'freq' as alias for 'period'
455 0 : attr = SUMO_ATTR_FREQUENCY;
456 0 : if (hasTimeAttribute(attr)) {
457 0 : return myTimeAttributes.at(attr);
458 : }
459 0 : handleAttributeError(SUMO_ATTR_PERIOD, "time");
460 0 : throw ProcessError();
461 : }
462 : }
463 :
464 :
465 : const RGBColor&
466 0 : CommonXMLStructure::SumoBaseObject::getColorAttribute(const SumoXMLAttr attr) const {
467 0 : if (hasColorAttribute(attr)) {
468 0 : return myColorAttributes.at(attr);
469 : } else {
470 0 : handleAttributeError(attr, "color");
471 0 : throw ProcessError();
472 : }
473 : }
474 :
475 :
476 : const std::vector<std::string>&
477 0 : CommonXMLStructure::SumoBaseObject::getStringListAttribute(const SumoXMLAttr attr) const {
478 0 : if (hasStringListAttribute(attr)) {
479 0 : return myStringListAttributes.at(attr);
480 : } else {
481 0 : handleAttributeError(attr, "string list");
482 0 : throw ProcessError();
483 : }
484 : }
485 :
486 :
487 : const std::vector<double>&
488 0 : CommonXMLStructure::SumoBaseObject::getDoubleListAttribute(const SumoXMLAttr attr) const {
489 0 : if (hasDoubleListAttribute(attr)) {
490 0 : return myDoubleListAttributes.at(attr);
491 : } else {
492 0 : handleAttributeError(attr, "double list");
493 0 : throw ProcessError();
494 : }
495 : }
496 :
497 :
498 : const PositionVector&
499 0 : CommonXMLStructure::SumoBaseObject::getPositionVectorAttribute(const SumoXMLAttr attr) const {
500 0 : if (hasPositionVectorAttribute(attr)) {
501 0 : return myPositionVectorAttributes.at(attr);
502 : } else {
503 0 : handleAttributeError(attr, "position vector");
504 0 : throw ProcessError();
505 : }
506 : }
507 :
508 :
509 : SUMOVehicleClass
510 0 : CommonXMLStructure::SumoBaseObject::getVClass() const {
511 0 : return myVClass;
512 : }
513 :
514 :
515 : const SUMOVTypeParameter&
516 0 : CommonXMLStructure::SumoBaseObject::getVehicleTypeParameter() const {
517 0 : if (myDefinedVehicleTypeParameter) {
518 0 : return myVehicleTypeParameter;
519 : } else {
520 0 : throw ProcessError(TL("Undefined vehicleType parameter"));
521 : }
522 : }
523 :
524 :
525 : const SUMOVehicleParameter&
526 0 : CommonXMLStructure::SumoBaseObject::getVehicleParameter() const {
527 0 : if (myDefinedVehicleParameter) {
528 0 : return myVehicleParameter;
529 : } else {
530 0 : throw ProcessError(TL("Undefined vehicle parameter"));
531 : }
532 : }
533 :
534 :
535 : const SUMOVehicleParameter::Stop&
536 0 : CommonXMLStructure::SumoBaseObject::getStopParameter() const {
537 0 : if (myDefinedStopParameter) {
538 0 : return myStopParameter;
539 : } else {
540 0 : throw ProcessError(TL("Undefined stop parameter"));
541 : }
542 :
543 : }
544 :
545 :
546 : const std::map<std::string, std::string>&
547 0 : CommonXMLStructure::SumoBaseObject::getParameters() const {
548 0 : return myParameters;
549 : }
550 :
551 :
552 : const CommonXMLStructure::PlanParameters&
553 0 : CommonXMLStructure::SumoBaseObject::getPlanParameters() const {
554 0 : return myPlanParameters;
555 : }
556 :
557 :
558 : const std::vector<CommonXMLStructure::SumoBaseObject*>&
559 0 : CommonXMLStructure::SumoBaseObject::getSumoBaseObjectChildren() const {
560 0 : return mySumoBaseObjectChildren;
561 : }
562 :
563 :
564 : bool
565 0 : CommonXMLStructure::SumoBaseObject::hasStringAttribute(const SumoXMLAttr attr) const {
566 0 : return myStringAttributes.count(attr) > 0;
567 : }
568 :
569 :
570 : bool
571 0 : CommonXMLStructure::SumoBaseObject::hasIntAttribute(const SumoXMLAttr attr) const {
572 0 : return myIntAttributes.count(attr) > 0;
573 : }
574 :
575 :
576 : bool
577 0 : CommonXMLStructure::SumoBaseObject::hasDoubleAttribute(const SumoXMLAttr attr) const {
578 0 : return myDoubleAttributes.count(attr) > 0;
579 : }
580 :
581 :
582 : bool
583 0 : CommonXMLStructure::SumoBaseObject::hasBoolAttribute(const SumoXMLAttr attr) const {
584 0 : return myBoolAttributes.count(attr) > 0;
585 : }
586 :
587 :
588 : bool
589 0 : CommonXMLStructure::SumoBaseObject::hasPositionAttribute(const SumoXMLAttr attr) const {
590 0 : return myPositionAttributes.count(attr) > 0;
591 : }
592 :
593 :
594 : bool
595 0 : CommonXMLStructure::SumoBaseObject::hasTimeAttribute(const SumoXMLAttr attr) const {
596 0 : return myTimeAttributes.count(attr) > 0;
597 : }
598 :
599 :
600 : bool
601 0 : CommonXMLStructure::SumoBaseObject::hasColorAttribute(const SumoXMLAttr attr) const {
602 0 : return myColorAttributes.count(attr) > 0;
603 : }
604 :
605 :
606 : bool
607 0 : CommonXMLStructure::SumoBaseObject::hasStringListAttribute(const SumoXMLAttr attr) const {
608 0 : return myStringListAttributes.count(attr) > 0;
609 : }
610 :
611 :
612 : bool
613 0 : CommonXMLStructure::SumoBaseObject::hasDoubleListAttribute(const SumoXMLAttr attr) const {
614 0 : return myDoubleListAttributes.count(attr) > 0;
615 : }
616 :
617 :
618 : bool
619 0 : CommonXMLStructure::SumoBaseObject::hasPositionVectorAttribute(const SumoXMLAttr attr) const {
620 0 : return myPositionVectorAttributes.count(attr) > 0;
621 : }
622 :
623 :
624 : void
625 0 : CommonXMLStructure::SumoBaseObject::addStringAttribute(const SumoXMLAttr attr, const std::string& value) {
626 0 : myStringAttributes[attr] = value;
627 0 : }
628 :
629 :
630 : void
631 0 : CommonXMLStructure::SumoBaseObject::addIntAttribute(const SumoXMLAttr attr, const int value) {
632 0 : myIntAttributes[attr] = value;
633 0 : }
634 :
635 :
636 : void
637 0 : CommonXMLStructure::SumoBaseObject::addDoubleAttribute(const SumoXMLAttr attr, const double value) {
638 0 : myDoubleAttributes[attr] = value;
639 0 : }
640 :
641 :
642 : void
643 0 : CommonXMLStructure::SumoBaseObject::addBoolAttribute(const SumoXMLAttr attr, const bool value) {
644 0 : myBoolAttributes[attr] = value;
645 0 : }
646 :
647 :
648 : void
649 0 : CommonXMLStructure::SumoBaseObject::addPositionAttribute(const SumoXMLAttr attr, const Position& value) {
650 0 : myPositionAttributes[attr] = value;
651 0 : }
652 :
653 :
654 : void
655 0 : CommonXMLStructure::SumoBaseObject::addTimeAttribute(const SumoXMLAttr attr, const SUMOTime value) {
656 0 : myTimeAttributes[attr] = value;
657 0 : }
658 :
659 :
660 : void
661 0 : CommonXMLStructure::SumoBaseObject::addColorAttribute(const SumoXMLAttr attr, const RGBColor& value) {
662 0 : myColorAttributes[attr] = value;
663 0 : }
664 :
665 :
666 : void
667 0 : CommonXMLStructure::SumoBaseObject::addStringListAttribute(const SumoXMLAttr attr, const std::vector<std::string>& value) {
668 0 : myStringListAttributes[attr] = value;
669 0 : }
670 :
671 :
672 : void
673 0 : CommonXMLStructure::SumoBaseObject::addDoubleListAttribute(const SumoXMLAttr attr, const std::vector<double>& value) {
674 0 : myDoubleListAttributes[attr] = value;
675 0 : }
676 :
677 :
678 : void
679 0 : CommonXMLStructure::SumoBaseObject::addPositionVectorAttribute(const SumoXMLAttr attr, const PositionVector& value) {
680 0 : myPositionVectorAttributes[attr] = value;
681 0 : }
682 :
683 :
684 : void
685 0 : CommonXMLStructure::SumoBaseObject::addParameter(const std::string& key, const std::string& value) {
686 : // check if we have to insert in vType, vehicle or stop parameters
687 0 : if (myDefinedVehicleTypeParameter) {
688 0 : myVehicleTypeParameter.setParameter(key, value);
689 0 : } else if (myDefinedVehicleParameter) {
690 0 : myVehicleParameter.setParameter(key, value);
691 0 : } else if (myDefinedStopParameter) {
692 0 : myStopParameter.setParameter(key, value);
693 : } else {
694 0 : myParameters[key] = value;
695 : }
696 0 : }
697 :
698 :
699 : void
700 0 : CommonXMLStructure::SumoBaseObject::setVClass(SUMOVehicleClass vClass) {
701 0 : myVClass = vClass;
702 0 : }
703 :
704 :
705 : void
706 0 : CommonXMLStructure::SumoBaseObject::setVehicleTypeParameter(const SUMOVTypeParameter* vehicleTypeParameter) {
707 0 : myVehicleTypeParameter = *vehicleTypeParameter;
708 0 : myDefinedVehicleTypeParameter = true;
709 : // set attribute id
710 0 : addStringAttribute(SUMO_ATTR_ID, myVehicleTypeParameter.id);
711 0 : }
712 :
713 :
714 : void
715 0 : CommonXMLStructure::SumoBaseObject::setVehicleParameter(const SUMOVehicleParameter* vehicleParameter) {
716 0 : myVehicleParameter = *vehicleParameter;
717 0 : myDefinedVehicleParameter = true;
718 : // set attribute id
719 0 : if (!myVehicleParameter.id.empty()) {
720 0 : addStringAttribute(SUMO_ATTR_ID, myVehicleParameter.id);
721 : }
722 : // set attribute route
723 0 : if (!vehicleParameter->routeid.empty()) {
724 0 : addStringAttribute(SUMO_ATTR_ROUTE, myVehicleParameter.routeid);
725 : }
726 0 : }
727 :
728 :
729 : void
730 0 : CommonXMLStructure::SumoBaseObject::setStopParameter(const SUMOVehicleParameter::Stop& stopParameter) {
731 0 : myStopParameter = stopParameter;
732 0 : myDefinedStopParameter = true;
733 : // set attribute edge
734 0 : if (!myStopParameter.edge.empty()) {
735 0 : addStringAttribute(SUMO_ATTR_EDGE, myStopParameter.edge);
736 : }
737 : // set attribute lane
738 0 : if (!myStopParameter.lane.empty()) {
739 0 : addStringAttribute(SUMO_ATTR_LANE, myStopParameter.lane);
740 : }
741 : // set attribute busStop
742 0 : if (!myStopParameter.busstop.empty()) {
743 0 : addStringAttribute(SUMO_ATTR_BUS_STOP, myStopParameter.busstop);
744 : }
745 : // set attribute containerstop
746 0 : if (!myStopParameter.containerstop.empty()) {
747 0 : addStringAttribute(SUMO_ATTR_CONTAINER_STOP, myStopParameter.containerstop);
748 : }
749 : // set attribute parkingarea
750 0 : if (!myStopParameter.parkingarea.empty()) {
751 0 : addStringAttribute(SUMO_ATTR_PARKING_AREA, myStopParameter.parkingarea);
752 : }
753 : // set attribute chargingStation
754 0 : if (!myStopParameter.chargingStation.empty()) {
755 0 : addStringAttribute(SUMO_ATTR_CHARGING_STATION, myStopParameter.chargingStation);
756 : }
757 0 : }
758 :
759 :
760 : void
761 0 : CommonXMLStructure::SumoBaseObject::setPlanParameters(const CommonXMLStructure::PlanParameters& planParameters) {
762 0 : myPlanParameters = planParameters;
763 0 : }
764 :
765 : void
766 0 : CommonXMLStructure::SumoBaseObject::addSumoBaseObjectChild(SumoBaseObject* sumoBaseObject) {
767 : // just add it into mySumoBaseObjectChildren
768 0 : mySumoBaseObjectChildren.push_back(sumoBaseObject);
769 0 : }
770 :
771 :
772 : void
773 0 : CommonXMLStructure::SumoBaseObject::removeSumoBaseObjectChild(SumoBaseObject* sumoBaseObject) {
774 : // find sumoBaseObject
775 0 : auto it = std::find(mySumoBaseObjectChildren.begin(), mySumoBaseObjectChildren.end(), sumoBaseObject);
776 : // check iterator
777 0 : if (it != mySumoBaseObjectChildren.end()) {
778 0 : mySumoBaseObjectChildren.erase(it);
779 : }
780 0 : }
781 :
782 :
783 : void
784 0 : CommonXMLStructure::SumoBaseObject::handleAttributeError(const SumoXMLAttr attr, const std::string& type) const {
785 0 : WRITE_ERRORF(TL("Trying to get undefined % attribute '%' in SUMOBaseObject '%'"), type, toString(attr), toString(myTag));
786 0 : }
787 :
788 : // ---------------------------------------------------------------------------
789 : // CommonXMLStructure - methods
790 : // ---------------------------------------------------------------------------
791 :
792 0 : CommonXMLStructure::CommonXMLStructure() :
793 0 : mySumoBaseObjectRoot(nullptr),
794 0 : myCurrentSumoBaseObject(nullptr) {
795 :
796 0 : }
797 :
798 :
799 0 : CommonXMLStructure::~CommonXMLStructure() {
800 : // delete mySumoBaseObjectRoot (this will also delete all SumoBaseObjectChildrens)
801 0 : if (mySumoBaseObjectRoot) {
802 0 : delete mySumoBaseObjectRoot;
803 : }
804 0 : }
805 :
806 :
807 : void
808 0 : CommonXMLStructure::openSUMOBaseOBject() {
809 : // first check if root is empty
810 0 : if (mySumoBaseObjectRoot == nullptr) {
811 : // create root
812 0 : mySumoBaseObjectRoot = new SumoBaseObject(nullptr);
813 : // set tag
814 0 : mySumoBaseObjectRoot->setTag(SUMO_TAG_ROOTFILE);
815 : // update last inserted Root
816 0 : myCurrentSumoBaseObject = mySumoBaseObjectRoot;
817 : } else {
818 : // create new node
819 0 : SumoBaseObject* newSumoBaseObject = new SumoBaseObject(myCurrentSumoBaseObject);
820 : // update last inserted node
821 0 : myCurrentSumoBaseObject = newSumoBaseObject;
822 : }
823 0 : }
824 :
825 :
826 : void
827 0 : CommonXMLStructure::closeSUMOBaseOBject() {
828 : // check that myCurrentSumoBaseObject is valid
829 0 : if (myCurrentSumoBaseObject) {
830 : // check if last inserted SumoBaseObject is the root
831 0 : if (myCurrentSumoBaseObject->getParentSumoBaseObject() == nullptr) {
832 : // reset both pointers
833 0 : myCurrentSumoBaseObject = nullptr;
834 0 : mySumoBaseObjectRoot = nullptr;
835 : } else {
836 : // update last inserted SumoBaseObject
837 0 : myCurrentSumoBaseObject = myCurrentSumoBaseObject->getParentSumoBaseObject();
838 : }
839 : }
840 0 : }
841 :
842 :
843 : void
844 0 : CommonXMLStructure::abortSUMOBaseOBject() {
845 : // delete current sumo base object and use their parent as sumo base object
846 0 : if (myCurrentSumoBaseObject) {
847 0 : if (myCurrentSumoBaseObject == mySumoBaseObjectRoot) {
848 0 : delete myCurrentSumoBaseObject;
849 0 : myCurrentSumoBaseObject = nullptr;
850 0 : mySumoBaseObjectRoot = nullptr;
851 : } else {
852 0 : auto parentSumoBaseObject = myCurrentSumoBaseObject->getParentSumoBaseObject();
853 0 : delete myCurrentSumoBaseObject;
854 0 : myCurrentSumoBaseObject = parentSumoBaseObject;
855 : }
856 : }
857 0 : }
858 :
859 :
860 : CommonXMLStructure::SumoBaseObject*
861 0 : CommonXMLStructure::getSumoBaseObjectRoot() const {
862 0 : return mySumoBaseObjectRoot;
863 : }
864 :
865 :
866 : CommonXMLStructure::SumoBaseObject*
867 0 : CommonXMLStructure::getCurrentSumoBaseObject() const {
868 0 : return myCurrentSumoBaseObject;
869 : }
870 :
871 : /****************************************************************************/
|