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