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