SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SUMOVehicleParserHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // Helper methods for parsing vehicle attributes
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
14 // Copyright (C) 2008-2014 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <utils/common/ToString.h>
43 
44 #ifdef CHECK_MEMORY_LEAKS
45 #include <foreign/nvwa/debug_new.h>
46 #endif // CHECK_MEMORY_LEAKS
47 
48 
49 // ===========================================================================
50 // static members
51 // ===========================================================================
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
59 SUMOVehicleParserHelper::parseFlowAttributes(const SUMOSAXAttributes& attrs, const SUMOTime beginDefault, const SUMOTime endDefault) {
60  bool ok = true;
61  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
63  throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
64  "' and '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
65  "' has to be given in the definition of flow '" + id + "'.");
66  }
68  throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
69  "' and '" + attrs.getName(SUMO_ATTR_PROB) +
70  "' has to be given in the definition of flow '" + id + "'.");
71  }
73  throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PROB) +
74  "' and '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
75  "' has to be given in the definition of flow '" + id + "'.");
76  }
79  throw ProcessError("If '" + attrs.getName(SUMO_ATTR_PERIOD) +
80  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
81  "' or '" + attrs.getName(SUMO_ATTR_PROB) +
82  "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) +
83  "' and '" + attrs.getName(SUMO_ATTR_NUMBER) +
84  "' are allowed in flow '" + id + "'.");
85  }
86  } else {
87  if (!attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
88  throw ProcessError("At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) +
89  "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) +
90  "', '" + attrs.getName(SUMO_ATTR_PROB) +
91  "', and '" + attrs.getName(SUMO_ATTR_NUMBER) +
92  "' is needed in flow '" + id + "'.");
93  }
94  }
96  ret->id = id;
97  try {
98  parseCommonAttributes(attrs, ret, "flow");
99  } catch (ProcessError&) {
100  delete ret;
101  throw;
102  }
103 
104  // parse repetition information
105  if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) {
107 #ifdef HAVE_SUBSECOND_TIMESTEPS
108  ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok);
109 #else
110  ret->repetitionOffset = attrs.get<SUMOReal>(SUMO_ATTR_PERIOD, id.c_str(), ok);
111 #endif
112  }
113  if (attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR)) {
115  const SUMOReal vph = attrs.get<SUMOReal>(SUMO_ATTR_VEHSPERHOUR, id.c_str(), ok);
116  if (ok && vph <= 0) {
117  delete ret;
118  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
119  }
120  if (ok && vph != 0) {
121  ret->repetitionOffset = TIME2STEPS(3600. / vph);
122  }
123  }
124  if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
125  ret->repetitionProbability = attrs.get<SUMOReal>(SUMO_ATTR_PROB, id.c_str(), ok);
126  if (ok && (ret->repetitionProbability < 0 || ret->repetitionProbability > 1)) {
127  delete ret;
128  throw ProcessError("Invalid repetition probability in the definition of flow '" + id + "'.");
129  }
130  }
131 
132  ret->depart = beginDefault;
133  if (attrs.hasAttribute(SUMO_ATTR_BEGIN)) {
134  ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok);
135  }
136  if (ok && ret->depart < 0) {
137  delete ret;
138  throw ProcessError("Negative begin time in the definition of flow '" + id + "'.");
139  }
140  SUMOTime end = endDefault;
141  if (end < 0) {
142  end = SUMOTime_MAX;
143  }
144  if (attrs.hasAttribute(SUMO_ATTR_END)) {
145  end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok);
146  }
147  if (ok && end <= ret->depart) {
148  delete ret;
149  throw ProcessError("Flow '" + id + "' ends before or at its begin time.");
150  }
151  if (attrs.hasAttribute(SUMO_ATTR_NUMBER)) {
152  ret->repetitionNumber = attrs.get<int>(SUMO_ATTR_NUMBER, id.c_str(), ok);
154  if (ret->repetitionNumber == 0) {
155  WRITE_WARNING("Flow '" + id + "' has 0 vehicles; will skip it.");
156  } else {
157  if (ok && ret->repetitionNumber < 0) {
158  delete ret;
159  throw ProcessError("Negative repetition number in the definition of flow '" + id + "'.");
160  }
161  if (ok && ret->repetitionOffset < 0) {
162  ret->repetitionOffset = (end - ret->depart) / ret->repetitionNumber;
163  }
164  }
165  } else {
166  // interpret repetitionNumber
167  if (ok && ret->repetitionProbability >= 0) {
168  ret->repetitionNumber = INT_MAX;
169  } else {
170  if (ok && ret->repetitionOffset <= 0) {
171  delete ret;
172  throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'.");
173  }
174  if (end == SUMOTime_MAX) {
175  ret->repetitionNumber = INT_MAX;
176  } else {
177  ret->repetitionNumber = static_cast<int>(static_cast<SUMOReal>(end - ret->depart) / ret->repetitionOffset + 0.5);
178  }
179  }
180  }
181  if (!ok) {
182  delete ret;
183  throw ProcessError();
184  }
185  return ret;
186 }
187 
188 
191  bool optionalID, bool skipDepart) {
192  bool ok = true;
193  std::string id, errorMsg;
194  if (optionalID) {
195  id = attrs.getOpt<std::string>(SUMO_ATTR_ID, 0, ok, "");
196  } else {
197  id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
198  }
200  ret->id = id;
201  try {
202  parseCommonAttributes(attrs, ret, "vehicle");
203  if (!skipDepart) {
204  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPART, ret->id.c_str(), ok);
205  if (!ok || !SUMOVehicleParameter::parseDepart(helper, "vehicle", ret->id, ret->depart, ret->departProcedure, errorMsg)) {
206  throw ProcessError(errorMsg);
207  }
208  }
209  } catch (ProcessError&) {
210  delete ret;
211  throw;
212  }
213  return ret;
214 }
215 
216 
217 void
219  SUMOVehicleParameter* ret, std::string element) {
220  //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, "");
221  bool ok = true;
222  // parse route information
223  if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) {
224  ret->setParameter |= VEHPARS_ROUTE_SET; // !!! needed?
225  ret->routeid = attrs.get<std::string>(SUMO_ATTR_ROUTE, ret->id.c_str(), ok);
226  }
227  // parse type information
228  if (attrs.hasAttribute(SUMO_ATTR_TYPE)) {
229  ret->setParameter |= VEHPARS_VTYPE_SET; // !!! needed?
230  ret->vtypeid = attrs.get<std::string>(SUMO_ATTR_TYPE, ret->id.c_str(), ok);
231  }
232  // parse line information
233  if (attrs.hasAttribute(SUMO_ATTR_LINE)) {
234  ret->setParameter |= VEHPARS_LINE_SET; // !!! needed?
235  ret->line = attrs.get<std::string>(SUMO_ATTR_LINE, ret->id.c_str(), ok);
236  }
237  // parse zone information
240  ret->fromTaz = attrs.get<std::string>(SUMO_ATTR_FROM_TAZ, ret->id.c_str(), ok);
241  ret->toTaz = attrs.get<std::string>(SUMO_ATTR_TO_TAZ, ret->id.c_str(), ok);
242  }
243  // parse reroute information
244  if (attrs.getOpt<bool>(SUMO_ATTR_REROUTE, 0, ok, false)) {
246  }
247 
248  std::string error;
249  // parse depart lane information
250  if (attrs.hasAttribute(SUMO_ATTR_DEPARTLANE)) {
252  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTLANE, ret->id.c_str(), ok);
253  if (!SUMOVehicleParameter::parseDepartLane(helper, element, ret->id, ret->departLane, ret->departLaneProcedure, error)) {
254  throw ProcessError(error);
255  }
256  }
257  // parse depart position information
258  if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS)) {
260  const std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTPOS, ret->id.c_str(), ok);
261  if (!SUMOVehicleParameter::parseDepartPos(helper, element, ret->id, ret->departPos, ret->departPosProcedure, error)) {
262  throw ProcessError(error);
263  }
264  }
265  // parse depart speed information
266  if (attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED)) {
268  std::string helper = attrs.get<std::string>(SUMO_ATTR_DEPARTSPEED, ret->id.c_str(), ok);
269  if (!SUMOVehicleParameter::parseDepartSpeed(helper, element, ret->id, ret->departSpeed, ret->departSpeedProcedure, error)) {
270  throw ProcessError(error);
271  }
272  }
273 
274  // parse arrival lane information
275  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE)) {
277  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALLANE, ret->id.c_str(), ok);
278  if (!SUMOVehicleParameter::parseArrivalLane(helper, element, ret->id, ret->arrivalLane, ret->arrivalLaneProcedure, error)) {
279  throw ProcessError(error);
280  }
281  }
282  // parse arrival position information
283  if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS)) {
285  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALPOS, ret->id.c_str(), ok);
286  if (!SUMOVehicleParameter::parseArrivalPos(helper, element, ret->id, ret->arrivalPos, ret->arrivalPosProcedure, error)) {
287  throw ProcessError(error);
288  }
289  }
290  // parse arrival speed information
293  std::string helper = attrs.get<std::string>(SUMO_ATTR_ARRIVALSPEED, ret->id.c_str(), ok);
294  if (!SUMOVehicleParameter::parseArrivalSpeed(helper, element, ret->id, ret->arrivalSpeed, ret->arrivalSpeedProcedure, error)) {
295  throw ProcessError(error);
296  }
297  }
298 
299  // parse color
300  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
302  ret->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, ret->id.c_str(), ok);
303  } else {
305  }
306  // parse person capacity
309  ret->personCapacity = attrs.get<int>(SUMO_ATTR_PERSON_CAPACITY, ret->id.c_str(), ok);
310  }
311  // parse person number
314  ret->personNumber = attrs.get<int>(SUMO_ATTR_PERSON_NUMBER, ret->id.c_str(), ok);
315  }
316 }
317 
318 
320 SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs, const std::string& file) {
321  bool ok = true;
322  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
324  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
325  vClass = parseVehicleClass(attrs, id);
326  }
327  SUMOVTypeParameter* vtype = new SUMOVTypeParameter(id, vClass);
328  if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) {
329  vtype->length = attrs.get<SUMOReal>(SUMO_ATTR_LENGTH, vtype->id.c_str(), ok);
331  }
332  if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) {
333  vtype->minGap = attrs.get<SUMOReal>(SUMO_ATTR_MINGAP, vtype->id.c_str(), ok);
335  }
336  if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) {
337  vtype->maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_MAXSPEED, vtype->id.c_str(), ok);
339  }
340  if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) {
341  vtype->speedFactor = attrs.get<SUMOReal>(SUMO_ATTR_SPEEDFACTOR, vtype->id.c_str(), ok);
343  }
344  if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) {
345  vtype->speedDev = attrs.get<SUMOReal>(SUMO_ATTR_SPEEDDEV, vtype->id.c_str(), ok);
347  }
349  vtype->emissionClass = parseEmissionClass(attrs, vtype->id);
351  }
352  if (attrs.hasAttribute(SUMO_ATTR_IMPATIENCE)) {
353  if (attrs.get<std::string>(SUMO_ATTR_IMPATIENCE, vtype->id.c_str(), ok) == "off") {
355  } else {
356  vtype->impatience = attrs.get<SUMOReal>(SUMO_ATTR_IMPATIENCE, vtype->id.c_str(), ok);
357  }
359  }
360  if (attrs.hasAttribute(SUMO_ATTR_VCLASS)) {
362  }
363  if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) {
364  vtype->width = attrs.get<SUMOReal>(SUMO_ATTR_WIDTH, vtype->id.c_str(), ok);
366  }
367  if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) {
368  vtype->height = attrs.get<SUMOReal>(SUMO_ATTR_HEIGHT, vtype->id.c_str(), ok);
370  }
371  if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) {
372  vtype->shape = parseGuiShape(attrs, vtype->id);
374  }
375  if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) {
376  vtype->osgFile = attrs.get<std::string>(SUMO_ATTR_OSGFILE, vtype->id.c_str(), ok);
378  }
379  if (attrs.hasAttribute(SUMO_ATTR_IMGFILE)) {
380  vtype->imgFile = attrs.get<std::string>(SUMO_ATTR_IMGFILE, vtype->id.c_str(), ok);
381  if (vtype->imgFile != "" && !FileHelpers::isAbsolute(vtype->imgFile)) {
383  }
385  }
386  if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
387  vtype->color = attrs.get<RGBColor>(SUMO_ATTR_COLOR, vtype->id.c_str(), ok);
389  } else {
390  vtype->color = RGBColor::YELLOW;
391  }
392  if (attrs.hasAttribute(SUMO_ATTR_PROB)) {
393  vtype->defaultProbability = attrs.get<SUMOReal>(SUMO_ATTR_PROB, vtype->id.c_str(), ok);
395  }
397  const std::string lcmS = attrs.get<std::string>(SUMO_ATTR_LANE_CHANGE_MODEL, vtype->id.c_str(), ok);
398  if (SUMOXMLDefinitions::LaneChangeModels.hasString(lcmS)) {
401  } else {
402  WRITE_ERROR("Unknown lane change model '" + lcmS + "' when parsing vtype '" + vtype->id + "'");
403  throw ProcessError();
404  }
405  }
406  try {
407  parseVTypeEmbedded(*vtype, SUMO_TAG_CF_KRAUSS, attrs, true);
408  } catch (ProcessError&) {
409  throw;
410  }
411  if (!ok) {
412  delete vtype;
413  throw ProcessError();
414  }
415  return vtype;
416 }
417 
418 
419 void
421  int element, const SUMOSAXAttributes& attrs,
422  bool fromVType) {
423  const CFAttrMap& allowedAttrs = getAllowedCFModelAttrs();
424  CFAttrMap::const_iterator cf_it;
425  for (cf_it = allowedAttrs.begin(); cf_it != allowedAttrs.end(); cf_it++) {
426  if (cf_it->first == element) {
427  break;
428  }
429  }
430  if (cf_it == allowedAttrs.end()) {
431  if (SUMOXMLDefinitions::Tags.has(element)) {
432  WRITE_ERROR("Unknown cfmodel " + toString((SumoXMLTag)element) + " when parsing vtype '" + into.id + "'");
433  } else {
434  WRITE_ERROR("Unknown cfmodel when parsing vtype '" + into.id + "'");
435  }
436  throw ProcessError();
437  return;
438  }
439  if (!fromVType) {
440  into.cfModel = cf_it->first;
441  }
442  bool ok = true;
443  for (std::set<SumoXMLAttr>::const_iterator it = cf_it->second.begin(); it != cf_it->second.end(); it++) {
444  if (attrs.hasAttribute(*it)) {
445  into.cfParameter[*it] = attrs.get<SUMOReal>(*it, into.id.c_str(), ok);
446  if (*it == SUMO_ATTR_TAU && TIME2STEPS(into.cfParameter[*it]) < DELTA_T) {
447  WRITE_WARNING("Value of tau=" + toString(into.cfParameter[*it])
448  + " in car following model '" + toString(into.cfModel) + "' lower than simulation step size may cause collisions");
449  }
450  }
451  }
452  if (!ok) {
453  throw ProcessError();
454  }
455 }
456 
457 
460  // init on first use
461  if (allowedCFModelAttrs.size() == 0) {
462  std::set<SumoXMLAttr> krausParams;
463  krausParams.insert(SUMO_ATTR_ACCEL);
464  krausParams.insert(SUMO_ATTR_DECEL);
465  krausParams.insert(SUMO_ATTR_SIGMA);
466  krausParams.insert(SUMO_ATTR_TAU);
470 
471  std::set<SumoXMLAttr> smartSKParams;
472  smartSKParams.insert(SUMO_ATTR_ACCEL);
473  smartSKParams.insert(SUMO_ATTR_DECEL);
474  smartSKParams.insert(SUMO_ATTR_SIGMA);
475  smartSKParams.insert(SUMO_ATTR_TAU);
476  smartSKParams.insert(SUMO_ATTR_TMP1);
477  smartSKParams.insert(SUMO_ATTR_TMP2);
478  smartSKParams.insert(SUMO_ATTR_TMP3);
479  smartSKParams.insert(SUMO_ATTR_TMP4);
480  smartSKParams.insert(SUMO_ATTR_TMP5);
481  allowedCFModelAttrs[SUMO_TAG_CF_SMART_SK] = smartSKParams;
482 
483  std::set<SumoXMLAttr> daniel1Params;
484  daniel1Params.insert(SUMO_ATTR_ACCEL);
485  daniel1Params.insert(SUMO_ATTR_DECEL);
486  daniel1Params.insert(SUMO_ATTR_SIGMA);
487  daniel1Params.insert(SUMO_ATTR_TAU);
488  daniel1Params.insert(SUMO_ATTR_TMP1);
489  daniel1Params.insert(SUMO_ATTR_TMP2);
490  daniel1Params.insert(SUMO_ATTR_TMP3);
491  daniel1Params.insert(SUMO_ATTR_TMP4);
492  daniel1Params.insert(SUMO_ATTR_TMP5);
493  allowedCFModelAttrs[SUMO_TAG_CF_DANIEL1] = daniel1Params;
494 
495  std::set<SumoXMLAttr> pwagParams;
496  pwagParams.insert(SUMO_ATTR_ACCEL);
497  pwagParams.insert(SUMO_ATTR_DECEL);
498  pwagParams.insert(SUMO_ATTR_SIGMA);
499  pwagParams.insert(SUMO_ATTR_TAU);
500  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST);
501  pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB);
503 
504  std::set<SumoXMLAttr> idmParams;
505  idmParams.insert(SUMO_ATTR_ACCEL);
506  idmParams.insert(SUMO_ATTR_DECEL);
507  idmParams.insert(SUMO_ATTR_TAU);
508  idmParams.insert(SUMO_ATTR_CF_IDM_DELTA);
509  idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
511 
512  std::set<SumoXMLAttr> idmmParams;
513  idmmParams.insert(SUMO_ATTR_ACCEL);
514  idmmParams.insert(SUMO_ATTR_DECEL);
515  idmmParams.insert(SUMO_ATTR_TAU);
516  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR);
517  idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME);
518  idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING);
520 
521  std::set<SumoXMLAttr> bkernerParams;
522  bkernerParams.insert(SUMO_ATTR_ACCEL);
523  bkernerParams.insert(SUMO_ATTR_DECEL);
524  bkernerParams.insert(SUMO_ATTR_TAU);
525  bkernerParams.insert(SUMO_ATTR_K);
526  bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI);
527  allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams;
528 
529  std::set<SumoXMLAttr> wiedemannParams;
530  wiedemannParams.insert(SUMO_ATTR_ACCEL);
531  wiedemannParams.insert(SUMO_ATTR_DECEL);
532  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY);
533  wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION);
534  allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams;
535  }
536  return allowedCFModelAttrs;
537 }
538 
539 
542  const std::string& id) {
544  try {
545  bool ok = true;
546  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_VCLASS, id.c_str(), ok, "");
547  if (vclassS == "") {
548  return vclass;
549  }
550  const SUMOVehicleClass result = getVehicleClassID(vclassS);
551  const std::string& realName = SumoVehicleClassStrings.getString(result);
552  if (realName != vclassS) {
553  WRITE_WARNING("The vehicle class '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
554  }
555  return result;
556  } catch (...) {
557  WRITE_ERROR("The class for " + attrs.getObjectType() + " '" + id + "' is not known.");
558  }
559  return vclass;
560 }
561 
562 
565  try {
566  bool ok = true;
567  std::string eClassS = attrs.getOpt<std::string>(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, "");
568  return PollutantsInterface::getClassByName(eClassS);
569  } catch (...) {
570  WRITE_ERROR("The emission class for " + attrs.getObjectType() + " '" + id + "' is not known.");
571  return 0;
572  }
573 }
574 
575 
577 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) {
578  bool ok = true;
579  std::string vclassS = attrs.getOpt<std::string>(SUMO_ATTR_GUISHAPE, id.c_str(), ok, "");
580  if (SumoVehicleShapeStrings.hasString(vclassS)) {
581  const SUMOVehicleShape result = SumoVehicleShapeStrings.get(vclassS);
582  const std::string& realName = SumoVehicleShapeStrings.getString(result);
583  if (realName != vclassS) {
584  WRITE_WARNING("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is deprecated, use '" + realName + "' instead.");
585  }
586  return result;
587  } else {
588  WRITE_ERROR("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is not known.");
589  return SVS_UNKNOWN;
590  }
591 }
592 
593 /****************************************************************************/
594