|
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, 00057 const SUMOReal beta, const SUMOReal gawronA, const SUMOReal logitGamma, 00058 const int maxRouteNumber, const bool tryRepair, const bool withTaz, const bool keepRoutes, 00059 const bool skipRouteCalculation, const std::string& file) 00060 : ROTypedXMLRoutesLoader(net, begin, end, file), 00061 myVehicleParameter(0), myCurrentIsOk(true), myAltIsValid(true), myHaveNextRoute(false), 00062 myCurrentAlternatives(0), 00063 myBeta(beta), myGawronA(gawronA), myLogitGamma(logitGamma), myMaxRouteNumber(maxRouteNumber), 00064 myCurrentRoute(0), myCurrentDepart(-1), myTryRepair(tryRepair), myWithTaz(withTaz), myKeepRoutes(keepRoutes), 00065 mySkipRouteCalculation(skipRouteCalculation), myColor(0), myCurrentVType(0), 00066 myHaveWarnedAboutDeprecatedVType(false), myHaveWarnedAboutDeprecatedRoute(false) { 00067 } 00068 00069 00070 RORDLoader_SUMOBase::~RORDLoader_SUMOBase() { 00071 // clean up (on failure) 00072 delete myCurrentAlternatives; 00073 delete myCurrentRoute; 00074 delete myVehicleParameter; 00075 delete myColor; 00076 } 00077 00078 00079 void 00080 RORDLoader_SUMOBase::myStartElement(int element, 00081 const SUMOSAXAttributes& attrs) { 00082 switch (element) { 00083 case SUMO_TAG_ROUTE: 00084 startRoute(attrs); 00085 break; 00086 case SUMO_TAG_VEHICLE: 00087 // try to parse the vehicle definition 00088 delete myVehicleParameter; 00089 myVehicleParameter = 0; 00090 myVehicleParameter = SUMOVehicleParserHelper::parseVehicleAttributes(attrs); 00091 if (myVehicleParameter != 0) { 00092 myCurrentDepart = myVehicleParameter->depart; 00093 } 00094 myCurrentIsOk = myVehicleParameter != 0; 00095 break; 00096 case SUMO_TAG_VTYPE__DEPRECATED: 00097 if (!myHaveWarnedAboutDeprecatedVType) { 00098 myHaveWarnedAboutDeprecatedVType = true; 00099 WRITE_WARNING("'" + toString(SUMO_TAG_VTYPE__DEPRECATED) + "' is deprecated; please use '" + toString(SUMO_TAG_VTYPE) + "'."); 00100 } 00101 case SUMO_TAG_VTYPE: 00102 myCurrentVType = SUMOVehicleParserHelper::beginVTypeParsing(attrs); 00103 break; 00104 case SUMO_TAG_ROUTE_DISTRIBUTION: 00105 myAltIsValid = true; 00106 startAlternative(attrs); 00107 if (!myCurrentIsOk) { 00108 myAltIsValid = false; 00109 } 00110 break; 00111 default: 00112 break; 00113 } 00114 // parse embedded vtype information 00115 if (myCurrentVType != 0 && element != SUMO_TAG_VTYPE && element != SUMO_TAG_VTYPE__DEPRECATED) { 00116 SUMOVehicleParserHelper::parseVTypeEmbedded(*myCurrentVType, element, attrs); 00117 return; 00118 } 00119 if (!myCurrentIsOk) { 00120 throw ProcessError(); 00121 } 00122 } 00123 00124 00125 void 00126 RORDLoader_SUMOBase::startRoute(const SUMOSAXAttributes& attrs) { 00127 delete myColor; 00128 myColor = 0; 00129 if (!myAltIsValid) { 00130 return; 00131 } 00132 if (myCurrentAlternatives == 0) { 00133 myCurrentIsOk = true; 00134 if (myVehicleParameter != 0) { 00135 if (attrs.hasAttribute(SUMO_ATTR_ID)) { 00136 WRITE_ERROR("Internal routes do not have an id (vehicle '" + myVehicleParameter->id + "')."); 00137 myCurrentIsOk = false; 00138 return; 00139 } 00140 myCurrentRouteName = "!" + myVehicleParameter->id; 00141 } else { 00142 myCurrentRouteName = attrs.getStringReporting(SUMO_ATTR_ID, 0, myCurrentIsOk); 00143 } 00144 } else { 00145 // parse route alternative... 00146 myCost = attrs.getOptSUMORealReporting(SUMO_ATTR_COST, myCurrentAlternatives->getID().c_str(), myCurrentIsOk, -1); 00147 myProbability = attrs.getSUMORealReporting(SUMO_ATTR_PROB, myCurrentAlternatives->getID().c_str(), myCurrentIsOk); 00148 if (myCurrentIsOk && myCost < 0 && myCost != -1) { 00149 WRITE_ERROR("Invalid cost in alternative for route '" + myCurrentAlternatives->getID() + "' (" + toString<SUMOReal>(myCost) + ")."); 00150 myCurrentIsOk = false; 00151 return; 00152 } 00153 if (myCurrentIsOk && myProbability < 0) { 00154 WRITE_ERROR("Invalid probability in alternative for route '" + myCurrentAlternatives->getID() + "' (" + toString<SUMOReal>(myProbability) + ")."); 00155 myCurrentIsOk = false; 00156 return; 00157 } 00158 } 00159 if (attrs.hasAttribute(SUMO_ATTR_COLOR)) { 00160 myColor = new RGBColor(RGBColor::parseColorReporting( 00161 attrs.getString(SUMO_ATTR_COLOR), 00162 attrs.getObjectType(), myCurrentRouteName.c_str(), true, myCurrentIsOk)); 00163 } 00164 if (attrs.hasAttribute(SUMO_ATTR_EDGES)) { 00165 myCharacters(SUMO_TAG_ROUTE, attrs.getStringReporting(SUMO_ATTR_EDGES, myCurrentRouteName.c_str(), myCurrentIsOk)); 00166 } else { 00167 if (!myHaveWarnedAboutDeprecatedRoute) { 00168 WRITE_WARNING("Defining routes as a nested string is deprecated, use the edges attribute instead."); 00169 myHaveWarnedAboutDeprecatedRoute = true; 00170 } 00171 } 00172 } 00173 00174 00175 void 00176 RORDLoader_SUMOBase::startAlternative(const SUMOSAXAttributes& attrs) { 00177 // try to get the id 00178 myCurrentIsOk = true; 00179 std::string id; 00180 if (myVehicleParameter != 0) { 00181 id = myVehicleParameter->id; 00182 if (id == "") { 00183 WRITE_ERROR("Missing 'id' of a routeDistribution."); 00184 myCurrentIsOk = false; 00185 return; 00186 } 00187 id = "!" + id; 00188 } else { 00189 id = attrs.getStringReporting(SUMO_ATTR_ID, 0, myCurrentIsOk); 00190 if (!myCurrentIsOk) { 00191 return; 00192 } 00193 } 00194 // try to get the index of the last element 00195 int index = attrs.getIntReporting(SUMO_ATTR_LAST, id.c_str(), myCurrentIsOk); 00196 if (myCurrentIsOk && index < 0) { 00197 WRITE_ERROR("Negative index of a route alternative (id='" + id + "')."); 00198 myCurrentIsOk = false; 00199 return; 00200 } 00201 // build the alternative cont 00202 myCurrentAlternatives = new RORouteDef_Alternatives(id, index, myBeta, myGawronA, myLogitGamma, 00203 myMaxRouteNumber, myKeepRoutes, mySkipRouteCalculation); 00204 } 00205 00206 void 00207 RORDLoader_SUMOBase::myCharacters(int element, 00208 const std::string& chars) { 00209 // process routes only, all other elements do 00210 // not have embedded characters 00211 if (element != SUMO_TAG_ROUTE) { 00212 return; 00213 } 00214 if (!myAltIsValid) { 00215 return; 00216 } 00217 if (myCurrentRoute != 0) { 00218 return; 00219 } 00220 // check whether the costs and the probability are valid 00221 if (myCurrentAlternatives != 0 && !myCurrentIsOk) { 00222 return; 00223 } 00224 // build the list of edges 00225 std::vector<const ROEdge*> *list = new std::vector<const ROEdge*>(); 00226 if (myWithTaz && myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) { 00227 ROEdge* edge = myNet.getEdge(myVehicleParameter->fromTaz + "-source"); 00228 if (edge != 0) { 00229 list->push_back(edge); 00230 } else { 00231 WRITE_ERROR("The vehicle '" + myVehicleParameter->id + "' contains the unknown zone '" + myVehicleParameter->fromTaz + "'."); 00232 myCurrentIsOk = false; 00233 } 00234 } 00235 StringTokenizer st(chars); 00236 while (myCurrentIsOk && st.hasNext()) { // !!! too slow !!! 00237 const std::string id = st.next(); 00238 ROEdge* edge = myNet.getEdge(id); 00239 if (edge != 0) { 00240 list->push_back(edge); 00241 } else { 00242 if (!myTryRepair) { 00243 std::string rid = myCurrentAlternatives != 0 ? myCurrentAlternatives->getID() : myCurrentRouteName; 00244 WRITE_ERROR("The route '" + rid + "' contains the unknown edge '" + id + "'."); 00245 myCurrentIsOk = false; 00246 } 00247 } 00248 } 00249 if (myWithTaz && myVehicleParameter->wasSet(VEHPARS_TAZ_SET)) { 00250 ROEdge* edge = myNet.getEdge(myVehicleParameter->toTaz + "-sink"); 00251 if (edge != 0) { 00252 list->push_back(edge); 00253 } else { 00254 WRITE_ERROR("The vehicle '" + myVehicleParameter->id + "' contains the unknown zone '" + myVehicleParameter->toTaz + "'."); 00255 myCurrentIsOk = false; 00256 } 00257 } 00258 if (myCurrentIsOk) { 00259 if (myCurrentAlternatives != 0) { 00260 myCurrentAlternatives->addLoadedAlternative( 00261 new RORoute(myCurrentAlternatives->getID(), myCost, myProbability, *list, myColor)); 00262 } else { 00263 myCurrentRoute = new RORouteDef_Complete(myCurrentRouteName, myColor, *list, myTryRepair); 00264 } 00265 myColor = 0; 00266 } 00267 delete list; 00268 } 00269 00270 00271 void 00272 RORDLoader_SUMOBase::myEndElement(int element) { 00273 switch (element) { 00274 case SUMO_TAG_ROUTE: 00275 if (!myAltIsValid) { 00276 return; 00277 } 00278 if (myCurrentRoute != 0 && myCurrentIsOk) { 00279 if (myCurrentAlternatives == 0) { 00280 myNet.addRouteDef(myCurrentRoute); 00281 myCurrentRoute = 0; 00282 } 00283 if (myVehicleParameter == 0) { 00284 myHaveNextRoute = true; 00285 } 00286 myCurrentRoute = 0; 00287 } 00288 break; 00289 case SUMO_TAG_ROUTE_DISTRIBUTION: 00290 if (!myCurrentIsOk) { 00291 return; 00292 } 00293 if (myVehicleParameter == 0) { 00294 myHaveNextRoute = true; 00295 } 00296 myNet.addRouteDef(myCurrentAlternatives); 00297 myCurrentRoute = 0; 00298 myCurrentAlternatives = 0; 00299 break; 00300 case SUMO_TAG_VEHICLE: 00301 closeVehicle(); 00302 delete myVehicleParameter; 00303 myVehicleParameter = 0; 00304 myHaveNextRoute = true; 00305 break; 00306 case SUMO_TAG_VTYPE__DEPRECATED: 00307 case SUMO_TAG_VTYPE: { 00308 SUMOVehicleParserHelper::closeVTypeParsing(*myCurrentVType); 00309 myNet.addVehicleType(myCurrentVType); 00310 myCurrentVType = 0; 00311 } 00312 default: 00313 break; 00314 } 00315 if (!myCurrentIsOk) { 00316 throw ProcessError(); 00317 } 00318 } 00319 00320 00321 bool 00322 RORDLoader_SUMOBase::closeVehicle() { 00323 // get the vehicle id 00324 if (myVehicleParameter->depart < myBegin || myVehicleParameter->depart >= myEnd) { 00325 myCurrentIsOk = false; 00326 return false; 00327 } 00328 // get vehicle type 00329 SUMOVTypeParameter* type = myNet.getVehicleTypeSecure(myVehicleParameter->vtypeid); 00330 // get the route 00331 RORouteDef* route = myNet.getRouteDef(myVehicleParameter->routeid); 00332 if (route == 0) { 00333 route = myNet.getRouteDef("!" + myVehicleParameter->id); 00334 } 00335 if (route == 0) { 00336 WRITE_ERROR("The route of the vehicle '" + myVehicleParameter->id + "' is not known."); 00337 myCurrentIsOk = false; 00338 return false; 00339 } 00340 // build the vehicle 00341 if (!MsgHandler::getErrorInstance()->wasInformed()) { 00342 ROVehicle* veh = new ROVehicle(*myVehicleParameter, route, type); 00343 myNet.addVehicle(myVehicleParameter->id, veh); 00344 return true; 00345 } 00346 return false; 00347 } 00348 00349 00350 void 00351 RORDLoader_SUMOBase::beginNextRoute() { 00352 myHaveNextRoute = false; 00353 } 00354 00355 00356 00357 /****************************************************************************/ 00358