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