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 SUMOVehicleParameter.cpp
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Tue, 31.03.2009
19 : ///
20 : // Structure representing possible vehicle parameter
21 : /****************************************************************************/
22 : #include <config.h>
23 : #include <utils/common/MsgHandler.h>
24 : #include <utils/common/StringTokenizer.h>
25 : #include <utils/common/StringUtils.h>
26 : #include <utils/common/ToString.h>
27 : #include <utils/common/RandHelper.h>
28 : #include <utils/iodevices/OutputDevice.h>
29 : #include <utils/options/OptionsCont.h>
30 :
31 : #include "SUMOVehicleParameter.h"
32 :
33 : // ===========================================================================
34 : // member method definitions
35 : // ===========================================================================
36 :
37 997431 : SUMOVehicleParameter::SUMOVehicleParameter()
38 1994862 : : tag(SUMO_TAG_NOTHING), vtypeid(DEFAULT_VTYPE_ID), color(RGBColor::DEFAULT_COLOR),
39 997431 : depart(-1), departProcedure(DepartDefinition::GIVEN),
40 997431 : departLane(0), departLaneProcedure(DepartLaneDefinition::DEFAULT),
41 997431 : departPos(0), departPosProcedure(DepartPosDefinition::DEFAULT),
42 997431 : departPosLat(0), departPosLatProcedure(DepartPosLatDefinition::DEFAULT),
43 997431 : departSpeed(-1), departSpeedProcedure(DepartSpeedDefinition::DEFAULT),
44 997431 : departEdge(0), departEdgeProcedure(RouteIndexDefinition::DEFAULT),
45 997431 : arrivalLane(0), arrivalLaneProcedure(ArrivalLaneDefinition::DEFAULT),
46 997431 : arrivalPos(0), arrivalPosProcedure(ArrivalPosDefinition::DEFAULT),
47 997431 : arrivalPosLat(0), arrivalPosLatProcedure(ArrivalPosLatDefinition::DEFAULT),
48 997431 : arrivalSpeed(-1), arrivalSpeedProcedure(ArrivalSpeedDefinition::DEFAULT),
49 997431 : arrivalEdge(-1), arrivalEdgeProcedure(RouteIndexDefinition::DEFAULT),
50 997431 : repetitionNumber(-1),
51 997431 : repetitionsDone(-1),
52 997431 : repetitionOffset(-1),
53 997431 : repetitionTotalOffset(0),
54 997431 : repetitionProbability(-1),
55 997431 : poissonRate(0),
56 997431 : repetitionEnd(-1),
57 997431 : line(), fromTaz(), toTaz(), personNumber(0), containerNumber(0),
58 997431 : speedFactor(-1),
59 997431 : calibratorSpeed(-1),
60 997431 : insertionChecks((int)InsertionCheck::ALL),
61 997431 : parametersSet(0)
62 997431 : { }
63 :
64 :
65 10895490 : SUMOVehicleParameter::~SUMOVehicleParameter() {
66 10895490 : }
67 :
68 :
69 : bool
70 282280 : SUMOVehicleParameter::defaultOptionOverrides(const OptionsCont& oc, const std::string& optionName) const {
71 564560 : return oc.exists(optionName) && oc.isSet(optionName) && oc.getBool("defaults-override");
72 : }
73 :
74 :
75 : void
76 384805 : SUMOVehicleParameter::write(OutputDevice& dev, const OptionsCont& oc, const SumoXMLTag altTag, const std::string& typeID) const {
77 384805 : if (!id.empty()) {
78 : // only used by calibrator flows
79 384805 : dev.openTag(altTag).writeAttr(SUMO_ATTR_ID, id);
80 : }
81 384805 : if (typeID == "") {
82 360465 : if (wasSet(VEHPARS_VTYPE_SET)) {
83 31632 : dev.writeAttr(SUMO_ATTR_TYPE, vtypeid);
84 : }
85 : } else {
86 : dev.writeAttr(SUMO_ATTR_TYPE, typeID);
87 : }
88 : // write depart depending of tag
89 : if (altTag == SUMO_TAG_FLOW
90 384805 : || altTag == SUMO_TAG_PERSONFLOW
91 : || altTag == SUMO_TAG_CONTAINERFLOW
92 : || altTag == GNE_TAG_FLOW_ROUTE
93 : || altTag == GNE_TAG_FLOW_WITHROUTE
94 : || altTag == SUMO_TAG_FLOWSTATE) {
95 148 : dev.writeAttr(SUMO_ATTR_BEGIN, getDepart());
96 : } else {
97 769462 : dev.writeAttr(SUMO_ATTR_DEPART, getDepart());
98 : }
99 : // optional parameter
100 : // departlane
101 487541 : if (wasSet(VEHPARS_DEPARTLANE_SET) && !defaultOptionOverrides(oc, "departlane")) {
102 205312 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, getDepartLane());
103 469061 : } else if (oc.exists("departlane") && oc.isSet("departlane")) {
104 676 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTLANE, oc.getString("departlane"));
105 : }
106 : // departpos
107 424125 : if (wasSet(VEHPARS_DEPARTPOS_SET) && !defaultOptionOverrides(oc, "departpos")) {
108 78512 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, getDepartPos());
109 613447 : } else if (oc.exists("departpos") && oc.isSet("departpos")) {
110 676 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS, oc.getString("departpos"));
111 : }
112 : // departPosLat
113 384805 : if (wasSet(VEHPARS_DEPARTPOSLAT_SET)) {
114 12 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTPOS_LAT, getDepartPosLat());
115 : }
116 : // departspeed
117 516628 : if (wasSet(VEHPARS_DEPARTSPEED_SET) && !defaultOptionOverrides(oc, "departspeed")) {
118 263518 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, getDepartSpeed());
119 436340 : } else if (oc.exists("departspeed") && oc.isSet("departspeed")) {
120 680 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTSPEED, oc.getString("departspeed"));
121 : }
122 : // departedge
123 385024 : if (wasSet(VEHPARS_DEPARTEDGE_SET) && !defaultOptionOverrides(oc, "departedge")) {
124 438 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, getDepartEdge());
125 384586 : } else if (oc.exists("departedge") && oc.isSet("departedge")) {
126 0 : dev.writeNonEmptyAttr(SUMO_ATTR_DEPARTEDGE, oc.getString("departedge"));
127 : }
128 : // arrivallane
129 385133 : if (wasSet(VEHPARS_ARRIVALLANE_SET) && !defaultOptionOverrides(oc, "arrivallane")) {
130 592 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, getArrivalLane());
131 653223 : } else if (oc.exists("arrivallane") && oc.isSet("arrivallane")) {
132 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALLANE, oc.getString("arrivallane"));
133 : }
134 : // arrivalpos
135 388849 : if (wasSet(VEHPARS_ARRIVALPOS_SET) && !defaultOptionOverrides(oc, "arrivalpos")) {
136 7992 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, getArrivalPos());
137 649368 : } else if (oc.exists("arrivalpos") && oc.isSet("arrivalpos")) {
138 692 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS, oc.getString("arrivalpos"));
139 : }
140 : // arrivalPosLat
141 384805 : if (wasSet(VEHPARS_ARRIVALPOSLAT_SET)) {
142 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALPOS_LAT, getArrivalPosLat());
143 : }
144 : // arrivalspeed
145 388572 : if (wasSet(VEHPARS_ARRIVALSPEED_SET) && !defaultOptionOverrides(oc, "arrivalspeed")) {
146 7470 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, getArrivalSpeed());
147 649792 : } else if (oc.exists("arrivalspeed") && oc.isSet("arrivalspeed")) {
148 708 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALSPEED, oc.getString("arrivalspeed"));
149 : }
150 : // arrivalEdge
151 385008 : if (wasSet(VEHPARS_ARRIVALEDGE_SET) && !defaultOptionOverrides(oc, "arrivaledge") && arrivalEdge >= 0) {
152 406 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, getArrivalEdge());
153 384602 : } else if (oc.exists("arrivaledge") && oc.isSet("arrivaledge")) {
154 0 : dev.writeNonEmptyAttr(SUMO_ATTR_ARRIVALEDGE, oc.getString("arrivaledge"));
155 : }
156 : // color
157 384805 : if (wasSet(VEHPARS_COLOR_SET)) {
158 6717 : dev.writeAttr(SUMO_ATTR_COLOR, color);
159 : }
160 : // line
161 384805 : if (wasSet(VEHPARS_LINE_SET)) {
162 353 : dev.writeAttr(SUMO_ATTR_LINE, line);
163 : }
164 : // from TAZ
165 384805 : if (wasSet(VEHPARS_FROM_TAZ_SET)) {
166 5257 : dev.writeAttr(SUMO_ATTR_FROM_TAZ, fromTaz);
167 : }
168 : // to TAZ
169 384805 : if (wasSet(VEHPARS_TO_TAZ_SET)) {
170 5257 : dev.writeAttr(SUMO_ATTR_TO_TAZ, toTaz);
171 : }
172 : // person number
173 384805 : if (wasSet(VEHPARS_PERSON_NUMBER_SET)) {
174 0 : dev.writeAttr(SUMO_ATTR_PERSON_NUMBER, personNumber);
175 : }
176 : // container number
177 384805 : if (wasSet(VEHPARS_CONTAINER_NUMBER_SET)) {
178 0 : dev.writeAttr(SUMO_ATTR_CONTAINER_NUMBER, containerNumber);
179 : }
180 : // individual speedFactor
181 384805 : if (wasSet(VEHPARS_SPEEDFACTOR_SET)) {
182 : // might be saving state with custom precision
183 47101 : const int precision = dev.precision();
184 47101 : dev.setPrecision(MAX2(gPrecisionRandom, precision));
185 47101 : dev.writeAttr(SUMO_ATTR_SPEEDFACTOR, speedFactor);
186 47101 : dev.setPrecision(precision);
187 : }
188 : // speed (only used by calibrators)
189 384805 : if (wasSet(VEHPARS_CALIBRATORSPEED_SET)) {
190 0 : dev.writeAttr(SUMO_ATTR_SPEED, calibratorSpeed);
191 : }
192 : // insertionChecks
193 384805 : if (wasSet(VEHPARS_INSERTION_CHECKS_SET) && insertionChecks != (int)InsertionCheck::ALL) {
194 : std::vector<std::string> checks;
195 26 : if (insertionChecks == (int)InsertionCheck::NONE) {
196 52 : checks.push_back(toString(InsertionCheck::NONE));
197 : } else {
198 0 : for (auto it : SUMOXMLDefinitions::InsertionChecks.getValues()) {
199 0 : if (((int)it & insertionChecks) != 0) {
200 0 : checks.push_back(toString(it));
201 : }
202 0 : }
203 : }
204 : dev.writeAttr(SUMO_ATTR_INSERTIONCHECKS, checks);
205 26 : }
206 : // parking access rights
207 384805 : if (wasSet(VEHPARS_PARKING_BADGES_SET)) {
208 52 : dev.writeNonEmptyAttr(SUMO_ATTR_PARKING_BADGES, joinToString(parkingBadges, " "));
209 : }
210 384805 : }
211 :
212 :
213 : void
214 33918 : SUMOVehicleParameter::Stop::write(OutputDevice& dev, const bool close, const bool writeTagAndParents) const {
215 33918 : if (writeTagAndParents) {
216 33918 : dev.openTag(SUMO_TAG_STOP);
217 33918 : if (busstop != "") {
218 : dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop);
219 : }
220 33918 : if (containerstop != "") {
221 : dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop);
222 : }
223 33918 : if (chargingStation != "") {
224 : dev.writeAttr(SUMO_ATTR_CHARGING_STATION, chargingStation);
225 : }
226 33918 : if (parkingarea != "") {
227 : dev.writeAttr(SUMO_ATTR_PARKING_AREA, parkingarea);
228 : }
229 33918 : if ((busstop == "") && (containerstop == "") && (parkingarea == "") && (chargingStation == "")) {
230 19721 : if (lane != "") {
231 : dev.writeAttr(SUMO_ATTR_LANE, lane);
232 : } else {
233 1166 : dev.writeAttr(SUMO_ATTR_EDGE, edge);
234 : }
235 19721 : if ((parametersSet & STOP_START_SET) != 0) {
236 2824 : dev.writeAttr(SUMO_ATTR_STARTPOS, startPos);
237 : }
238 19721 : if ((parametersSet & STOP_END_SET) != 0) {
239 6056 : dev.writeAttr(SUMO_ATTR_ENDPOS, endPos);
240 : }
241 : }
242 : }
243 33918 : if (index > 0) {
244 260 : dev.writeAttr(SUMO_ATTR_INDEX, index);
245 : }
246 33918 : if ((parametersSet & STOP_POSLAT_SET) != 0 && posLat != INVALID_DOUBLE) {
247 71 : dev.writeAttr(SUMO_ATTR_POSITION_LAT, posLat);
248 : }
249 33918 : if ((parametersSet & STOP_ARRIVAL_SET) && (arrival >= 0)) {
250 738 : dev.writeAttr(SUMO_ATTR_ARRIVAL, time2string(arrival));
251 : }
252 33918 : if ((parametersSet & STOP_DURATION_SET) && (duration >= 0)) {
253 49486 : dev.writeAttr(SUMO_ATTR_DURATION, time2string(duration));
254 : }
255 33918 : if ((parametersSet & STOP_UNTIL_SET) && (until >= 0)) {
256 19354 : dev.writeAttr(SUMO_ATTR_UNTIL, time2string(until));
257 : }
258 33918 : if ((parametersSet & STOP_STARTED_SET) && (started >= 0)) {
259 176 : dev.writeAttr(SUMO_ATTR_STARTED, time2string(started));
260 : }
261 33918 : if ((parametersSet & STOP_ENDED_SET) && (ended >= 0)) {
262 218 : dev.writeAttr(SUMO_ATTR_ENDED, time2string(ended));
263 : }
264 33918 : if ((parametersSet & STOP_EXTENSION_SET) && (extension >= 0)) {
265 146 : dev.writeAttr(SUMO_ATTR_EXTENSION, time2string(extension));
266 : }
267 33918 : if ((parametersSet & STOP_TRIGGER_SET) != 0) {
268 209 : const std::vector<std::string> triggers = getTriggers();
269 209 : if (triggers.size() > 0) {
270 : dev.writeAttr(SUMO_ATTR_TRIGGERED, triggers);
271 : }
272 209 : }
273 33918 : if ((parametersSet & STOP_PARKING_SET) != 0) {
274 360 : dev.writeAttr(SUMO_ATTR_PARKING, parking);
275 : }
276 33918 : if ((parametersSet & STOP_EXPECTED_SET) != 0 && awaitedPersons.size() > 0) {
277 50 : dev.writeAttr(SUMO_ATTR_EXPECTED, awaitedPersons);
278 : }
279 33918 : if ((parametersSet & STOP_PERMITTED_SET) != 0 && permitted.size() > 0) {
280 786 : dev.writeAttr(SUMO_ATTR_PERMITTED, permitted);
281 : }
282 33918 : if ((parametersSet & STOP_EXPECTED_CONTAINERS_SET) != 0 && awaitedContainers.size() > 0) {
283 4 : dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, awaitedContainers);
284 : }
285 33918 : if ((parametersSet & STOP_TRIP_ID_SET) != 0) {
286 55 : dev.writeAttr(SUMO_ATTR_TRIP_ID, tripId);
287 : }
288 33918 : if ((parametersSet & STOP_LINE_SET) != 0) {
289 22 : dev.writeAttr(SUMO_ATTR_LINE, line);
290 : }
291 33918 : if ((parametersSet & STOP_SPLIT_SET) != 0) {
292 21 : dev.writeAttr(SUMO_ATTR_SPLIT, split);
293 : }
294 33918 : if ((parametersSet & STOP_JOIN_SET) != 0) {
295 17 : dev.writeAttr(SUMO_ATTR_JOIN, join);
296 : }
297 33918 : if ((parametersSet & STOP_SPEED_SET) != 0) {
298 157 : dev.writeAttr(SUMO_ATTR_SPEED, speed);
299 : }
300 33918 : if ((parametersSet & STOP_ONDEMAND_SET) != 0) {
301 79 : dev.writeAttr(SUMO_ATTR_ONDEMAND, onDemand);
302 : }
303 33918 : if ((parametersSet & STOP_JUMP_SET) != 0 && jump >= 0) {
304 550 : dev.writeAttr(SUMO_ATTR_JUMP, time2string(jump));
305 : }
306 33918 : if (collision) {
307 622 : dev.writeAttr(SUMO_ATTR_COLLISION, collision);
308 : }
309 : // only write friendly position if is true
310 33918 : if (friendlyPos) {
311 0 : dev.writeAttr(SUMO_ATTR_FRIENDLY_POS, friendlyPos);
312 : }
313 : // only write act type if isn't empty
314 33918 : if (!actType.empty()) {
315 1357 : dev.writeAttr(SUMO_ATTR_ACTTYPE, actType);
316 : }
317 33918 : if (close) {
318 : // the user is closing the stop it is responsible for writing params
319 28816 : writeParams(dev);
320 57632 : dev.closeTag();
321 : }
322 33918 : }
323 :
324 : std::vector<std::string>
325 164 : SUMOVehicleParameter::Stop::getStoppingPlaceIDs() const {
326 : std::vector<std::string> result;
327 164 : if (busstop != "") {
328 76 : result.push_back(busstop);
329 : }
330 164 : if (containerstop != "") {
331 8 : result.push_back(containerstop);
332 : }
333 164 : if (chargingStation != "") {
334 8 : result.push_back(chargingStation);
335 : }
336 164 : if (parkingarea != "") {
337 8 : result.push_back(parkingarea);
338 : }
339 164 : return result;
340 0 : }
341 :
342 : bool
343 517966 : SUMOVehicleParameter::parseDepart(const std::string& val, const std::string& element, const std::string& id,
344 : SUMOTime& depart, DepartDefinition& dd, std::string& error, const std::string& attr) {
345 517966 : if (val == "triggered") {
346 1370 : dd = DepartDefinition::TRIGGERED;
347 516596 : } else if (val == "containerTriggered") {
348 105 : dd = DepartDefinition::CONTAINER_TRIGGERED;
349 516491 : } else if (val == "now") {
350 : // only used via TraCI. depart must be set by the calling code
351 22850 : dd = DepartDefinition::NOW;
352 493641 : } else if (val == "split") {
353 40 : dd = DepartDefinition::SPLIT;
354 493601 : } else if (val == "begin") {
355 11 : dd = DepartDefinition::BEGIN;
356 : } else {
357 : try {
358 493590 : depart = string2time(val);
359 493582 : dd = DepartDefinition::GIVEN;
360 493582 : if (depart < 0) {
361 14 : error = "Negative " + attr + " time in the definition of " + element + " '" + id + "'.";
362 7 : return false;
363 : }
364 8 : } catch (...) {
365 8 : if (id.empty()) {
366 0 : error = "Invalid " + attr + " time for " + element + ". Must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
367 : } else {
368 24 : error = "Invalid " + attr + " time for " + element + " '" + id + "';\n must be one of (\"triggered\", \"containerTriggered\", \"now\", or a float >= 0)";
369 : }
370 : return false;
371 8 : }
372 : }
373 : return true;
374 : }
375 :
376 :
377 : bool
378 133170 : SUMOVehicleParameter::parseDepartLane(const std::string& val, const std::string& element, const std::string& id,
379 : int& lane, DepartLaneDefinition& dld, std::string& error) {
380 : bool ok = true;
381 133170 : lane = 0;
382 133170 : dld = DepartLaneDefinition::GIVEN;
383 133170 : if (val == "random") {
384 4055 : dld = DepartLaneDefinition::RANDOM;
385 129115 : } else if (val == "free") {
386 2292 : dld = DepartLaneDefinition::FREE;
387 126823 : } else if (val == "allowed") {
388 131 : dld = DepartLaneDefinition::ALLOWED_FREE;
389 126692 : } else if (val == "best") {
390 94006 : dld = DepartLaneDefinition::BEST_FREE;
391 32686 : } else if (val == "first") {
392 1044 : dld = DepartLaneDefinition::FIRST_ALLOWED;
393 : } else {
394 : try {
395 31642 : lane = StringUtils::toInt(val);
396 31583 : if (lane < 0) {
397 : ok = false;
398 : }
399 59 : } catch (...) {
400 : ok = false;
401 59 : }
402 : }
403 : if (!ok) {
404 59 : if (id.empty()) {
405 0 : error = "Invalid departLane definition for " + element + ". Must be one of (\"random\", \"free\", \"allowed\", \"best\", \"first\", or an int>=0)";
406 : } else {
407 177 : error = "Invalid departLane definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", \"allowed\", \"best\", \"first\", or an int>=0)";
408 : }
409 : }
410 133170 : return ok;
411 : }
412 :
413 :
414 : bool
415 109733 : SUMOVehicleParameter::parseDepartPos(const std::string& val, const std::string& element, const std::string& id,
416 : double& pos, DepartPosDefinition& dpd, std::string& error) {
417 : bool ok = true;
418 109733 : pos = 0.;
419 109733 : dpd = DepartPosDefinition::GIVEN;
420 109733 : if (val == "random") {
421 2102 : dpd = DepartPosDefinition::RANDOM;
422 107631 : } else if (val == "random_free") {
423 72 : dpd = DepartPosDefinition::RANDOM_FREE;
424 107559 : } else if (val == "random_location") {
425 0 : dpd = DepartPosDefinition::RANDOM_LOCATION;
426 107559 : } else if (val == "free") {
427 375 : dpd = DepartPosDefinition::FREE;
428 107184 : } else if (val == "base") {
429 962 : dpd = DepartPosDefinition::BASE;
430 106222 : } else if (val == "last") {
431 773 : dpd = DepartPosDefinition::LAST;
432 105449 : } else if (val == "splitFront") {
433 5 : dpd = DepartPosDefinition::SPLIT_FRONT;
434 105444 : } else if (val == "stop") {
435 1831 : dpd = DepartPosDefinition::STOP;
436 : } else {
437 : try {
438 103613 : pos = StringUtils::toDouble(val);
439 54 : } catch (...) {
440 : ok = false;
441 54 : }
442 : }
443 : if (!ok) {
444 54 : if (id.empty()) {
445 0 : error = "Invalid departPos definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
446 : } else {
447 162 : error = "Invalid departPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"base\", \"last\" or a float)";
448 : }
449 : }
450 109733 : return ok;
451 : }
452 :
453 :
454 : bool
455 8968 : SUMOVehicleParameter::parseDepartPosLat(const std::string& val, const std::string& element, const std::string& id,
456 : double& pos, DepartPosLatDefinition& dpd, std::string& error) {
457 : bool ok = true;
458 8968 : pos = 0.;
459 8968 : dpd = DepartPosLatDefinition::GIVEN;
460 8968 : if (val == "random") {
461 6181 : dpd = DepartPosLatDefinition::RANDOM;
462 2787 : } else if (val == "random_free") {
463 450 : dpd = DepartPosLatDefinition::RANDOM_FREE;
464 2337 : } else if (val == "free") {
465 71 : dpd = DepartPosLatDefinition::FREE;
466 2266 : } else if (val == "right") {
467 246 : dpd = DepartPosLatDefinition::RIGHT;
468 2020 : } else if (val == "center") {
469 590 : dpd = DepartPosLatDefinition::CENTER;
470 1430 : } else if (val == "left") {
471 187 : dpd = DepartPosLatDefinition::LEFT;
472 : } else {
473 : try {
474 1243 : pos = StringUtils::toDouble(val);
475 0 : } catch (...) {
476 : ok = false;
477 0 : }
478 : }
479 : if (!ok) {
480 0 : if (id.empty()) {
481 0 : error = "Invalid departPosLat definition for " + element + ". Must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
482 : } else {
483 0 : error = "Invalid departPosLat definition for " + element + " '" + id + "';\n must be one of (\"random\", \"random_free\", \"free\", \"right\", \"center\", \"left\", or a float)";
484 : }
485 : }
486 8968 : return ok;
487 : }
488 :
489 :
490 : bool
491 263664 : SUMOVehicleParameter::parseDepartSpeed(const std::string& val, const std::string& element, const std::string& id,
492 : double& speed, DepartSpeedDefinition& dsd, std::string& error) {
493 : bool ok = true;
494 263664 : speed = -1.;
495 263664 : dsd = DepartSpeedDefinition::GIVEN;
496 263664 : if (val == "random") {
497 221 : dsd = DepartSpeedDefinition::RANDOM;
498 263443 : } else if (val == "max") {
499 137473 : dsd = DepartSpeedDefinition::MAX;
500 125970 : } else if (val == "desired") {
501 191 : dsd = DepartSpeedDefinition::DESIRED;
502 125779 : } else if (val == "speedLimit") {
503 489 : dsd = DepartSpeedDefinition::LIMIT;
504 125290 : } else if (val == "last") {
505 37 : dsd = DepartSpeedDefinition::LAST;
506 125253 : } else if (val == "avg") {
507 602 : dsd = DepartSpeedDefinition::AVG;
508 : } else {
509 : try {
510 124651 : speed = StringUtils::toDouble(val);
511 124597 : if (speed < 0) {
512 : ok = false;
513 : }
514 54 : } catch (...) {
515 : ok = false;
516 54 : }
517 : }
518 : if (!ok) {
519 54 : if (id.empty()) {
520 0 : error = "Invalid departSpeed definition for " + element + ". Must be one of (\"random\", \"max\", or a float>=0)";
521 : } else {
522 162 : error = "Invalid departSpeed definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float>=0)";
523 : }
524 : }
525 263664 : return ok;
526 : }
527 :
528 :
529 : bool
530 232 : SUMOVehicleParameter::parseRouteIndex(const std::string& val, const std::string& element, const std::string& id,
531 : const SumoXMLAttr attr, int& edgeIndex, RouteIndexDefinition& rid, std::string& error) {
532 : bool ok = true;
533 232 : edgeIndex = -1;
534 232 : rid = RouteIndexDefinition::GIVEN;
535 232 : if (val == "random") {
536 63 : rid = RouteIndexDefinition::RANDOM;
537 : } else {
538 : try {
539 169 : edgeIndex = StringUtils::toInt(val);
540 169 : if (edgeIndex < 0) {
541 : ok = false;
542 : }
543 0 : } catch (...) {
544 : ok = false;
545 0 : }
546 : }
547 : if (!ok) {
548 14 : if (id.empty()) {
549 0 : error = "Invalid " + toString(attr) + " definition for " + element + ". Must be one of (\"random\", \"free\", or an int>=0)";
550 : } else {
551 42 : error = "Invalid " + toString(attr) + " definition for " + element + " '" + id + "';\n must be one of (\"random\", \"free\", or an int>=0)";
552 : }
553 : }
554 232 : return ok;
555 : }
556 :
557 :
558 : bool
559 26054 : SUMOVehicleParameter::parseArrivalLane(const std::string& val, const std::string& element, const std::string& id,
560 : int& lane, ArrivalLaneDefinition& ald, std::string& error) {
561 : bool ok = true;
562 26054 : lane = 0;
563 26054 : ald = ArrivalLaneDefinition::GIVEN;
564 26054 : if (val == "current") {
565 23423 : ald = ArrivalLaneDefinition::CURRENT;
566 2631 : } else if (val == "random") {
567 67 : ald = ArrivalLaneDefinition::RANDOM;
568 2564 : } else if (val == "first") {
569 7 : ald = ArrivalLaneDefinition::FIRST_ALLOWED;
570 : } else {
571 : try {
572 2557 : lane = StringUtils::toInt(val);
573 2503 : if (lane < 0) {
574 : ok = false;
575 : }
576 54 : } catch (...) {
577 : ok = false;
578 54 : }
579 : }
580 : if (!ok) {
581 54 : if (id.empty()) {
582 0 : error = "Invalid arrivalLane definition for " + element + ". Must be one of (\"current\", or an int>=0)";
583 : } else {
584 162 : error = "Invalid arrivalLane definition for " + element + " '" + id + "';\n must be one of (\"current\", or an int>=0)";
585 : }
586 : }
587 26054 : return ok;
588 : }
589 :
590 :
591 : bool
592 62730 : SUMOVehicleParameter::parseArrivalPos(const std::string& val, const std::string& element, const std::string& id,
593 : double& pos, ArrivalPosDefinition& apd, std::string& error) {
594 : bool ok = true;
595 62730 : pos = 0.;
596 62730 : apd = ArrivalPosDefinition::GIVEN;
597 62730 : if (val == "random") {
598 1448 : apd = ArrivalPosDefinition::RANDOM;
599 61282 : } else if (val == "center") {
600 0 : apd = ArrivalPosDefinition::CENTER;
601 61282 : } else if (val == "max") {
602 22975 : apd = ArrivalPosDefinition::MAX;
603 : } else {
604 : try {
605 38307 : pos = StringUtils::toDouble(val);
606 54 : } catch (...) {
607 : ok = false;
608 54 : }
609 : }
610 : if (!ok) {
611 54 : if (id.empty()) {
612 0 : error = "Invalid arrivalPos definition for " + element + ". Must be one of (\"random\", \"max\", or a float)";
613 : } else {
614 162 : error = "Invalid arrivalPos definition for " + element + " '" + id + "';\n must be one of (\"random\", \"max\", or a float)";
615 : }
616 : }
617 62730 : return ok;
618 : }
619 :
620 :
621 : bool
622 1065 : SUMOVehicleParameter::parseArrivalPosLat(const std::string& val, const std::string& element, const std::string& id,
623 : double& pos, ArrivalPosLatDefinition& apd, std::string& error) {
624 : bool ok = true;
625 1065 : pos = 0.;
626 1065 : apd = ArrivalPosLatDefinition::GIVEN;
627 1065 : if (val == "right") {
628 499 : apd = ArrivalPosLatDefinition::RIGHT;
629 566 : } else if (val == "center") {
630 9 : apd = ArrivalPosLatDefinition::CENTER;
631 557 : } else if (val == "left") {
632 39 : apd = ArrivalPosLatDefinition::LEFT;
633 : } else {
634 : try {
635 518 : pos = StringUtils::toDouble(val);
636 0 : } catch (...) {
637 : ok = false;
638 0 : }
639 : }
640 : if (!ok) {
641 0 : if (id.empty()) {
642 0 : error = "Invalid arrivalPosLat definition for " + element + ". Must be one of (\"right\", \"center\", \"left\", or a float)";
643 : } else {
644 0 : error = "Invalid arrivalPosLat definition for " + element + " '" + id + "';\n must be one of (\"right\", \"center\", \"left\", or a float)";
645 : }
646 : }
647 1065 : return ok;
648 : }
649 :
650 :
651 : bool
652 26705 : SUMOVehicleParameter::parseArrivalSpeed(const std::string& val, const std::string& element, const std::string& id,
653 : double& speed, ArrivalSpeedDefinition& asd, std::string& error) {
654 : bool ok = true;
655 26705 : speed = -1.;
656 26705 : asd = ArrivalSpeedDefinition::GIVEN;
657 26705 : if (val == "current") {
658 23496 : asd = ArrivalSpeedDefinition::CURRENT;
659 : } else {
660 : try {
661 3209 : speed = StringUtils::toDouble(val);
662 3155 : if (speed < 0) {
663 : ok = false;
664 : }
665 54 : } catch (...) {
666 : ok = false;
667 54 : }
668 : }
669 : if (!ok) {
670 54 : if (id.empty()) {
671 0 : error = "Invalid arrivalSpeed definition for " + element + ". Must be one of (\"current\", or a float>=0)";
672 : } else {
673 162 : error = "Invalid arrivalSpeed definition for " + element + " '" + id + "';\n must be one of (\"current\", or a float>=0)";
674 : }
675 : }
676 26705 : return ok;
677 : }
678 :
679 :
680 : double
681 1408039 : SUMOVehicleParameter::interpretEdgePos(double pos, double maximumValue, SumoXMLAttr attr, const std::string& id, bool silent) {
682 1408039 : if (pos < 0) {
683 28733 : pos = maximumValue + pos;
684 : }
685 1408039 : if (pos > maximumValue && pos != std::numeric_limits<double>::infinity()) {
686 3 : if (!silent) {
687 9 : WRITE_WARNINGF(TL("Invalid % % given for %. Using edge end instead."), toString(attr), toString(pos), id);
688 : }
689 3 : pos = maximumValue;
690 : }
691 1408039 : return pos;
692 : }
693 :
694 :
695 : bool
696 964 : SUMOVehicleParameter::parsePersonModes(const std::string& modes, const std::string& element, const std::string& id, SVCPermissions& modeSet, std::string& error) {
697 : // separte modes in different strings, and check if modes are valid
698 3038 : for (StringTokenizer st(modes); st.hasNext();) {
699 1110 : const std::string mode = st.next();
700 1110 : if (mode == "car") {
701 437 : modeSet |= SVC_PASSENGER;
702 673 : } else if (mode == "taxi") {
703 124 : modeSet |= SVC_TAXI;
704 549 : } else if (mode == "bicycle") {
705 41 : modeSet |= SVC_BICYCLE;
706 508 : } else if (mode == "public") {
707 508 : modeSet |= SVC_BUS;
708 : } else {
709 0 : if (id.empty()) {
710 0 : error = "Unknown person mode '" + mode + "'. Must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
711 : } else {
712 0 : error = "Unknown person mode '" + mode + "' for " + element + " '" + id + "';\n must be a combination of (\"car\", \"taxi\", \"bicycle\" or \"public\")";
713 : }
714 : return false;
715 : }
716 964 : }
717 964 : return true;
718 : }
719 :
720 :
721 : void
722 43860 : SUMOVehicleParameter::parseStopTriggers(const std::vector<std::string>& triggers, bool expectTrigger, Stop& stop) {
723 43860 : if (triggers.size() == 0 && expectTrigger) {
724 1145 : stop.triggered = true;
725 : }
726 45150 : for (std::string val : triggers) {
727 1290 : if (val == toString(SUMO_TAG_PERSON)) {
728 774 : stop.triggered = true;
729 516 : } else if (val == toString(SUMO_TAG_CONTAINER)) {
730 267 : stop.containerTriggered = true;
731 249 : } else if (val == toString(SUMO_ATTR_JOIN)) {
732 116 : stop.joinTriggered = true;
733 : } else {
734 : try {
735 133 : stop.triggered = StringUtils::toBool(val);
736 0 : } catch (BoolFormatException&) {
737 0 : WRITE_ERROR(TL("Value of stop attribute 'trigger' must be 'person', 'container', 'join' or a boolean"));
738 0 : }
739 : }
740 : }
741 43860 : }
742 :
743 :
744 : ParkingType
745 3097 : SUMOVehicleParameter::parseParkingType(const std::string& value) {
746 3097 : if (value == toString(ParkingType::OPPORTUNISTIC)) {
747 : return ParkingType::OPPORTUNISTIC;
748 : } else {
749 3097 : return StringUtils::toBool(value) ? ParkingType::OFFROAD : ParkingType::ONROAD;
750 : }
751 : }
752 :
753 :
754 : std::vector<std::string>
755 238 : SUMOVehicleParameter::Stop::getTriggers() const {
756 : std::vector<std::string> triggers;
757 238 : if (triggered) {
758 326 : triggers.push_back(toString(SUMO_TAG_PERSON));
759 : }
760 238 : if (containerTriggered) {
761 60 : triggers.push_back(toString(SUMO_TAG_CONTAINER));
762 : }
763 238 : if (joinTriggered) {
764 64 : triggers.push_back(toString(SUMO_ATTR_JOIN));
765 : }
766 238 : return triggers;
767 0 : }
768 :
769 : int
770 7768 : SUMOVehicleParameter::Stop::getFlags() const {
771 7768 : return (((parking == ParkingType::OFFROAD) ? 1 : 0) +
772 7768 : (triggered ? 2 : 0) +
773 7768 : (containerTriggered ? 4 : 0) +
774 7768 : (busstop != "" ? 8 : 0) +
775 7768 : (containerstop != "" ? 16 : 0) +
776 7768 : (chargingStation != "" ? 32 : 0) +
777 7768 : (parkingarea != "" ? 64 : 0) +
778 7768 : (overheadWireSegment != "" ? 128 : 0));
779 : }
780 :
781 :
782 : std::string
783 384805 : SUMOVehicleParameter::getDepart() const {
784 384805 : if (departProcedure == DepartDefinition::TRIGGERED) {
785 702 : return "triggered";
786 384103 : } else if (departProcedure == DepartDefinition::CONTAINER_TRIGGERED) {
787 16 : return "containerTriggered";
788 : // } else if (departProcedure == DepartDefinition::NOW) { // TODO check whether this is useful in XML input (currently TraCI only)
789 : // return "now";
790 384087 : } else if (departProcedure == DepartDefinition::SPLIT) {
791 0 : return "split";
792 384087 : } else if (departProcedure == DepartDefinition::BEGIN) {
793 8 : return "begin";
794 : } else {
795 384079 : return time2string(depart);
796 : }
797 : }
798 :
799 :
800 : std::string
801 102656 : SUMOVehicleParameter::getDepartLane() const {
802 : std::string val;
803 102656 : switch (departLaneProcedure) {
804 15110 : case DepartLaneDefinition::GIVEN:
805 15110 : val = toString(departLane);
806 15110 : break;
807 : case DepartLaneDefinition::RANDOM:
808 : val = "random";
809 : break;
810 : case DepartLaneDefinition::FREE:
811 : val = "free";
812 : break;
813 : case DepartLaneDefinition::ALLOWED_FREE:
814 : val = "allowed";
815 : break;
816 : case DepartLaneDefinition::BEST_FREE:
817 : val = "best";
818 : break;
819 : case DepartLaneDefinition::FIRST_ALLOWED:
820 : val = "first";
821 : break;
822 : case DepartLaneDefinition::DEFAULT:
823 : default:
824 : break;
825 : }
826 102656 : return val;
827 : }
828 :
829 :
830 : std::string
831 39256 : SUMOVehicleParameter::getDepartPos() const {
832 : std::string val;
833 39256 : switch (departPosProcedure) {
834 24444 : case DepartPosDefinition::GIVEN:
835 24444 : val = toString(departPos);
836 24444 : break;
837 13767 : case DepartPosDefinition::GIVEN_VEHROUTE:
838 13767 : val = StringUtils::pruneZeros(toString(departPos, MAX2(gPrecisionRandom, gPrecision)), 2);
839 13767 : break;
840 : case DepartPosDefinition::RANDOM:
841 : val = "random";
842 : break;
843 : case DepartPosDefinition::RANDOM_FREE:
844 : val = "random_free";
845 : break;
846 : case DepartPosDefinition::RANDOM_LOCATION:
847 : val = "random_location";
848 : break;
849 : case DepartPosDefinition::FREE:
850 : val = "free";
851 : break;
852 : case DepartPosDefinition::LAST:
853 : val = "last";
854 : break;
855 : case DepartPosDefinition::BASE:
856 : val = "base";
857 : break;
858 : case DepartPosDefinition::SPLIT_FRONT:
859 : val = "splitFront";
860 : break;
861 : case DepartPosDefinition::STOP:
862 : val = "stop";
863 : break;
864 : case DepartPosDefinition::DEFAULT:
865 : default:
866 : break;
867 : }
868 39256 : return val;
869 : }
870 :
871 :
872 : std::string
873 6 : SUMOVehicleParameter::getDepartPosLat() const {
874 : std::string val;
875 6 : switch (departPosLatProcedure) {
876 0 : case DepartPosLatDefinition::GIVEN:
877 0 : val = toString(departPosLat);
878 0 : break;
879 4 : case DepartPosLatDefinition::GIVEN_VEHROUTE:
880 4 : val = StringUtils::pruneZeros(toString(departPosLat, MAX2(gPrecisionRandom, gPrecision)), 2);
881 4 : break;
882 : case DepartPosLatDefinition::RANDOM:
883 : val = "random";
884 : break;
885 : case DepartPosLatDefinition::RANDOM_FREE:
886 : val = "random_free";
887 : break;
888 : case DepartPosLatDefinition::FREE:
889 : val = "free";
890 : break;
891 : case DepartPosLatDefinition::RIGHT:
892 : val = "right";
893 : break;
894 : case DepartPosLatDefinition::CENTER:
895 : val = "center";
896 : break;
897 : case DepartPosLatDefinition::LEFT:
898 : val = "left";
899 : break;
900 : case DepartPosLatDefinition::DEFAULT:
901 : default:
902 : break;
903 : }
904 6 : return val;
905 : }
906 :
907 :
908 : std::string
909 131759 : SUMOVehicleParameter::getDepartSpeed() const {
910 : std::string val;
911 131759 : switch (departSpeedProcedure) {
912 2399 : case DepartSpeedDefinition::GIVEN:
913 2399 : val = toString(departSpeed);
914 2399 : break;
915 43138 : case DepartSpeedDefinition::GIVEN_VEHROUTE:
916 43138 : val = StringUtils::pruneZeros(toString(departSpeed, MAX2(gPrecisionRandom, gPrecision)), 2);
917 43138 : break;
918 : case DepartSpeedDefinition::RANDOM:
919 : val = "random";
920 : break;
921 : case DepartSpeedDefinition::MAX:
922 : val = "max";
923 : break;
924 : case DepartSpeedDefinition::DESIRED:
925 : val = "desired";
926 : break;
927 : case DepartSpeedDefinition::LIMIT:
928 : val = "speedLimit";
929 : break;
930 : case DepartSpeedDefinition::LAST:
931 : val = "last";
932 : break;
933 : case DepartSpeedDefinition::AVG:
934 : val = "avg";
935 : break;
936 : case DepartSpeedDefinition::DEFAULT:
937 : default:
938 : break;
939 : }
940 131759 : return val;
941 : }
942 :
943 :
944 : std::string
945 219 : SUMOVehicleParameter::getDepartEdge() const {
946 : std::string val;
947 219 : switch (departEdgeProcedure) {
948 219 : case RouteIndexDefinition::GIVEN:
949 219 : val = toString(departEdge);
950 219 : break;
951 : case RouteIndexDefinition::RANDOM:
952 : val = "random";
953 : break;
954 : case RouteIndexDefinition::DEFAULT:
955 : default:
956 : break;
957 : }
958 219 : return val;
959 : }
960 :
961 : std::string
962 203 : SUMOVehicleParameter::getArrivalEdge() const {
963 : std::string val;
964 203 : switch (arrivalEdgeProcedure) {
965 203 : case RouteIndexDefinition::GIVEN:
966 203 : val = toString(arrivalEdge);
967 203 : break;
968 : case RouteIndexDefinition::RANDOM:
969 : val = "random";
970 : break;
971 : case RouteIndexDefinition::DEFAULT:
972 : default:
973 : break;
974 : }
975 203 : return val;
976 : }
977 :
978 :
979 :
980 :
981 : std::string
982 296 : SUMOVehicleParameter::getArrivalLane() const {
983 : std::string val;
984 296 : switch (arrivalLaneProcedure) {
985 160 : case ArrivalLaneDefinition::GIVEN:
986 160 : val = toString(arrivalLane);
987 160 : break;
988 : case ArrivalLaneDefinition::CURRENT:
989 : val = "current";
990 : break;
991 : case ArrivalLaneDefinition::RANDOM:
992 : val = "random";
993 : break;
994 : case ArrivalLaneDefinition::FIRST_ALLOWED:
995 : val = "first";
996 : break;
997 : case ArrivalLaneDefinition::DEFAULT:
998 : default:
999 : break;
1000 : }
1001 296 : return val;
1002 : }
1003 :
1004 :
1005 : std::string
1006 3996 : SUMOVehicleParameter::getArrivalPos() const {
1007 : std::string val;
1008 3996 : switch (arrivalPosProcedure) {
1009 3724 : case ArrivalPosDefinition::GIVEN:
1010 3724 : val = toString(arrivalPos);
1011 3724 : break;
1012 : case ArrivalPosDefinition::RANDOM:
1013 : val = "random";
1014 : break;
1015 : case ArrivalPosDefinition::CENTER:
1016 : val = "center";
1017 : break;
1018 : case ArrivalPosDefinition::MAX:
1019 : val = "max";
1020 : break;
1021 : case ArrivalPosDefinition::DEFAULT:
1022 : default:
1023 : break;
1024 : }
1025 3996 : return val;
1026 : }
1027 :
1028 :
1029 : std::string
1030 0 : SUMOVehicleParameter::getArrivalPosLat() const {
1031 : std::string val;
1032 0 : switch (arrivalPosLatProcedure) {
1033 0 : case ArrivalPosLatDefinition::GIVEN:
1034 0 : val = toString(arrivalPosLat);
1035 0 : break;
1036 : case ArrivalPosLatDefinition::RIGHT:
1037 : val = "right";
1038 : break;
1039 : case ArrivalPosLatDefinition::CENTER:
1040 : val = "center";
1041 : break;
1042 : case ArrivalPosLatDefinition::LEFT:
1043 : val = "left";
1044 : break;
1045 : case ArrivalPosLatDefinition::DEFAULT:
1046 : default:
1047 : break;
1048 : }
1049 0 : return val;
1050 : }
1051 :
1052 :
1053 : std::string
1054 3735 : SUMOVehicleParameter::getArrivalSpeed() const {
1055 : std::string val;
1056 3735 : switch (arrivalSpeedProcedure) {
1057 3599 : case ArrivalSpeedDefinition::GIVEN:
1058 3599 : val = toString(arrivalSpeed);
1059 3599 : break;
1060 : case ArrivalSpeedDefinition::CURRENT:
1061 : val = "current";
1062 : break;
1063 : case ArrivalSpeedDefinition::DEFAULT:
1064 : default:
1065 : break;
1066 : }
1067 3735 : return val;
1068 : }
1069 :
1070 :
1071 : void
1072 4568754 : SUMOVehicleParameter::incrementFlow(double scale, SumoRNG* rng) {
1073 4568754 : repetitionsDone++;
1074 : // equidistant or exponential offset (for poisson distributed arrivals)
1075 4568754 : if (repetitionProbability < 0) {
1076 4078050 : if (repetitionOffset >= 0) {
1077 3714999 : repetitionTotalOffset += (SUMOTime)((double)repetitionOffset / scale);
1078 : } else {
1079 : assert(poissonRate > 0);
1080 : // we need to cache this do avoid double generation of the rng in the TIME2STEPS macro
1081 363051 : const double r = RandHelper::randExp(poissonRate, rng);
1082 363051 : repetitionTotalOffset += TIME2STEPS(r / scale);
1083 : }
1084 : }
1085 4568754 : }
1086 :
1087 :
1088 : std::string
1089 0 : SUMOVehicleParameter::getInsertionChecks() const {
1090 0 : if ((insertionChecks == 0) || (insertionChecks == (int)InsertionCheck::ALL)) {
1091 0 : return SUMOXMLDefinitions::InsertionChecks.getString(InsertionCheck::ALL);
1092 : } else {
1093 : std::vector<std::string> insertionChecksStrs;
1094 0 : const auto insertionCheckValues = SUMOXMLDefinitions::InsertionChecks.getValues();
1095 : // iterate over values
1096 0 : for (const auto insertionCheckValue : insertionCheckValues) {
1097 0 : if ((insertionCheckValue != InsertionCheck::ALL) && (insertionChecks & (int)insertionCheckValue) != 0) {
1098 0 : insertionChecksStrs.push_back(SUMOXMLDefinitions::InsertionChecks.getString(insertionCheckValue));
1099 : }
1100 : }
1101 0 : return toString(insertionChecksStrs);
1102 0 : }
1103 : }
1104 :
1105 :
1106 : bool
1107 0 : SUMOVehicleParameter::areInsertionChecksValid(const std::string& value) const {
1108 0 : if (value.empty()) {
1109 : return true;
1110 : } else {
1111 : // split value in substrinsg
1112 0 : StringTokenizer valueStrs(value, " ");
1113 : // iterate over values
1114 0 : while (valueStrs.hasNext()) {
1115 0 : if (!SUMOXMLDefinitions::InsertionChecks.hasString(valueStrs.next())) {
1116 : return false;
1117 : }
1118 : }
1119 : return true;
1120 0 : }
1121 : }
1122 :
1123 :
1124 : int
1125 43775 : SUMOVehicleParameter::parseInsertionChecks(const std::string& value) {
1126 : // first reset insertionChecks
1127 : int result = 0;
1128 43775 : if (value.empty()) {
1129 : return (int)InsertionCheck::ALL;
1130 : } else {
1131 : // split value in substrinsg
1132 131325 : StringTokenizer insertionCheckStrs(value, " ");
1133 90439 : while (insertionCheckStrs.hasNext()) {
1134 46668 : std::string val = insertionCheckStrs.next();
1135 : if (SUMOXMLDefinitions::InsertionChecks.hasString(val)) {
1136 46664 : result |= (int)SUMOXMLDefinitions::InsertionChecks.get(val);
1137 : } else {
1138 12 : throw InvalidArgument("Unknown value '" + val + "' in " + toString(SUMO_ATTR_INSERTIONCHECKS) + ".");
1139 : }
1140 : }
1141 43775 : }
1142 43771 : return result;
1143 : }
1144 :
1145 : /****************************************************************************/
|