SUMO - Simulation of Urban MObility
RORDLoader_SUMOBase.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // The base class for SUMO-native route handlers
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include "RORDLoader_SUMOBase.h"
00034 #include <utils/common/SUMOVTypeParameter.h>
00035 #include "RORouteDef.h"
00036 #include "RONet.h"
00037 #include <utils/common/UtilExceptions.h>
00038 #include <utils/common/MsgHandler.h>
00039 #include <utils/common/StringTokenizer.h>
00040 #include <utils/common/ToString.h>
00041 #include "ROVehicle.h"
00042 #include "RORouteDef_Alternatives.h"
00043 #include "RORouteDef_Complete.h"
00044 #include "RORoute.h"
00045 #include <utils/xml/SUMOVehicleParserHelper.h>
00046 
00047 #ifdef CHECK_MEMORY_LEAKS
00048 #include <foreign/nvwa/debug_new.h>
00049 #endif // CHECK_MEMORY_LEAKS
00050 
00051 
00052 // ===========================================================================
00053 // method definitions
00054 // ===========================================================================
00055 RORDLoader_SUMOBase::RORDLoader_SUMOBase(RONet& net,
00056         SUMOTime begin, SUMOTime end, const int maxRouteNumber, const bool tryRepair,
00057         const bool withTaz, const bool keepRoutes,
00058         const bool skipRouteCalculation, const std::string& file)
00059     : ROTypedXMLRoutesLoader(net, begin, end, file),
00060       myVehicleParameter(0), myCurrentIsOk(true), myAltIsValid(true),
00061       myCurrentAlternatives(0), myMaxRouteNumber(maxRouteNumber),
00062       myCurrentRoute(0), myTryRepair(tryRepair), myWithTaz(withTaz), myKeepRoutes(keepRoutes),
00063       mySkipRouteCalculation(skipRouteCalculation), myColor(0), myCurrentVType(0),
00064       myHaveWarnedAboutDeprecatedVType(false), myHaveWarnedAboutDeprecatedRoute(false) {
00065 }
00066 
00067 
00068 RORDLoader_SUMOBase::~RORDLoader_SUMOBase() {
00069     // clean up (on failure)
00070     delete myCurrentAlternatives;
00071     delete myCurrentRoute;
00072     delete myVehicleParameter;
00073     delete myColor;
00074 }
00075 
00076 
00077 void
00078 RORDLoader_SUMOBase::myStartElement(int element,
00079                                     const SUMOSAXAttributes& attrs) {
00080     switch (element) {
00081         case SUMO_TAG_ROUTE:
00082             startRoute(attrs);
00083             break;
00084         case SUMO_TAG_VEHICLE:
00085             // try to parse the vehicle definition
00086             delete myVehicleParameter;
00087             myVehicleParameter = 0;
00088             myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs);
00089             if (myVehicleParameter != 0) {
00090                 myCurrentDepart = myVehicleParameter->depart;
00091             }
00092             myCurrentIsOk = myVehicleParameter != 0;
00093             break;
00094         case SUMO_TAG_VTYPE__DEPRECATED:
00095             if (!myHaveWarnedAboutDeprecatedVType) {
00096                 myHaveWarnedAboutDeprecatedVType = true;
00097                 WRITE_WARNING("'" + toString(SUMO_TAG_VTYPE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPE) + "'.");
00098             }
00099         case SUMO_TAG_VTYPE:
00100             myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs);
00101             break;
00102         case SUMO_TAG_ROUTE_DISTRIBUTION:
00103             myAltIsValid = true;
00104             startAlternative(attrs);
00105             if (!myCurrentIsOk) {
00106                 myAltIsValid = false;
00107             }
00108             break;
00109         default:
00110             break;
00111     }
00112     // parse embedded vtype information
00113     if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_VTYPE__DEPRECATED) {
00114         SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs);
00115         return;
00116     }
00117     if (!myCurrentIsOk) {
00118         throw ProcessError();
00119     }
00120 }
00121 
00122 
00123 void
00124 RORDLoader_SUMOBase::startRoute(const SUMOSAXAttributes& attrs) {
00125     delete myColor;
00126     myColor = 0;
00127     if (!myAltIsValid) {
00128         return;
00129     }
00130     if (myCurrentAlternatives == 0) {
00131         myCurrentIsOk = true;
00132         if (myVehicleParameter != 0) {
00133             if (attrs.hasAttribute(SUMO_ATTR_ID)) {
00134                 WRITE_ERROR("Internal routes do not have an id (vehicle '" + myVehicleParameter->id + "').");
00135                 myCurrentIsOk = false;
00136                 return;
00137             }
00138             myCurrentRouteName = "!" + myVehicleParameter->id;
00139         } else {
00140             myCurrentRouteName = attrs.getStringReporting(SUMO_ATTR_ID, 0, myCurrentIsOk);
00141         }
00142     } else {
00143         // parse route alternative...
00144         myCost = attrs.getOptSUMORealReporting(SUMO_ATTR_COST, myCurrentAlternatives->getID().c_str(), myCurrentIsOk, -1);
00145         myProbability = attrs.getSUMORealReporting(SUMO_ATTR_PROB, myCurrentAlternatives->getID().c_str(), myCurrentIsOk);
00146         if (myCurrentIsOk && myCost < 0 && myCost != -1) {
00147             WRITE_ERROR("Invalid cost in alternative for route '" + myCurrentAlternatives->getID() + "' (" + toString<SUMOReal>(myCost) + ").");
00148             myCurrentIsOk = false;
00149             return;
00150         }
00151         if (myCurrentIsOk && myProbability < 0) {
00152             WRITE_ERROR("Invalid probability in alternative for route '" + myCurrentAlternatives->getID() + "' (" + toString<SUMOReal>(myProbability) + ").");
00153             myCurrentIsOk = false;
00154             return;
00155         }
00156     }
00157     if (attrs.hasAttribute(SUMO_ATTR_COLOR)) {
00158         myColor = new RGBColor(RGBColor::parseColorReporting(
00159                                    attrs.getString(SUMO_ATTR_COLOR),
00160                                    attrs.getObjectType(), myCurrentRouteName.c_str(), true, myCurrentIsOk));
00161     }
00162     if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
00163         myCharacters(SUMO_TAG_ROUTE, attrs.getStringReporting(SUMO_ATTR_EDGES, myCurrentRouteName.c_str(), myCurrentIsOk));
00164     } else {
00165         if (!myHaveWarnedAboutDeprecatedRoute) {
00166             WRITE_WARNING("Defining routes as a nested string is deprecated, use the edges attribute instead.");
00167             myHaveWarnedAboutDeprecatedRoute = true;
00168         }
00169     }
00170 }
00171 
00172 
00173 void
00174 RORDLoader_SUMOBase::startAlternative(const SUMOSAXAttributes& attrs) {
00175     // try to get the id
00176     myCurrentIsOk = true;
00177     std::string id;
00178     if (myVehicleParameter != 0) {
00179         id = myVehicleParameter->id;
00180         if (id == "") {
00181             WRITE_ERROR("Missing 'id' of a routeDistribution.");
00182             myCurrentIsOk = false;
00183             return;
00184         }
00185         id = "!" + id;
00186     } else {
00187         id = attrs.getStringReporting(SUMO_ATTR_ID, 0, myCurrentIsOk);
00188         if (!myCurrentIsOk) {
00189             return;
00190         }
00191     }
00192     // try to get the index of the last element
00193     int index = attrs.getIntReporting(SUMO_ATTR_LAST, id.c_str(), myCurrentIsOk);
00194     if (myCurrentIsOk && index < 0) {
00195         WRITE_ERROR("Negative index of a route alternative (id='" + id + "').");
00196         myCurrentIsOk = false;
00197         return;
00198     }
00199     // build the alternative cont
00200     myCurrentAlternatives = new RORouteDef_Alternatives(id, index, 
00201         myMaxRouteNumber, myKeepRoutes, mySkipRouteCalculation);
00202 }
00203 
00204 void
00205 RORDLoader_SUMOBase::myCharacters(int element,
00206                                   const std::string& chars) {
00207     // process routes only, all other elements do
00208     //  not have embedded characters
00209     if (element != SUMO_TAG_ROUTE) {
00210         return;
00211     }
00212     if (!myAltIsValid) {
00213         return;
00214     }
00215     if (myCurrentRoute != 0) {
00216         return;
00217     }
00218     // check whether the costs and the probability are valid
00219     if (myCurrentAlternatives != 0 && !myCurrentIsOk) {
00220         return;
00221     }
00222     // build the list of edges
00223     std::vector<const ROEdge*> *list = new std::vector<const ROEdge*>();
00224     if (myWithTaz && myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
00225         ROEdge* edge = myNet.getEdge(myVehicleParameter->fromTaz + "-source");
00226         if (edge != 0) {
00227             list->push_back(edge);
00228         } else {
00229             WRITE_ERROR("The vehicle '" + myVehicleParameter->id + "' contains the unknown zone '" + myVehicleParameter->fromTaz + "'.");
00230             myCurrentIsOk = false;
00231         }
00232     }
00233     StringTokenizer st(chars);
00234     while (myCurrentIsOk && st.hasNext()) { // !!! too slow !!!
00235         const std::string id = st.next();
00236         ROEdge* edge = myNet.getEdge(id);
00237         if (edge != 0) {
00238             list->push_back(edge);
00239         } else {
00240             if (!myTryRepair) {
00241                 std::string rid = myCurrentAlternatives != 0 ? myCurrentAlternatives->getID() : myCurrentRouteName;
00242                 WRITE_ERROR("The route '" + rid + "' contains the unknown edge '" + id + "'.");
00243                 myCurrentIsOk = false;
00244             }
00245         }
00246     }
00247     if (myWithTaz && myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) {
00248         ROEdge* edge = myNet.getEdge(myVehicleParameter->toTaz + "-sink");
00249         if (edge != 0) {
00250             list->push_back(edge);
00251         } else {
00252             WRITE_ERROR("The vehicle '" + myVehicleParameter->id + "' contains the unknown zone '" + myVehicleParameter->toTaz + "'.");
00253             myCurrentIsOk = false;
00254         }
00255     }
00256     if (myCurrentIsOk) {
00257         if (myCurrentAlternatives != 0) {
00258             myCurrentAlternatives->addLoadedAlternative(
00259                 new RORoute(myCurrentAlternatives->getID(), myCost, myProbability, *list, myColor));
00260         } else {
00261             myCurrentRoute = new RORouteDef_Complete(myCurrentRouteName, myColor, *list, myTryRepair);
00262         }
00263         myColor = 0;
00264     }
00265     delete list;
00266 }
00267 
00268 
00269 void
00270 RORDLoader_SUMOBase::myEndElement(int element) {
00271     switch (element) {
00272         case SUMO_TAG_ROUTE:
00273             if (!myAltIsValid) {
00274                 return;
00275             }
00276             if (myCurrentRoute != 0 && myCurrentIsOk) {
00277                 if (myCurrentAlternatives == 0) {
00278                     myNet.addRouteDef(myCurrentRoute);
00279                     myCurrentRoute = 0;
00280                 }
00281                 if (myVehicleParameter == 0) {
00282                     myNextRouteRead = true;
00283                 }
00284                 myCurrentRoute = 0;
00285             }
00286             break;
00287         case SUMO_TAG_ROUTE_DISTRIBUTION:
00288             if (!myCurrentIsOk) {
00289                 return;
00290             }
00291             if (myVehicleParameter == 0) {
00292                 myNextRouteRead = true;
00293             }
00294             myNet.addRouteDef(myCurrentAlternatives);
00295             myCurrentRoute = 0;
00296             myCurrentAlternatives = 0;
00297             break;
00298         case SUMO_TAG_VEHICLE:
00299             closeVehicle();
00300             delete myVehicleParameter;
00301             myVehicleParameter = 0;
00302             myNextRouteRead = true;
00303             break;
00304         case SUMO_TAG_VTYPE__DEPRECATED:
00305         case SUMO_TAG_VTYPE: {
00306             SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType);
00307             myNet.addVehicleType(myCurrentVType);
00308             myCurrentVType = 0;
00309         }
00310         default:
00311             break;
00312     }
00313     if (!myCurrentIsOk) {
00314         throw ProcessError();
00315     }
00316 }
00317 
00318 
00319 bool
00320 RORDLoader_SUMOBase::closeVehicle() {
00321     // get the vehicle id
00322     if (myVehicleParameter->depart < myBegin || myVehicleParameter->depart >= myEnd) {
00323         myCurrentIsOk = false;
00324         return false;
00325     }
00326     // get vehicle type
00327     SUMOVTypeParameter* type = myNet.getVehicleTypeSecure(myVehicleParameter->vtypeid);
00328     // get the route
00329     RORouteDef* route = myNet.getRouteDef(myVehicleParameter->routeid);
00330     if (route == 0) {
00331         route = myNet.getRouteDef("!" + myVehicleParameter->id);
00332     }
00333     if (route == 0) {
00334         WRITE_ERROR("The route of the vehicle '" + myVehicleParameter->id + "' is not known.");
00335         myCurrentIsOk = false;
00336         return false;
00337     }
00338     // build the vehicle
00339     if (!MsgHandler::getErrorInstance()->wasInformed()) {
00340         ROVehicle* veh = new ROVehicle(*myVehicleParameter, route, type);
00341         myNet.addVehicle(myVehicleParameter->id, veh);
00342         return true;
00343     }
00344     return false;
00345 }
00346 
00347 
00348 
00349 /****************************************************************************/
00350 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines