SUMO - Simulation of Urban MObility
|
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