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