SUMO - Simulation of Urban MObility
SUMOVehicleParserHelper.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines