SUMO - Simulation of Urban MObility
NLBuilder.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // The main interface for loading a microsim
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 #include "NLBuilder.h"
00034 #include <microsim/MSNet.h>
00035 #include <microsim/MSEdgeControl.h>
00036 #include <microsim/MSGlobals.h>
00037 #include <iostream>
00038 #include <vector>
00039 #include <xercesc/parsers/SAXParser.hpp>
00040 #include <xercesc/sax2/SAX2XMLReader.hpp>
00041 #include <string>
00042 #include <map>
00043 #include "NLHandler.h"
00044 #include "NLEdgeControlBuilder.h"
00045 #include "NLJunctionControlBuilder.h"
00046 #include "NLDetectorBuilder.h"
00047 #include "NLTriggerBuilder.h"
00048 #include <microsim/MSVehicleControl.h>
00049 #include <microsim/MSVehicleTransfer.h>
00050 #include <microsim/MSRouteLoaderControl.h>
00051 #include <microsim/MSRouteLoader.h>
00052 #include <utils/common/MsgHandler.h>
00053 #include <utils/common/StringTokenizer.h>
00054 #include <utils/options/Option.h>
00055 #include <utils/options/OptionsCont.h>
00056 #include <utils/common/TplConvert.h>
00057 #include <utils/common/FileHelpers.h>
00058 #include <utils/common/SysUtils.h>
00059 #include <utils/common/ToString.h>
00060 #include <utils/xml/XMLSubSys.h>
00061 #include <microsim/output/MSDetectorControl.h>
00062 #include <microsim/MSFrame.h>
00063 #include <microsim/MSEdgeWeightsStorage.h>
00064 #include <utils/iodevices/BinaryInputDevice.h>
00065 
00066 #ifdef CHECK_MEMORY_LEAKS
00067 #include <foreign/nvwa/debug_new.h>
00068 #endif // CHECK_MEMORY_LEAKS
00069 
00070 
00071 // ===========================================================================
00072 // method definitions
00073 // ===========================================================================
00074 // ---------------------------------------------------------------------------
00075 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeWeight - methods
00076 // ---------------------------------------------------------------------------
00077 void
00078 NLBuilder::EdgeFloatTimeLineRetriever_EdgeEffort::addEdgeWeight(const std::string& id,
00079         SUMOReal value, SUMOReal begTime, SUMOReal endTime) const {
00080     MSEdge* edge = MSEdge::dictionary(id);
00081     if (edge != 0) {
00082         myNet.getWeightsStorage().addEffort(edge, begTime, endTime, value);
00083     } else {
00084         WRITE_ERROR("Trying to set the effort for the unknown edge '" + id + "'.");
00085     }
00086 }
00087 
00088 
00089 // ---------------------------------------------------------------------------
00090 // NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime - methods
00091 // ---------------------------------------------------------------------------
00092 void
00093 NLBuilder::EdgeFloatTimeLineRetriever_EdgeTravelTime::addEdgeWeight(const std::string& id,
00094         SUMOReal value, SUMOReal begTime, SUMOReal endTime) const {
00095     MSEdge* edge = MSEdge::dictionary(id);
00096     if (edge != 0) {
00097         myNet.getWeightsStorage().addTravelTime(edge, begTime, endTime, value);
00098     } else {
00099         WRITE_ERROR("Trying to set the travel time for the unknown edge '" + id + "'.");
00100     }
00101 }
00102 
00103 
00104 // ---------------------------------------------------------------------------
00105 // NLBuilder - methods
00106 // ---------------------------------------------------------------------------
00107 NLBuilder::NLBuilder(OptionsCont& oc,
00108                      MSNet& net,
00109                      NLEdgeControlBuilder& eb,
00110                      NLJunctionControlBuilder& jb,
00111                      NLDetectorBuilder& db,
00112                      NLHandler& xmlHandler)
00113     : myOptions(oc), myEdgeBuilder(eb), myJunctionBuilder(jb),
00114       myDetectorBuilder(db),
00115       myNet(net), myXMLHandler(xmlHandler) {}
00116 
00117 
00118 NLBuilder::~NLBuilder() {}
00119 
00120 
00121 bool
00122 NLBuilder::build() {
00123     // try to build the net
00124     if (!load("net-file")) {
00125         return false;
00126     }
00127     buildNet();
00128 #ifdef HAVE_MESOSIM
00129     // load the previous state if wished
00130     if (myOptions.isSet("load-state")) {
00131         long before = SysUtils::getCurrentMillis();
00132         BinaryInputDevice strm(myOptions.getString("load-state"));
00133         if (!strm.good()) {
00134             WRITE_ERROR("Could not read state from '" + myOptions.getString("load-state") + "'!");
00135         } else {
00136             PROGRESS_BEGIN_MESSAGE("Loading state from '" + myOptions.getString("load-state") + "'");
00137             unsigned int step = myNet.loadState(strm);
00138             if (myOptions.isDefault("begin")) {
00139                 myOptions.set("begin", time2string(step));
00140             }
00141             if (step != string2time(myOptions.getString("begin"))) {
00142                 WRITE_WARNING("State was written at a different time " + time2string(step) + " than the begin time " + myOptions.getString("begin") + "!");
00143             }
00144         }
00145         if (MsgHandler::getErrorInstance()->wasInformed()) {
00146             return false;
00147         }
00148         MsgHandler::getMessageInstance()->endProcessMsg("done (" + toString(SysUtils::getCurrentMillis() - before) + "ms).");
00149     }
00150 #endif
00151     // load weights if wished
00152     if (myOptions.isSet("weight-files")) {
00153         if (!myOptions.isUsableFileList("weight-files")) {
00154             return false;
00155         }
00156         // build and prepare the weights handler
00157         std::vector<SAXWeightsHandler::ToRetrieveDefinition*> retrieverDefs;
00158         //  travel time, first (always used)
00159         EdgeFloatTimeLineRetriever_EdgeTravelTime ttRetriever(myNet);
00160         retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition("traveltime", true, ttRetriever));
00161         //  the measure to use, then
00162         EdgeFloatTimeLineRetriever_EdgeEffort eRetriever(myNet);
00163         std::string measure = myOptions.getString("weight-attribute");
00164         if (measure != "traveltime") {
00165             if (measure == "CO" || measure == "CO2" || measure == "HC" || measure == "PMx" || measure == "NOx" || measure == "fuel") {
00166                 measure += "_perVeh";
00167             }
00168             retrieverDefs.push_back(new SAXWeightsHandler::ToRetrieveDefinition(measure, true, eRetriever));
00169         }
00170         //  set up handler
00171         SAXWeightsHandler handler(retrieverDefs, "");
00172         // start parsing; for each file in the list
00173         std::vector<std::string> files = myOptions.getStringVector("weight-files");
00174         for (std::vector<std::string>::iterator i = files.begin(); i != files.end(); ++i) {
00175             // report about loading when wished
00176             WRITE_MESSAGE("Loading weights from '" + *i + "'...");
00177             // parse the file
00178             if (!XMLSubSys::runParser(handler, *i)) {
00179                 return false;
00180             }
00181         }
00182     }
00183     // load routes
00184     if (myOptions.isSet("route-files") && string2time(myOptions.getString("route-steps")) <= 0) {
00185         if (!load("route-files")) {
00186             return false;
00187         }
00188     }
00189     // load additional net elements (sources, detectors, ...)
00190     if (myOptions.isSet("additional-files")) {
00191         if (!load("additional-files")) {
00192             return false;
00193         }
00194     }
00195     WRITE_MESSAGE("Loading done.");
00196     return true;
00197 }
00198 
00199 
00200 void
00201 NLBuilder::buildNet() {
00202     MSEdgeControl* edges = 0;
00203     MSJunctionControl* junctions = 0;
00204     MSRouteLoaderControl* routeLoaders = 0;
00205     MSTLLogicControl* tlc = 0;
00206     try {
00207         edges = myEdgeBuilder.build();
00208         junctions = myJunctionBuilder.build();
00209         routeLoaders = buildRouteLoaderControl(myOptions);
00210         tlc = myJunctionBuilder.buildTLLogics();
00211         MSFrame::buildStreams();
00212         std::vector<SUMOTime> stateDumpTimes;
00213         std::vector<std::string> stateDumpFiles;
00214 #ifdef HAVE_MESOSIM
00215         const std::vector<int> times = myOptions.getIntVector("save-state.times");
00216         for (std::vector<int>::const_iterator i = times.begin(); i != times.end(); ++i) {
00217             stateDumpTimes.push_back(TIME2STEPS(*i));
00218         }
00219         if (!myOptions.isDefault("save-state.prefix")) {
00220             const std::string prefix = myOptions.getString("save-state.prefix");
00221             for (std::vector<SUMOTime>::iterator i = stateDumpTimes.begin(); i != stateDumpTimes.end(); ++i) {
00222                 stateDumpFiles.push_back(prefix + "_" + time2string(*i) + ".bin");
00223             }
00224         } else {
00225             stateDumpFiles = StringTokenizer(myOptions.getString("save-state.files")).getVector() ;
00226         }
00227 #endif
00228         myNet.closeBuilding(edges, junctions, routeLoaders, tlc, stateDumpTimes, stateDumpFiles);
00229     } catch (IOError& e) {
00230         delete edges;
00231         delete junctions;
00232         delete routeLoaders;
00233         delete tlc;
00234         throw ProcessError(e.what());
00235     } catch (ProcessError&) {
00236         delete edges;
00237         delete junctions;
00238         delete routeLoaders;
00239         delete tlc;
00240         throw;
00241     }
00242 }
00243 
00244 
00245 bool
00246 NLBuilder::load(const std::string& mmlWhat) {
00247     if (!OptionsCont::getOptions().isUsableFileList(mmlWhat)) {
00248         return false;
00249     }
00250     std::vector<std::string> files = OptionsCont::getOptions().getStringVector(mmlWhat);
00251     for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
00252         PROGRESS_BEGIN_MESSAGE("Loading " + mmlWhat + " from '" + *fileIt + "'");
00253         long before = SysUtils::getCurrentMillis();
00254         if (!XMLSubSys::runParser(myXMLHandler, *fileIt)) {
00255             WRITE_MESSAGE("Loading of " + mmlWhat + " failed.");
00256             return false;
00257         }
00258         MsgHandler::getMessageInstance()->endProcessMsg(" done (" + toString(SysUtils::getCurrentMillis() - before) + "ms).");
00259     }
00260     return true;
00261 }
00262 
00263 
00264 MSRouteLoaderControl*
00265 NLBuilder::buildRouteLoaderControl(const OptionsCont& oc) {
00266     // build the loaders
00267     MSRouteLoaderControl::LoaderVector loaders;
00268     // check whether a list is existing
00269     if (oc.isSet("route-files") && string2time(oc.getString("route-steps")) > 0) {
00270         std::vector<std::string> files = oc.getStringVector("route-files");
00271         for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
00272             if (!FileHelpers::exists(*fileIt)) {
00273                 throw ProcessError("The route file '" + *fileIt + "' does not exist.");
00274             }
00275         }
00276         // open files for reading
00277         for (std::vector<std::string>::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
00278             loaders.push_back(new MSRouteLoader(myNet, new MSRouteHandler(*fileIt, false)));
00279         }
00280     }
00281     // build the route control
00282     return new MSRouteLoaderControl(myNet, string2time(oc.getString("route-steps")), loaders);
00283 }
00284 
00285 
00286 /****************************************************************************/
00287 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines