SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00011 // Helper methods for parsing vehicle attributes 00012 /****************************************************************************/ 00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00014 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00015 /****************************************************************************/ 00016 // 00017 // This file is part of SUMO. 00018 // SUMO is free software: you can redistribute it and/or modify 00019 // it under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation, either version 3 of the License, or 00021 // (at your option) any later version. 00022 // 00023 /****************************************************************************/ 00024 00025 00026 // =========================================================================== 00027 // included modules 00028 // =========================================================================== 00029 #ifdef _MSC_VER 00030 #include <windows_config.h> 00031 #else 00032 #include <config.h> 00033 #endif 00034 00035 #include <utils/common/ToString.h> 00036 #include <utils/common/UtilExceptions.h> 00037 #include <utils/common/MsgHandler.h> 00038 #include <utils/common/TplConvert.h> 00039 #include <utils/common/SUMOVehicleParameter.h> 00040 #include <utils/options/OptionsCont.h> 00041 #include "SUMOVehicleParserHelper.h" 00042 00043 #ifdef CHECK_MEMORY_LEAKS 00044 #include <foreign/nvwa/debug_new.h> 00045 #endif // CHECK_MEMORY_LEAKS 00046 00047 00048 // =========================================================================== 00049 // static members 00050 // =========================================================================== 00051 SUMOVehicleParserHelper::CFAttrMap SUMOVehicleParserHelper::allowedCFModelAttrs; 00052 00053 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedNumber = false; 00054 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedTazs = false; 00055 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedDepartLane = false; 00056 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedDepartPos = false; 00057 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedDepartSpeed = false; 00058 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedArrivalLane = false; 00059 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedArrivalPos = false; 00060 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedArrivalSpeed = false; 00061 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedMaxSpeed = false; 00062 bool SUMOVehicleParserHelper::gHaveWarnedAboutDeprecatedVClass = false; 00063 00064 00065 // =========================================================================== 00066 // method definitions 00067 // =========================================================================== 00068 SUMOVehicleParameter* 00069 SUMOVehicleParserHelper::parseFlowAttributes(const SUMOSAXAttributes& attrs) { 00070 bool ok = true; 00071 std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok); 00072 if (attrs.hasAttribute(SUMO_ATTR_PERIOD) && attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR)) { 00073 throw ProcessError("At most one of '" + attrs.getName(SUMO_ATTR_PERIOD) + 00074 "' and '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) + 00075 "' has to be given in the definition of flow '" + id + "'."); 00076 } 00077 if (attrs.hasAttribute(SUMO_ATTR_PERIOD) || attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR)) { 00078 if (attrs.hasAttribute(SUMO_ATTR_END) && (attrs.hasAttribute(SUMO_ATTR_NO__DEPRECATED) || attrs.hasAttribute(SUMO_ATTR_NUMBER))) { 00079 throw ProcessError("If '" + attrs.getName(SUMO_ATTR_PERIOD) + 00080 "' or '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) + 00081 "' are given at most one of '" + attrs.getName(SUMO_ATTR_END) + 00082 "' and '" + attrs.getName(SUMO_ATTR_NUMBER) + 00083 "' are allowed in flow '" + id + "'."); 00084 } 00085 } else { 00086 if (!attrs.hasAttribute(SUMO_ATTR_NO__DEPRECATED) && !attrs.hasAttribute(SUMO_ATTR_NUMBER)) { 00087 throw ProcessError("At least one of '" + attrs.getName(SUMO_ATTR_PERIOD) + 00088 "', '" + attrs.getName(SUMO_ATTR_VEHSPERHOUR) + 00089 "', and '" + attrs.getName(SUMO_ATTR_NUMBER) + 00090 "' is needed in flow '" + id + "'."); 00091 } 00092 } 00093 SUMOVehicleParameter* ret = new SUMOVehicleParameter(); 00094 ret->id = id; 00095 parseCommonAttributes(attrs, ret, "flow"); 00096 00097 // parse repetition information 00098 if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) { 00099 ret->setParameter |= VEHPARS_PERIODFREQ_SET; 00100 #ifdef HAVE_SUBSECOND_TIMESTEPS 00101 ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok); 00102 #else 00103 ret->repetitionOffset = attrs.getSUMORealReporting(SUMO_ATTR_PERIOD, id.c_str(), ok); 00104 #endif 00105 } 00106 if (attrs.hasAttribute(SUMO_ATTR_VEHSPERHOUR)) { 00107 ret->setParameter |= VEHPARS_PERIODFREQ_SET; 00108 const SUMOReal vph = attrs.getSUMORealReporting(SUMO_ATTR_VEHSPERHOUR, id.c_str(), ok); 00109 if (ok && vph <= 0) { 00110 delete ret; 00111 throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'."); 00112 } 00113 if (ok && vph != 0) { 00114 ret->repetitionOffset = TIME2STEPS(3600. / vph); 00115 } 00116 } 00117 00118 ret->depart = string2time(OptionsCont::getOptions().getString("begin")); 00119 if (attrs.hasAttribute(SUMO_ATTR_BEGIN)) { 00120 ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_BEGIN, id.c_str(), ok); 00121 } 00122 if (ok && ret->depart < 0) { 00123 delete ret; 00124 throw ProcessError("Negative begin time in the definition of flow '" + id + "'."); 00125 } 00126 SUMOTime end = string2time(OptionsCont::getOptions().getString("end")); 00127 if (end < 0) { 00128 end = SUMOTime_MAX; 00129 } 00130 if (attrs.hasAttribute(SUMO_ATTR_END)) { 00131 end = attrs.getSUMOTimeReporting(SUMO_ATTR_END, id.c_str(), ok); 00132 } 00133 if (ok && end <= ret->depart) { 00134 delete ret; 00135 throw ProcessError("Flow '" + id + "' ends before or at its begin time."); 00136 } 00137 if (attrs.hasAttribute(SUMO_ATTR_NO__DEPRECATED) || attrs.hasAttribute(SUMO_ATTR_NUMBER)) { 00138 ret->repetitionNumber = attrs.hasAttribute(SUMO_ATTR_NUMBER) 00139 ? attrs.getIntReporting(SUMO_ATTR_NUMBER, id.c_str(), ok) 00140 : attrs.getIntReporting(SUMO_ATTR_NO__DEPRECATED, id.c_str(), ok); 00141 if (!gHaveWarnedAboutDeprecatedNumber && attrs.hasAttribute(SUMO_ATTR_NO__DEPRECATED)) { 00142 gHaveWarnedAboutDeprecatedNumber = true; 00143 WRITE_WARNING("'" + toString(SUMO_ATTR_NO__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_NUMBER) + "' instead."); 00144 } 00145 ret->setParameter |= VEHPARS_PERIODFREQ_SET; 00146 if (ok && ret->repetitionNumber < 0) { 00147 delete ret; 00148 throw ProcessError("Negative repetition number in the definition of flow '" + id + "'."); 00149 } 00150 if (ok && ret->repetitionOffset < 0) { 00151 ret->repetitionOffset = (end - ret->depart) / ret->repetitionNumber; 00152 } 00153 } else { 00154 if (ok && ret->repetitionOffset <= 0) { 00155 delete ret; 00156 throw ProcessError("Invalid repetition rate in the definition of flow '" + id + "'."); 00157 } 00158 if (end == SUMOTime_MAX) { 00159 ret->repetitionNumber = INT_MAX; 00160 } else { 00161 ret->repetitionNumber = static_cast<int>(static_cast<SUMOReal>(end - ret->depart) / ret->repetitionOffset + 0.5); 00162 } 00163 } 00164 if (!ok) { 00165 delete ret; 00166 throw ProcessError(); 00167 } 00168 return ret; 00169 } 00170 00171 00172 SUMOVehicleParameter* 00173 SUMOVehicleParserHelper::parseVehicleAttributes(const SUMOSAXAttributes& attrs, 00174 bool skipID, bool skipDepart) { 00175 bool ok = true; 00176 std::string id, errorMsg; 00177 if (!skipID) { 00178 id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok); 00179 } 00180 if (attrs.hasAttribute(SUMO_ATTR_PERIOD) ^ attrs.hasAttribute(SUMO_ATTR_REPNUMBER)) { 00181 throw ProcessError("The attributes '" + attrs.getName(SUMO_ATTR_PERIOD) + 00182 "' and '" + attrs.getName(SUMO_ATTR_REPNUMBER) + 00183 "' have to be given both in the definition of '" + id + "'."); 00184 } 00185 SUMOVehicleParameter* ret = new SUMOVehicleParameter(); 00186 ret->id = id; 00187 try { 00188 parseCommonAttributes(attrs, ret, "vehicle"); 00189 } catch (ProcessError&) { 00190 delete ret; 00191 throw; 00192 } 00193 if (!skipDepart) { 00194 const std::string helper = attrs.getStringReporting(SUMO_ATTR_DEPART, 0, ok); 00195 if (helper == "triggered") { 00196 ret->departProcedure = DEPART_TRIGGERED; 00197 } else { 00198 ret->departProcedure = DEPART_GIVEN; 00199 ret->depart = attrs.getSUMOTimeReporting(SUMO_ATTR_DEPART, id.c_str(), ok); 00200 if (ok && ret->depart < 0) { 00201 errorMsg = "Negative departure time in the definition of '" + id + "'."; 00202 ok = false; 00203 } 00204 } 00205 } 00206 // parse repetition information 00207 if (attrs.hasAttribute(SUMO_ATTR_PERIOD)) { 00208 WRITE_WARNING("period and repno are deprecated in vehicle '" + id + "', use flows instead."); 00209 ret->setParameter |= VEHPARS_PERIODFREQ_SET; 00210 #ifdef HAVE_SUBSECOND_TIMESTEPS 00211 ret->repetitionOffset = attrs.getSUMOTimeReporting(SUMO_ATTR_PERIOD, id.c_str(), ok); 00212 #else 00213 ret->repetitionOffset = attrs.getSUMORealReporting(SUMO_ATTR_PERIOD, id.c_str(), ok); 00214 #endif 00215 } 00216 if (attrs.hasAttribute(SUMO_ATTR_REPNUMBER)) { 00217 ret->setParameter |= VEHPARS_PERIODNUM_SET; 00218 ret->repetitionNumber = attrs.getIntReporting(SUMO_ATTR_REPNUMBER, id.c_str(), ok); 00219 } 00220 00221 if (!ok) { 00222 delete ret; 00223 throw ProcessError(errorMsg); 00224 } 00225 return ret; 00226 } 00227 00228 00229 void 00230 SUMOVehicleParserHelper::parseCommonAttributes(const SUMOSAXAttributes& attrs, 00231 SUMOVehicleParameter* ret, std::string element) { 00232 //ret->refid = attrs.getStringSecure(SUMO_ATTR_REFID, ""); 00233 bool ok = true; 00234 // parse route information 00235 if (attrs.hasAttribute(SUMO_ATTR_ROUTE)) { 00236 ret->setParameter |= VEHPARS_ROUTE_SET; // !!! needed? 00237 ret->routeid = attrs.getStringReporting(SUMO_ATTR_ROUTE, 0, ok); 00238 } 00239 // parse type information 00240 if (attrs.hasAttribute(SUMO_ATTR_TYPE)) { 00241 ret->setParameter |= VEHPARS_VTYPE_SET; // !!! needed? 00242 ret->vtypeid = attrs.getStringReporting(SUMO_ATTR_TYPE, 0, ok); 00243 } 00244 // parse line information 00245 if (attrs.hasAttribute(SUMO_ATTR_LINE)) { 00246 ret->setParameter |= VEHPARS_LINE_SET; // !!! needed? 00247 ret->line = attrs.getStringReporting(SUMO_ATTR_LINE, 0, ok); 00248 } 00249 // parse zone information 00250 if ((attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) || attrs.hasAttribute(SUMO_ATTR_FROM_TAZ__DEPRECATED)) 00251 && 00252 (attrs.hasAttribute(SUMO_ATTR_TO_TAZ) || attrs.hasAttribute(SUMO_ATTR_TO_TAZ__DEPRECATED))) { 00253 ret->setParameter |= VEHPARS_TAZ_SET; 00254 ret->fromTaz = attrs.hasAttribute(SUMO_ATTR_FROM_TAZ) 00255 ? attrs.getStringReporting(SUMO_ATTR_FROM_TAZ, 0, ok) 00256 : attrs.getStringReporting(SUMO_ATTR_FROM_TAZ__DEPRECATED, 0, ok); 00257 ret->toTaz = attrs.hasAttribute(SUMO_ATTR_TO_TAZ) 00258 ? attrs.getStringReporting(SUMO_ATTR_TO_TAZ, 0, ok) 00259 : attrs.getStringReporting(SUMO_ATTR_TO_TAZ__DEPRECATED, 0, ok); 00260 if (!gHaveWarnedAboutDeprecatedTazs && (attrs.hasAttribute(SUMO_ATTR_TO_TAZ__DEPRECATED) || attrs.hasAttribute(SUMO_ATTR_FROM_TAZ__DEPRECATED))) { 00261 gHaveWarnedAboutDeprecatedTazs = true; 00262 WRITE_WARNING("'" + toString(SUMO_ATTR_FROM_TAZ__DEPRECATED) 00263 + "'/'" + toString(SUMO_ATTR_TO_TAZ__DEPRECATED) 00264 + "' is deprecated, please use '" + toString(SUMO_ATTR_FROM_TAZ) 00265 + "'/'" + toString(SUMO_ATTR_TO_TAZ) 00266 + "' instead."); 00267 } 00268 } 00269 // parse reroute information 00270 if (attrs.getOptBoolReporting(SUMO_ATTR_REROUTE, 0, ok, false)) { 00271 ret->setParameter |= VEHPARS_FORCE_REROUTE; 00272 } 00273 00274 // parse depart lane information 00275 if (attrs.hasAttribute(SUMO_ATTR_DEPARTLANE) || attrs.hasAttribute(SUMO_ATTR_DEPARTLANE__DEPRECATED)) { 00276 ret->setParameter |= VEHPARS_DEPARTLANE_SET; 00277 const std::string helper = attrs.hasAttribute(SUMO_ATTR_DEPARTLANE) 00278 ? attrs.getStringReporting(SUMO_ATTR_DEPARTLANE, 0, ok) 00279 : attrs.getStringReporting(SUMO_ATTR_DEPARTLANE__DEPRECATED, 0, ok); 00280 if (!gHaveWarnedAboutDeprecatedDepartLane && attrs.hasAttribute(SUMO_ATTR_DEPARTLANE__DEPRECATED)) { 00281 gHaveWarnedAboutDeprecatedDepartLane = true; 00282 WRITE_WARNING("'" + toString(SUMO_ATTR_DEPARTLANE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_DEPARTLANE) + "' instead."); 00283 } 00284 if (helper == "random") { 00285 ret->departLaneProcedure = DEPART_LANE_RANDOM; 00286 } else if (helper == "free") { 00287 ret->departLaneProcedure = DEPART_LANE_FREE; 00288 } else if (helper == "allowed") { 00289 ret->departLaneProcedure = DEPART_LANE_ALLOWED_FREE; 00290 } else if (helper == "best") { 00291 ret->departLaneProcedure = DEPART_LANE_BEST_FREE; 00292 } else { 00293 try { 00294 ret->departLane = TplConvert<char>::_2int(helper.c_str()); 00295 ret->departLaneProcedure = DEPART_LANE_GIVEN; 00296 if (ret->departLane < 0) { 00297 throw ProcessError("Invalid departLane definition for " + element + " '" + ret->id + "'"); 00298 } 00299 } catch (NumberFormatException&) { 00300 throw ProcessError("Invalid departLane definition for " + element + " '" + ret->id + "'"); 00301 } catch (EmptyData&) { 00302 throw ProcessError("Invalid departLane definition for " + element + " '" + ret->id + "'"); 00303 } 00304 } 00305 } 00306 // parse depart position information 00307 if (attrs.hasAttribute(SUMO_ATTR_DEPARTPOS) || attrs.hasAttribute(SUMO_ATTR_DEPARTPOS__DEPRECATED)) { 00308 ret->setParameter |= VEHPARS_DEPARTPOS_SET; 00309 const std::string helper = attrs.hasAttribute(SUMO_ATTR_DEPARTPOS) 00310 ? attrs.getStringReporting(SUMO_ATTR_DEPARTPOS, 0, ok) 00311 : attrs.getStringReporting(SUMO_ATTR_DEPARTPOS__DEPRECATED, 0, ok); 00312 if (!gHaveWarnedAboutDeprecatedDepartPos && attrs.hasAttribute(SUMO_ATTR_DEPARTPOS__DEPRECATED)) { 00313 gHaveWarnedAboutDeprecatedDepartPos = true; 00314 WRITE_WARNING("'" + toString(SUMO_ATTR_DEPARTPOS__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_DEPARTPOS) + "' instead."); 00315 } 00316 if (helper == "random") { 00317 ret->departPosProcedure = DEPART_POS_RANDOM; 00318 } else if (helper == "random_free") { 00319 ret->departPosProcedure = DEPART_POS_RANDOM_FREE; 00320 } else if (helper == "free") { 00321 ret->departPosProcedure = DEPART_POS_FREE; 00322 } else if (helper == "base") { 00323 ret->departPosProcedure = DEPART_POS_BASE; 00324 } else if (helper == "pwagSimple") { 00325 ret->departPosProcedure = DEPART_POS_PWAG_SIMPLE; 00326 } else if (helper == "pwagGeneric") { 00327 ret->departPosProcedure = DEPART_POS_PWAG_GENERIC; 00328 } else if (helper == "maxSpeedGap") { 00329 ret->departPosProcedure = DEPART_POS_MAX_SPEED_GAP; 00330 } else { 00331 try { 00332 ret->departPos = TplConvert<char>::_2SUMOReal(helper.c_str()); 00333 ret->departPosProcedure = DEPART_POS_GIVEN; 00334 } catch (NumberFormatException&) { 00335 throw ProcessError("Invalid departPos definition for " + element + " '" + ret->id + "'"); 00336 } catch (EmptyData&) { 00337 throw ProcessError("Invalid departPos definition for " + element + " '" + ret->id + "'"); 00338 } 00339 } 00340 } 00341 // parse depart speed information 00342 if (attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED) || attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED__DEPRECATED)) { 00343 ret->setParameter |= VEHPARS_DEPARTSPEED_SET; 00344 std::string helper = attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED) 00345 ? attrs.getStringReporting(SUMO_ATTR_DEPARTSPEED, 0, ok) 00346 : attrs.getStringReporting(SUMO_ATTR_DEPARTSPEED__DEPRECATED, 0, ok); 00347 if (!gHaveWarnedAboutDeprecatedDepartSpeed && attrs.hasAttribute(SUMO_ATTR_DEPARTSPEED__DEPRECATED)) { 00348 gHaveWarnedAboutDeprecatedDepartSpeed = true; 00349 WRITE_WARNING("'" + toString(SUMO_ATTR_DEPARTSPEED__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_DEPARTSPEED) + "' instead."); 00350 } 00351 if (helper == "random") { 00352 ret->departSpeedProcedure = DEPART_SPEED_RANDOM; 00353 } else if (helper == "max") { 00354 ret->departSpeedProcedure = DEPART_SPEED_MAX; 00355 } else { 00356 try { 00357 ret->departSpeed = TplConvert<char>::_2SUMOReal(helper.c_str()); 00358 ret->departSpeedProcedure = DEPART_SPEED_GIVEN; 00359 } catch (NumberFormatException&) { 00360 throw ProcessError("Invalid departSpeed definition for " + element + " '" + ret->id + "'"); 00361 } catch (EmptyData&) { 00362 throw ProcessError("Invalid departSpeed definition for " + element + " '" + ret->id + "'"); 00363 } 00364 } 00365 } 00366 00367 // parse arrival lane information 00368 if (attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE) || attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE__DEPRECATED)) { 00369 ret->setParameter |= VEHPARS_ARRIVALLANE_SET; 00370 std::string helper = attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE) 00371 ? attrs.getStringReporting(SUMO_ATTR_ARRIVALLANE, 0, ok) 00372 : attrs.getStringReporting(SUMO_ATTR_ARRIVALLANE__DEPRECATED, 0, ok); 00373 if (!gHaveWarnedAboutDeprecatedArrivalLane && attrs.hasAttribute(SUMO_ATTR_ARRIVALLANE__DEPRECATED)) { 00374 gHaveWarnedAboutDeprecatedArrivalLane = true; 00375 WRITE_WARNING("'" + toString(SUMO_ATTR_ARRIVALLANE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_ARRIVALLANE) + "' instead."); 00376 } 00377 if (helper == "current") { 00378 ret->arrivalLaneProcedure = ARRIVAL_LANE_CURRENT; 00379 } else { 00380 try { 00381 ret->arrivalLane = TplConvert<char>::_2int(helper.c_str()); 00382 ret->arrivalLaneProcedure = ARRIVAL_LANE_GIVEN; 00383 } catch (NumberFormatException&) { 00384 throw ProcessError("Invalid arrivalLane definition for " + element + " '" + ret->id + "'"); 00385 } catch (EmptyData&) { 00386 throw ProcessError("Invalid arrivalLane definition for " + element + " '" + ret->id + "'"); 00387 } 00388 } 00389 } 00390 // parse arrival position information 00391 if (attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS) || attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS__DEPRECATED)) { 00392 ret->setParameter |= VEHPARS_ARRIVALPOS_SET; 00393 std::string helper = attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS) 00394 ? attrs.getStringReporting(SUMO_ATTR_ARRIVALPOS, 0, ok) 00395 : attrs.getStringReporting(SUMO_ATTR_ARRIVALPOS__DEPRECATED, 0, ok); 00396 if (!gHaveWarnedAboutDeprecatedArrivalPos && attrs.hasAttribute(SUMO_ATTR_ARRIVALPOS__DEPRECATED)) { 00397 gHaveWarnedAboutDeprecatedArrivalPos = true; 00398 WRITE_WARNING("'" + toString(SUMO_ATTR_ARRIVALPOS__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_ARRIVALPOS) + "' instead."); 00399 } 00400 if (helper == "random") { 00401 ret->arrivalPosProcedure = ARRIVAL_POS_RANDOM; 00402 } else if (helper == "max") { 00403 ret->arrivalPosProcedure = ARRIVAL_POS_MAX; 00404 } else { 00405 try { 00406 ret->arrivalPos = TplConvert<char>::_2SUMOReal(helper.c_str()); 00407 ret->arrivalPosProcedure = ARRIVAL_POS_GIVEN; 00408 } catch (NumberFormatException&) { 00409 throw ProcessError("Invalid arrivalPos definition for " + element + " '" + ret->id + "'"); 00410 } catch (EmptyData&) { 00411 throw ProcessError("Invalid arrivalPos definition for " + element + " '" + ret->id + "'"); 00412 } 00413 } 00414 } 00415 // parse arrival speed information 00416 if (attrs.hasAttribute(SUMO_ATTR_ARRIVALSPEED) || attrs.hasAttribute(SUMO_ATTR_ARRIVALSPEED__DEPRECATED)) { 00417 ret->setParameter |= VEHPARS_ARRIVALSPEED_SET; 00418 std::string helper = attrs.hasAttribute(SUMO_ATTR_ARRIVALSPEED) 00419 ? attrs.getStringReporting(SUMO_ATTR_ARRIVALSPEED, 0, ok) 00420 : attrs.getStringReporting(SUMO_ATTR_ARRIVALSPEED__DEPRECATED, 0, ok); 00421 if (!gHaveWarnedAboutDeprecatedArrivalSpeed && attrs.hasAttribute(SUMO_ATTR_ARRIVALSPEED__DEPRECATED)) { 00422 gHaveWarnedAboutDeprecatedArrivalSpeed = true; 00423 WRITE_WARNING("'" + toString(SUMO_ATTR_ARRIVALSPEED__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_ARRIVALSPEED) + "' instead."); 00424 } 00425 if (helper == "current") { 00426 ret->arrivalSpeedProcedure = ARRIVAL_SPEED_CURRENT; 00427 } else { 00428 try { 00429 ret->arrivalSpeed = TplConvert<char>::_2SUMOReal(helper.c_str()); 00430 ret->arrivalSpeedProcedure = ARRIVAL_SPEED_GIVEN; 00431 } catch (NumberFormatException&) { 00432 throw ProcessError("Invalid arrivalSpeed definition for " + element + " '" + ret->id + "'"); 00433 } catch (EmptyData&) { 00434 throw ProcessError("Invalid arrivalSpeed definition for " + element + " '" + ret->id + "'"); 00435 } 00436 } 00437 } 00438 00439 // parse color 00440 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) { 00441 ret->setParameter |= VEHPARS_COLOR_SET; 00442 try { 00443 ret->color = RGBColor::parseColor(attrs.getStringReporting(SUMO_ATTR_COLOR, 0, ok)); 00444 } catch (NumberFormatException&) { 00445 throw ProcessError("Invalid color definition for " + element + " '" + ret->id + "'"); 00446 } catch (EmptyData&) { 00447 throw ProcessError("Invalid color definition for " + element + " '" + ret->id + "'"); 00448 } 00449 } else { 00450 ret->color = RGBColor::DEFAULT_COLOR; 00451 } 00452 } 00453 00454 00455 SUMOVTypeParameter* 00456 SUMOVehicleParserHelper::beginVTypeParsing(const SUMOSAXAttributes& attrs) { 00457 SUMOVTypeParameter* vtype = new SUMOVTypeParameter(); 00458 bool ok = true; 00459 vtype->id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok); 00460 if (attrs.hasAttribute(SUMO_ATTR_LENGTH)) { 00461 if (!attrs.hasAttribute(SUMO_ATTR_MINGAP)) { 00462 WRITE_WARNING("The length does not include the gap to the preceeding vehicle anymore! Please recheck your values."); 00463 } 00464 vtype->length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, vtype->id.c_str(), ok); 00465 vtype->setParameter |= VTYPEPARS_LENGTH_SET; 00466 } 00467 if (attrs.hasAttribute(SUMO_ATTR_MINGAP)) { 00468 vtype->minGap = attrs.getSUMORealReporting(SUMO_ATTR_MINGAP, vtype->id.c_str(), ok); 00469 vtype->setParameter |= VTYPEPARS_MINGAP_SET; 00470 } 00471 if (attrs.hasAttribute(SUMO_ATTR_GUIOFFSET)) { 00472 WRITE_WARNING("The guiOffset attribute is deprecated! Please use minGap instead."); 00473 vtype->minGap = attrs.getSUMORealReporting(SUMO_ATTR_GUIOFFSET, vtype->id.c_str(), ok); 00474 vtype->setParameter |= VTYPEPARS_MINGAP_SET; 00475 } 00476 if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED)) { 00477 vtype->maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED, vtype->id.c_str(), ok); 00478 vtype->setParameter |= VTYPEPARS_MAXSPEED_SET; 00479 } else if (attrs.hasAttribute(SUMO_ATTR_MAXSPEED__DEPRECATED)) { 00480 vtype->maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED__DEPRECATED, vtype->id.c_str(), ok); 00481 vtype->setParameter |= VTYPEPARS_MAXSPEED_SET; 00482 if (!gHaveWarnedAboutDeprecatedMaxSpeed) { 00483 gHaveWarnedAboutDeprecatedMaxSpeed = true; 00484 WRITE_WARNING("'" + toString(SUMO_ATTR_MAXSPEED__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_MAXSPEED) + "' instead."); 00485 } 00486 } 00487 if (attrs.hasAttribute(SUMO_ATTR_SPEEDFACTOR)) { 00488 vtype->speedFactor = attrs.getSUMORealReporting(SUMO_ATTR_SPEEDFACTOR, vtype->id.c_str(), ok); 00489 vtype->setParameter |= VTYPEPARS_SPEEDFACTOR_SET; 00490 } 00491 if (attrs.hasAttribute(SUMO_ATTR_SPEEDDEV)) { 00492 vtype->speedDev = attrs.getSUMORealReporting(SUMO_ATTR_SPEEDDEV, vtype->id.c_str(), ok); 00493 vtype->setParameter |= VTYPEPARS_SPEEDDEVIATION_SET; 00494 } 00495 if (attrs.hasAttribute(SUMO_ATTR_EMISSIONCLASS)) { 00496 vtype->emissionClass = parseEmissionClass(attrs, vtype->id); 00497 vtype->setParameter |= VTYPEPARS_EMISSIONCLASS_SET; 00498 } 00499 if (attrs.hasAttribute(SUMO_ATTR_VCLASS) || attrs.hasAttribute(SUMO_ATTR_VCLASS__DEPRECATED)) { 00500 if (!gHaveWarnedAboutDeprecatedVClass && attrs.hasAttribute(SUMO_ATTR_VCLASS__DEPRECATED)) { 00501 gHaveWarnedAboutDeprecatedVClass = true; 00502 WRITE_WARNING("'" + toString(SUMO_ATTR_VCLASS__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_ATTR_VCLASS) + "' instead."); 00503 } 00504 vtype->vehicleClass = parseVehicleClass(attrs, vtype->id); 00505 vtype->setParameter |= VTYPEPARS_VEHICLECLASS_SET; 00506 } 00507 if (attrs.hasAttribute(SUMO_ATTR_WIDTH)) { 00508 vtype->width = attrs.getSUMORealReporting(SUMO_ATTR_WIDTH, vtype->id.c_str(), ok); 00509 vtype->setParameter |= VTYPEPARS_WIDTH_SET; 00510 } 00511 if (attrs.hasAttribute(SUMO_ATTR_HEIGHT)) { 00512 vtype->height = attrs.getSUMORealReporting(SUMO_ATTR_HEIGHT, vtype->id.c_str(), ok); 00513 vtype->setParameter |= VTYPEPARS_HEIGHT_SET; 00514 } 00515 if (attrs.hasAttribute(SUMO_ATTR_GUISHAPE)) { 00516 vtype->shape = parseGuiShape(attrs, vtype->id); 00517 vtype->setParameter |= VTYPEPARS_SHAPE_SET; 00518 } 00519 if (attrs.hasAttribute(SUMO_ATTR_OSGFILE)) { 00520 vtype->osgFile = attrs.getStringReporting(SUMO_ATTR_OSGFILE, vtype->id.c_str(), ok); 00521 vtype->setParameter |= VTYPEPARS_OSGFILE_SET; 00522 } 00523 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) { 00524 vtype->color = RGBColor::parseColorReporting(attrs.getString(SUMO_ATTR_COLOR), attrs.getObjectType(), vtype->id.c_str(), true, ok); 00525 vtype->setParameter |= VTYPEPARS_COLOR_SET; 00526 } else { 00527 vtype->color = RGBColor(1, 1, 0); 00528 } 00529 if (attrs.hasAttribute(SUMO_ATTR_PROB)) { 00530 vtype->defaultProbability = attrs.getSUMORealReporting(SUMO_ATTR_PROB, vtype->id.c_str(), ok); 00531 vtype->setParameter |= VTYPEPARS_PROBABILITY_SET; 00532 } 00533 try { 00534 parseVTypeEmbedded(*vtype, SUMO_TAG_CF_KRAUSS, attrs, true); 00535 } catch (ProcessError&) { 00536 throw; 00537 } 00538 if (!ok) { 00539 delete vtype; 00540 throw ProcessError(); 00541 } 00542 return vtype; 00543 } 00544 00545 00546 void 00547 SUMOVehicleParserHelper::parseVTypeEmbedded(SUMOVTypeParameter& into, 00548 int element, const SUMOSAXAttributes& attrs, 00549 bool fromVType) { 00550 const CFAttrMap& allowedAttrs = getAllowedCFModelAttrs(); 00551 CFAttrMap::const_iterator cf_it; 00552 for (cf_it = allowedAttrs.begin(); cf_it != allowedAttrs.end(); cf_it++) { 00553 if (cf_it->first == element) { 00554 break; 00555 } 00556 } 00557 if (cf_it == allowedAttrs.end()) { 00558 if (SUMOXMLDefinitions::Tags.has(element)) { 00559 WRITE_WARNING("Unknown cfmodel " + toString((SumoXMLTag)element) + " when parsing vtype '" + into.id + "'"); 00560 } else { 00561 WRITE_WARNING("Unknown cfmodel when parsing vtype '" + into.id + "'"); 00562 } 00563 } 00564 if (!fromVType) { 00565 into.cfModel = cf_it->first; 00566 } 00567 bool ok = true; 00568 for (std::set<SumoXMLAttr>::const_iterator it = cf_it->second.begin(); it != cf_it->second.end(); it++) { 00569 if (attrs.hasAttribute(*it)) { 00570 into.cfParameter[*it] = attrs.getSUMORealReporting(*it, into.id.c_str(), ok); 00571 } 00572 } 00573 if (!ok) { 00574 throw ProcessError(); 00575 } 00576 } 00577 00578 00579 const SUMOVehicleParserHelper::CFAttrMap& 00580 SUMOVehicleParserHelper::getAllowedCFModelAttrs() { 00581 // init on first use 00582 if (allowedCFModelAttrs.size() == 0) { 00583 std::set<SumoXMLAttr> krausParams; 00584 krausParams.insert(SUMO_ATTR_ACCEL); 00585 krausParams.insert(SUMO_ATTR_DECEL); 00586 krausParams.insert(SUMO_ATTR_SIGMA); 00587 krausParams.insert(SUMO_ATTR_TAU); 00588 allowedCFModelAttrs[SUMO_TAG_CF_KRAUSS] = krausParams; 00589 allowedCFModelAttrs[SUMO_TAG_CF_KRAUSS_ORIG1] = krausParams; 00590 00591 std::set<SumoXMLAttr> pwagParams; 00592 pwagParams.insert(SUMO_ATTR_ACCEL); 00593 pwagParams.insert(SUMO_ATTR_DECEL); 00594 pwagParams.insert(SUMO_ATTR_SIGMA); 00595 pwagParams.insert(SUMO_ATTR_TAU); 00596 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_TAULAST); 00597 pwagParams.insert(SUMO_ATTR_CF_PWAGNER2009_APPROB); 00598 allowedCFModelAttrs[SUMO_TAG_CF_PWAGNER2009] = pwagParams; 00599 00600 std::set<SumoXMLAttr> idmParams; 00601 idmParams.insert(SUMO_ATTR_ACCEL); 00602 idmParams.insert(SUMO_ATTR_DECEL); 00603 idmParams.insert(SUMO_ATTR_TAU); 00604 idmParams.insert(SUMO_ATTR_CF_IDM_DELTA); 00605 idmParams.insert(SUMO_ATTR_CF_IDM_STEPPING); 00606 allowedCFModelAttrs[SUMO_TAG_CF_IDM] = idmParams; 00607 00608 std::set<SumoXMLAttr> idmmParams; 00609 idmmParams.insert(SUMO_ATTR_ACCEL); 00610 idmmParams.insert(SUMO_ATTR_DECEL); 00611 idmmParams.insert(SUMO_ATTR_TAU); 00612 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_FACTOR); 00613 idmmParams.insert(SUMO_ATTR_CF_IDMM_ADAPT_TIME); 00614 idmmParams.insert(SUMO_ATTR_CF_IDM_STEPPING); 00615 allowedCFModelAttrs[SUMO_TAG_CF_IDMM] = idmmParams; 00616 00617 std::set<SumoXMLAttr> bkernerParams; 00618 bkernerParams.insert(SUMO_ATTR_ACCEL); 00619 bkernerParams.insert(SUMO_ATTR_DECEL); 00620 bkernerParams.insert(SUMO_ATTR_TAU); 00621 bkernerParams.insert(SUMO_ATTR_K); 00622 bkernerParams.insert(SUMO_ATTR_CF_KERNER_PHI); 00623 allowedCFModelAttrs[SUMO_TAG_CF_BKERNER] = bkernerParams; 00624 00625 std::set<SumoXMLAttr> wiedemannParams; 00626 wiedemannParams.insert(SUMO_ATTR_ACCEL); 00627 wiedemannParams.insert(SUMO_ATTR_DECEL); 00628 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_SECURITY); 00629 wiedemannParams.insert(SUMO_ATTR_CF_WIEDEMANN_ESTIMATION); 00630 allowedCFModelAttrs[SUMO_TAG_CF_WIEDEMANN] = wiedemannParams; 00631 } 00632 return allowedCFModelAttrs; 00633 } 00634 00635 00636 SUMOVehicleClass 00637 SUMOVehicleParserHelper::parseVehicleClass(const SUMOSAXAttributes& attrs, 00638 const std::string& id) { 00639 SUMOVehicleClass vclass = SVC_UNKNOWN; 00640 try { 00641 bool ok = true; 00642 std::string vclassS = attrs.hasAttribute(SUMO_ATTR_VCLASS) 00643 ? attrs.getOptStringReporting(SUMO_ATTR_VCLASS, id.c_str(), ok, "") 00644 : attrs.getOptStringReporting(SUMO_ATTR_VCLASS__DEPRECATED, id.c_str(), ok, ""); 00645 if (vclassS == "") { 00646 return vclass; 00647 } 00648 return getVehicleClassID(vclassS); 00649 } catch (...) { 00650 WRITE_ERROR("The class for " + attrs.getObjectType() + " '" + id + "' is not known."); 00651 } 00652 return vclass; 00653 } 00654 00655 00656 SUMOEmissionClass 00657 SUMOVehicleParserHelper::parseEmissionClass(const SUMOSAXAttributes& attrs, const std::string& id) { 00658 SUMOEmissionClass vclass = SVE_UNKNOWN; 00659 try { 00660 bool ok = true; 00661 std::string vclassS = attrs.getOptStringReporting(SUMO_ATTR_EMISSIONCLASS, id.c_str(), ok, ""); 00662 if (vclassS == "") { 00663 return vclass; 00664 } 00665 return getVehicleEmissionTypeID(vclassS); 00666 } catch (...) { 00667 WRITE_ERROR("The emission class for " + attrs.getObjectType() + " '" + id + "' is not known."); 00668 } 00669 return vclass; 00670 } 00671 00672 00673 SUMOVehicleShape 00674 SUMOVehicleParserHelper::parseGuiShape(const SUMOSAXAttributes& attrs, const std::string& id) { 00675 bool ok = true; 00676 std::string vclassS = attrs.getOptStringReporting(SUMO_ATTR_GUISHAPE, id.c_str(), ok, ""); 00677 if (SumoVehicleShapeStrings.hasString(vclassS)) { 00678 return SumoVehicleShapeStrings.get(vclassS); 00679 } else { 00680 WRITE_ERROR("The shape '" + vclassS + "' for " + attrs.getObjectType() + " '" + id + "' is not known."); 00681 return SVS_UNKNOWN; 00682 } 00683 } 00684 00685 00686 /****************************************************************************/ 00687