|
SUMO - Simulation of Urban MObility
|
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