SUMO - Simulation of Urban MObility

ROLoader.cpp

Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines