|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Loader for networks and route imports 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 <iostream> 00031 #include <string> 00032 #include <iomanip> 00033 #include <xercesc/parsers/SAXParser.hpp> 00034 #include <xercesc/util/PlatformUtils.hpp> 00035 #include <xercesc/util/TransService.hpp> 00036 #include <xercesc/sax2/SAX2XMLReader.hpp> 00037 #include <utils/options/OptionsCont.h> 00038 #include <utils/common/ToString.h> 00039 #include <utils/common/StringTokenizer.h> 00040 #include <utils/common/MsgHandler.h> 00041 #include <utils/common/UtilExceptions.h> 00042 #include <utils/common/FileHelpers.h> 00043 #include <utils/xml/XMLSubSys.h> 00044 #include <utils/xml/SAXWeightsHandler.h> 00045 #include "RONet.h" 00046 #include "RONetHandler.h" 00047 #include "ROLoader.h" 00048 #include "ROEdge.h" 00049 #include "RORDLoader_TripDefs.h" 00050 #include "RORDLoader_SUMOBase.h" 00051 #include "RORDGenerator_ODAmounts.h" 00052 #include "ROAbstractRouteDefLoader.h" 00053 00054 #ifdef CHECK_MEMORY_LEAKS 00055 #include <foreign/nvwa/debug_new.h> 00056 #endif // CHECK_MEMORY_LEAKS 00057 00058 00059 // =========================================================================== 00060 // method definitions 00061 // =========================================================================== 00062 // --------------------------------------------------------------------------- 00063 // ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods 00064 // --------------------------------------------------------------------------- 00065 void 00066 ROLoader::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id, 00067 SUMOReal val, SUMOReal beg, SUMOReal end) const throw() { 00068 ROEdge* e = myNet.getEdge(id); 00069 if (e!=0) { 00070 e->addTravelTime(val, beg, end); 00071 } else { 00072 if (id[0]!=':') { 00073 WRITE_ERROR("Trying to set a weight for the unknown edge '" + id + "'."); 00074 } 00075 } 00076 } 00077 00078 00079 // --------------------------------------------------------------------------- 00080 // ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight - methods 00081 // --------------------------------------------------------------------------- 00082 void 00083 ROLoader::EdgeFloatTimeLineRetriever_EdgeWeight::addEdgeWeight(const std::string& id, 00084 SUMOReal val, SUMOReal beg, SUMOReal end) const throw() { 00085 ROEdge* e = myNet.getEdge(id); 00086 if (e!=0) { 00087 e->addEffort(val, beg, end); 00088 } else { 00089 if (id[0]!=':') { 00090 WRITE_ERROR("Trying to set a weight for the unknown edge '" + id + "'."); 00091 } 00092 } 00093 } 00094 00095 00096 // --------------------------------------------------------------------------- 00097 // ROLoader - methods 00098 // --------------------------------------------------------------------------- 00099 ROLoader::ROLoader(OptionsCont& oc, bool emptyDestinationsAllowed) throw() 00100 : myOptions(oc), myEmptyDestinationsAllowed(emptyDestinationsAllowed) {} 00101 00102 00103 ROLoader::~ROLoader() { 00104 destroyHandlers(); 00105 } 00106 00107 00108 void 00109 ROLoader::loadNet(RONet& toFill, ROAbstractEdgeBuilder& eb) { 00110 std::string file = myOptions.getString("net-file"); 00111 if (file=="") { 00112 throw ProcessError("Missing definition of network to load!"); 00113 } 00114 if (!FileHelpers::exists(file)) { 00115 throw ProcessError("The network file '" + file + "' could not be found."); 00116 } 00117 PROGRESS_BEGIN_MESSAGE("Loading net"); 00118 RONetHandler handler(toFill, eb); 00119 handler.setFileName(file); 00120 if (!XMLSubSys::runParser(handler, file)) { 00121 PROGRESS_FAILED_MESSAGE(); 00122 throw ProcessError(); 00123 } else { 00124 PROGRESS_DONE_MESSAGE(); 00125 } 00126 if (myOptions.isSet("taz-files", false)) { // dfrouter does not register this option 00127 file = myOptions.getString("taz-files"); 00128 if (!FileHelpers::exists(file)) { 00129 throw ProcessError("The districts file '" + file + "' could not be found."); 00130 } 00131 PROGRESS_BEGIN_MESSAGE("Loading districts"); 00132 handler.setFileName(file); 00133 if (!XMLSubSys::runParser(handler, file)) { 00134 PROGRESS_FAILED_MESSAGE(); 00135 throw ProcessError(); 00136 } else { 00137 PROGRESS_DONE_MESSAGE(); 00138 } 00139 } 00140 } 00141 00142 00143 unsigned int 00144 ROLoader::openRoutes(RONet& net) { 00145 // build loader 00146 // load sumo-routes when wished 00147 bool ok = openTypedRoutes("route-files", net); 00148 // load the XML-trip definitions when wished 00149 ok &= openTypedRoutes("trip-files", net); 00150 // load the sumo-alternative file when wished 00151 ok &= openTypedRoutes("alternative-files", net); 00152 // load the amount definitions if wished 00153 ok &= openTypedRoutes("flow-files", net); 00154 // check 00155 if (ok&&myHandler.size()==0) { 00156 throw ProcessError("No route input specified."); 00157 } 00158 // skip routes prior to the begin time 00159 if (ok&&!myOptions.getBool("unsorted-input")) { 00160 WRITE_MESSAGE("Skipping..."); 00161 for (RouteLoaderCont::iterator i=myHandler.begin(); ok&&i!=myHandler.end(); i++) { 00162 ok &= (*i)->readRoutesAtLeastUntil(string2time(myOptions.getString("begin")), true); 00163 } 00164 WRITE_MESSAGE("Skipped until: " + time2string(getMinTimeStep())); 00165 } 00166 // check whether everything's ok 00167 if (!ok) { 00168 destroyHandlers(); 00169 throw ProcessError(); 00170 } 00171 return (unsigned int) myHandler.size(); 00172 } 00173 00174 00175 void 00176 ROLoader::processRoutesStepWise(SUMOTime start, SUMOTime end, 00177 RONet& net, SUMOAbstractRouter<ROEdge,ROVehicle> &router) { 00178 SUMOTime absNo = end - start; 00179 // skip routes that begin before the simulation's begin 00180 // loop till the end 00181 bool endReached = false; 00182 bool errorOccured = false; 00183 SUMOTime time = myHandler.size()!=0 ? getMinTimeStep() : start; 00184 SUMOTime firstStep = time; 00185 SUMOTime lastStep = time; 00186 for (; time<end&&!errorOccured&&!endReached; time+=DELTA_T) { 00187 writeStats(time, start, absNo); 00188 makeSingleStep(time, net, router); 00189 // check whether further data exist 00190 endReached = !net.furtherStored(); 00191 lastStep = time; 00192 for (RouteLoaderCont::iterator i=myHandler.begin(); endReached&&i!=myHandler.end(); i++) { 00193 if (!(*i)->ended()) { 00194 endReached = false; 00195 } 00196 } 00197 errorOccured = MsgHandler::getErrorInstance()->wasInformed() && !myOptions.getBool("ignore-errors"); 00198 } 00199 WRITE_MESSAGE("Routes found between time steps " + time2string(firstStep) + " and " + time2string(lastStep) + "."); 00200 } 00201 00202 00203 bool 00204 ROLoader::makeSingleStep(SUMOTime end, RONet& net, SUMOAbstractRouter<ROEdge,ROVehicle> &router) { 00205 RouteLoaderCont::iterator i; 00206 // go through all handlers 00207 if (myHandler.size()!= 0) { 00208 for (i=myHandler.begin(); i!=myHandler.end(); i++) { 00209 // load routes until the time point is reached 00210 if ((*i)->readRoutesAtLeastUntil(end, false)) { 00211 // save the routes 00212 net.saveAndRemoveRoutesUntil(myOptions, router, end); 00213 } else { 00214 return false; 00215 } 00216 } 00217 return MsgHandler::getErrorInstance()->wasInformed(); 00218 } else { 00219 return false; 00220 } 00221 } 00222 00223 00224 SUMOTime 00225 ROLoader::getMinTimeStep() const throw() { 00226 RouteLoaderCont::const_iterator i=myHandler.begin(); 00227 SUMOTime ret = (*i)->getLastReadTimeStep(); 00228 ++i; 00229 for (; i!=myHandler.end(); i++) { 00230 SUMOTime akt = (*i)->getLastReadTimeStep(); 00231 if (akt<ret) { 00232 ret = akt; 00233 } 00234 } 00235 return ret; 00236 } 00237 00238 00239 void 00240 ROLoader::processAllRoutes(SUMOTime start, SUMOTime end, 00241 RONet& net, SUMOAbstractRouter<ROEdge,ROVehicle> &router) { 00242 long absNo = end - start; 00243 bool ok = true; 00244 for (RouteLoaderCont::iterator i=myHandler.begin(); ok&&i!=myHandler.end(); i++) { 00245 ok &= (*i)->readRoutesAtLeastUntil(SUMOTime_MAX, false); 00246 } 00247 // save the routes 00248 SUMOTime time = start; 00249 for (; time<end;) { 00250 writeStats(time, start, absNo); 00251 time = net.saveAndRemoveRoutesUntil(myOptions, router, time); 00252 if (time<0) { 00253 time = end; 00254 } 00255 } 00256 } 00257 00258 00259 bool 00260 ROLoader::openTypedRoutes(const std::string& optionName, 00261 RONet& net) throw() { 00262 // check whether the current loader is known 00263 // (not all routers import all route formats) 00264 if (!myOptions.exists(optionName)) { 00265 return true; 00266 } 00267 // check whether the current loader is wished 00268 // and the file(s) can be used 00269 if (!myOptions.isUsableFileList(optionName)) { 00270 return !myOptions.isSet(optionName); 00271 } 00272 bool ok = true; 00273 std::vector<std::string> files = myOptions.getStringVector(optionName); 00274 for (std::vector<std::string>::const_iterator fileIt=files.begin(); fileIt!=files.end(); ++fileIt) { 00275 // build the instance when everything's all right 00276 try { 00277 ROAbstractRouteDefLoader* instance = buildNamedHandler(optionName, *fileIt, net); 00278 myHandler.push_back(instance); 00279 } catch (ProcessError& e) { 00280 std::string msg = "The loader for " + optionName + " from file '" + *fileIt + "' could not be initialised;"; 00281 std::string reason = e.what(); 00282 if (reason!="Process Error"&&reason!="") { 00283 msg = msg + "\n Reason: " + reason + "."; 00284 } else { 00285 msg = msg + "\n (unknown reason)."; 00286 } 00287 WRITE_ERROR(msg); 00288 ok = false; 00289 } 00290 } 00291 return ok; 00292 } 00293 00294 00295 ROAbstractRouteDefLoader* 00296 ROLoader::buildNamedHandler(const std::string& optionName, 00297 const std::string& file, 00298 RONet& net) throw(ProcessError) { 00299 if (optionName=="route-files" || optionName=="alternative-files") { 00300 const SUMOReal beta = myOptions.getBool("logit") 00301 ? myOptions.getFloat("logit.beta") 00302 : myOptions.getFloat("gawron.beta"); 00303 const SUMOReal gamma = myOptions.getBool("logit") 00304 ? myOptions.getFloat("logit.gamma") 00305 : -1; 00306 return new RORDLoader_SUMOBase(net, 00307 string2time(myOptions.getString("begin")), string2time(myOptions.getString("end")), 00308 beta, myOptions.getFloat("gawron.a"), gamma, 00309 myOptions.getInt("max-alternatives"), myOptions.getBool("repair"), 00310 myOptions.getBool("with-taz"), myOptions.getBool("keep-all-routes"), 00311 myOptions.getBool("skip-new-routes"), file); 00312 } 00313 if (optionName=="trip-files") { 00314 return new RORDLoader_TripDefs(net, 00315 string2time(myOptions.getString("begin")), string2time(myOptions.getString("end")), 00316 myEmptyDestinationsAllowed, myOptions.getBool("with-taz"), file); 00317 } 00318 if (optionName=="flow-files") { 00319 return new RORDGenerator_ODAmounts(net, 00320 string2time(myOptions.getString("begin")), string2time(myOptions.getString("end")), 00321 myEmptyDestinationsAllowed, myOptions.getBool("randomize-flows"), file); 00322 } 00323 return 0; 00324 } 00325 00326 00327 bool 00328 ROLoader::loadWeights(RONet& net, const std::string& optionName, 00329 const std::string& measure, bool useLanes) { 00330 // check whether the file exists 00331 if (!myOptions.isUsableFileList(optionName)) { 00332 return false; 00333 } 00334 // build and prepare the weights handler 00335 std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs; 00336 // travel time, first (always used) 00337 EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(net); 00338 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", !useLanes, ttRetriever)); 00339 // the measure to use, then 00340 EdgeFloatTimeLineRetriever_EdgeWeight eRetriever(net); 00341 if (measure!="traveltime") { 00342 std::string umeasure = measure; 00343 if (measure=="CO"||measure=="CO2"||measure=="HC"||measure=="PMx"||measure=="NOx"||measure=="fuel") { 00344 umeasure = measure + "_perVeh"; 00345 } 00346 retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(umeasure, !useLanes, eRetriever)); 00347 } 00348 // set up handler 00349 SAXWeightsHandler handler(retrieverDefs, ""); 00350 // go through files 00351 std::vector<std::string> files = myOptions.getStringVector(optionName); 00352 for (std::vector<std::string>::const_iterator fileIt=files.begin(); fileIt!=files.end(); ++fileIt) { 00353 PROGRESS_BEGIN_MESSAGE("Loading precomputed net weights from '" + *fileIt + "'"); 00354 if (XMLSubSys::runParser(handler, *fileIt)) { 00355 PROGRESS_DONE_MESSAGE(); 00356 } else { 00357 WRITE_MESSAGE("failed."); 00358 return false; 00359 } 00360 } 00361 // build edge-internal time lines 00362 const std::map<std::string, ROEdge*> &edges = net.getEdgeMap(); 00363 for (std::map<std::string, ROEdge*>::const_iterator i=edges.begin(); i!=edges.end(); ++i) { 00364 (*i).second->buildTimeLines(measure); 00365 } 00366 return true; 00367 } 00368 00369 00370 void 00371 ROLoader::writeStats(SUMOTime time, SUMOTime start, int absNo) throw() { 00372 if (myOptions.getBool("verbose")) { 00373 SUMOReal perc = (SUMOReal)(time-start) / (SUMOReal) absNo; 00374 std::cout.setf(std::ios::fixed, std::ios::floatfield); // use decimal format 00375 std::cout.setf(std::ios::showpoint); // print decimal point 00376 std::cout << std::setprecision(OUTPUT_ACCURACY); 00377 MsgHandler::getMessageInstance()->progressMsg("Reading time step: " + time2string(time) + " (" + time2string(time-start) + "/" + time2string(absNo) + " = " + toString(perc * 100) + "% done) "); 00378 } 00379 } 00380 00381 00382 void 00383 ROLoader::destroyHandlers() throw() { 00384 for (RouteLoaderCont::const_iterator i=myHandler.begin(); i!=myHandler.end(); ++i) { 00385 delete *i; 00386 } 00387 myHandler.clear(); 00388 } 00389 00390 00391 /****************************************************************************/ 00392