SUMO - Simulation of Urban MObility

SUMOVehicleParserHelper.cpp

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