|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // Importer for networks stored in MATSim format 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 #include <set> 00030 #include <functional> 00031 #include <sstream> 00032 #include <utils/xml/SUMOSAXHandler.h> 00033 #include <utils/common/MsgHandler.h> 00034 #include <netbuild/NBEdge.h> 00035 #include <netbuild/NBEdgeCont.h> 00036 #include <netbuild/NBNode.h> 00037 #include <netbuild/NBNodeCont.h> 00038 #include <netbuild/NBNetBuilder.h> 00039 #include <utils/geom/GeoConvHelper.h> 00040 #include <utils/options/OptionsCont.h> 00041 #include <utils/common/FileHelpers.h> 00042 #include <utils/common/StringTokenizer.h> 00043 #include <utils/common/TplConvert.h> 00044 #include <utils/xml/XMLSubSys.h> 00045 #include "NILoader.h" 00046 #include "NIImporter_MATSim.h" 00047 00048 #ifdef CHECK_MEMORY_LEAKS 00049 #include <foreign/nvwa/debug_new.h> 00050 #endif // CHECK_MEMORY_LEAKS 00051 00052 00053 00054 // =========================================================================== 00055 // static variables 00056 // =========================================================================== 00057 StringBijection<int>::Entry NIImporter_MATSim::matsimTags[] = { 00058 { "network", NIImporter_MATSim::MATSIM_TAG_NETWORK }, 00059 { "node", NIImporter_MATSim::MATSIM_TAG_NODE }, 00060 { "link", NIImporter_MATSim::MATSIM_TAG_LINK }, 00061 { "links", NIImporter_MATSim::MATSIM_TAG_LINKS }, 00062 { "", NIImporter_MATSim::MATSIM_TAG_NOTHING } 00063 }; 00064 00065 00066 StringBijection<int>::Entry NIImporter_MATSim::matsimAttrs[] = { 00067 { "id", NIImporter_MATSim::MATSIM_ATTR_ID }, 00068 { "x", NIImporter_MATSim::MATSIM_ATTR_X }, 00069 { "y", NIImporter_MATSim::MATSIM_ATTR_Y }, 00070 { "from", NIImporter_MATSim::MATSIM_ATTR_FROM }, 00071 { "to", NIImporter_MATSim::MATSIM_ATTR_TO }, 00072 { "length", NIImporter_MATSim::MATSIM_ATTR_LENGTH }, 00073 { "freespeed", NIImporter_MATSim::MATSIM_ATTR_FREESPEED }, 00074 { "capacity", NIImporter_MATSim::MATSIM_ATTR_CAPACITY }, 00075 { "permlanes", NIImporter_MATSim::MATSIM_ATTR_PERMLANES }, 00076 { "oneway", NIImporter_MATSim::MATSIM_ATTR_ONEWAY }, 00077 { "modes", NIImporter_MATSim::MATSIM_ATTR_MODES }, 00078 { "origid", NIImporter_MATSim::MATSIM_ATTR_ORIGID }, 00079 { "capperiod", NIImporter_MATSim::MATSIM_ATTR_CAPPERIOD }, 00080 { "capDivider", NIImporter_MATSim::MATSIM_ATTR_CAPDIVIDER }, 00081 00082 { "", NIImporter_MATSim::MATSIM_ATTR_NOTHING } 00083 }; 00084 00085 00086 // =========================================================================== 00087 // method definitions 00088 // =========================================================================== 00089 // --------------------------------------------------------------------------- 00090 // static methods 00091 // --------------------------------------------------------------------------- 00092 void 00093 NIImporter_MATSim::loadNetwork(const OptionsCont& oc, NBNetBuilder& nb) { 00094 // check whether the option is set (properly) 00095 if (!oc.isSet("matsim-files")) { 00096 return; 00097 } 00098 /* Parse file(s) 00099 * Each file is parsed twice: first for nodes, second for edges. */ 00100 std::vector<std::string> files = oc.getStringVector("matsim-files"); 00101 // load nodes, first 00102 NodesHandler nodesHandler(nb.getNodeCont()); 00103 for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { 00104 // nodes 00105 if (!FileHelpers::exists(*file)) { 00106 WRITE_ERROR("Could not open matsim-file '" + *file + "'."); 00107 return; 00108 } 00109 nodesHandler.setFileName(*file); 00110 PROGRESS_BEGIN_MESSAGE("Parsing nodes from matsim-file '" + *file + "'"); 00111 if (!XMLSubSys::runParser(nodesHandler, *file)) { 00112 return; 00113 } 00114 PROGRESS_DONE_MESSAGE(); 00115 } 00116 // load edges, then 00117 EdgesHandler edgesHandler(nb.getNodeCont(), nb.getEdgeCont(), oc.getBool("matsim.keep-length"), 00118 oc.getBool("matsim.lanes-from-capacity"), NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm"))); 00119 for (std::vector<std::string>::const_iterator file=files.begin(); file!=files.end(); ++file) { 00120 // edges 00121 edgesHandler.setFileName(*file); 00122 PROGRESS_BEGIN_MESSAGE("Parsing edges from matsim-file '" + *file + "'"); 00123 XMLSubSys::runParser(edgesHandler, *file); 00124 PROGRESS_DONE_MESSAGE(); 00125 } 00126 } 00127 00128 00129 // --------------------------------------------------------------------------- 00130 // definitions of NIImporter_MATSim::NodesHandler-methods 00131 // --------------------------------------------------------------------------- 00132 NIImporter_MATSim::NodesHandler::NodesHandler(NBNodeCont& toFill) throw() 00133 : GenericSAXHandler(matsimTags, MATSIM_TAG_NOTHING, 00134 matsimAttrs, MATSIM_ATTR_NOTHING, 00135 "matsim - file"), myNodeCont(toFill) { 00136 } 00137 00138 00139 NIImporter_MATSim::NodesHandler::~NodesHandler() throw() {} 00140 00141 00142 void 00143 NIImporter_MATSim::NodesHandler::myStartElement(int element, const SUMOSAXAttributes& attrs) throw(ProcessError) { 00144 if (element != MATSIM_TAG_NODE) { 00145 return; 00146 } 00147 // get the id, report a warning if not given or empty... 00148 bool ok = true; 00149 std::string id = attrs.getStringReporting(MATSIM_ATTR_ID, 0, ok); 00150 SUMOReal x = attrs.getSUMORealReporting(MATSIM_ATTR_X, id.c_str(), ok); 00151 SUMOReal y = attrs.getSUMORealReporting(MATSIM_ATTR_Y, id.c_str(), ok); 00152 if (!ok) { 00153 return; 00154 } 00155 Position pos(x, y); 00156 if (!NILoader::transformCoordinates(pos)) { 00157 WRITE_ERROR("Unable to project coordinates for node '" + id + "'."); 00158 } 00159 NBNode* node = new NBNode(id, pos); 00160 if (!myNodeCont.insert(node)) { 00161 delete node; 00162 WRITE_ERROR("Could not add node '" + id + "'. Probably declared twice."); 00163 } 00164 } 00165 00166 00167 00168 // --------------------------------------------------------------------------- 00169 // definitions of NIImporter_MATSim::EdgesHandler-methods 00170 // --------------------------------------------------------------------------- 00171 NIImporter_MATSim::EdgesHandler::EdgesHandler(const NBNodeCont& nc, NBEdgeCont& toFill, 00172 bool keepEdgeLengths, bool lanesFromCapacity, 00173 NBCapacity2Lanes capacity2Lanes) throw() 00174 : GenericSAXHandler(matsimTags, MATSIM_TAG_NOTHING, 00175 matsimAttrs, MATSIM_ATTR_NOTHING, "matsim - file"), 00176 myNodeCont(nc), myEdgeCont(toFill), myCapacityNorm(3600), 00177 myKeepEdgeLengths(keepEdgeLengths), myLanesFromCapacity(lanesFromCapacity), 00178 myCapacity2Lanes(capacity2Lanes) { 00179 } 00180 00181 00182 NIImporter_MATSim::EdgesHandler::~EdgesHandler() throw() { 00183 } 00184 00185 00186 void 00187 NIImporter_MATSim::EdgesHandler::myStartElement(int element, 00188 const SUMOSAXAttributes& attrs) throw(ProcessError) { 00189 bool ok = true; 00190 if (element==MATSIM_TAG_NETWORK) { 00191 if (attrs.hasAttribute(MATSIM_ATTR_CAPDIVIDER)) { 00192 int capDivider = attrs.getIntReporting(MATSIM_ATTR_CAPDIVIDER, "network", ok); 00193 if (ok) { 00194 myCapacityNorm = (SUMOReal)(capDivider*3600); 00195 } 00196 } 00197 } 00198 if (element==MATSIM_TAG_LINKS) { 00199 bool ok = true; 00200 std::string capperiod = attrs.getStringReporting(MATSIM_ATTR_CAPPERIOD, "links", ok); 00201 StringTokenizer st(capperiod, ":"); 00202 if (st.size()!=3) { 00203 WRITE_ERROR("Bogus capacity period format; requires 'hh:mm:ss'."); 00204 return; 00205 } 00206 try { 00207 int hours = TplConvert<char>::_2int(st.next().c_str()); 00208 int minutes = TplConvert<char>::_2int(st.next().c_str()); 00209 int seconds = TplConvert<char>::_2int(st.next().c_str()); 00210 myCapacityNorm = (SUMOReal)(hours*3600+minutes*60+seconds); 00211 } catch (NumberFormatException&) { 00212 } catch (EmptyData&) { 00213 } 00214 return; 00215 } 00216 00217 // parse "link" elements 00218 if (element!=MATSIM_TAG_LINK) { 00219 return; 00220 } 00221 std::string id = attrs.getStringReporting(MATSIM_ATTR_ID, 0, ok); 00222 std::string fromNodeID = attrs.getStringReporting(MATSIM_ATTR_FROM, id.c_str(), ok); 00223 std::string toNodeID = attrs.getStringReporting(MATSIM_ATTR_TO, id.c_str(), ok); 00224 SUMOReal length = attrs.getSUMORealReporting(MATSIM_ATTR_LENGTH, id.c_str(), ok); // override computed? 00225 SUMOReal freeSpeed = attrs.getSUMORealReporting(MATSIM_ATTR_FREESPEED, id.c_str(), ok); // 00226 SUMOReal capacity = attrs.getSUMORealReporting(MATSIM_ATTR_CAPACITY, id.c_str(), ok); // override permLanes? 00227 SUMOReal permLanes = attrs.getSUMORealReporting(MATSIM_ATTR_PERMLANES, id.c_str(), ok); 00228 //bool oneWay = attrs.getOptBoolReporting(MATSIM_ATTR_ONEWAY, id.c_str(), ok, true); // mandatory? 00229 std::string modes = attrs.getOptStringReporting(MATSIM_ATTR_MODES, id.c_str(), ok, ""); // which values? 00230 std::string origid = attrs.getOptStringReporting(MATSIM_ATTR_ORIGID, id.c_str(), ok, ""); 00231 NBNode* fromNode = myNodeCont.retrieve(fromNodeID); 00232 NBNode* toNode = myNodeCont.retrieve(toNodeID); 00233 if (fromNode==0) { 00234 WRITE_ERROR("Could not find from-node for edge '" + id + "'."); 00235 } 00236 if (toNode==0) { 00237 WRITE_ERROR("Could not find to-node for edge '" + id + "'."); 00238 } 00239 if (fromNode==0||toNode==0) { 00240 return; 00241 } 00242 if (myLanesFromCapacity) { 00243 permLanes = myCapacity2Lanes.get(capacity); 00244 } 00245 NBEdge* edge = new NBEdge(id, fromNode, toNode, "", freeSpeed, (unsigned int) permLanes, -1, -1, -1); 00246 if (myKeepEdgeLengths) { 00247 edge->setLoadedLength(length); 00248 } 00249 if (!myEdgeCont.insert(edge)) { 00250 delete edge; 00251 WRITE_ERROR("Could not add edge '" + id + "'. Probably declared twice."); 00252 } 00253 } 00254 00255 00256 /****************************************************************************/ 00257