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