SUMO - Simulation of Urban MObility

NLBuilder.cpp

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