Eclipse SUMO - Simulation of Urban MObility
NIImporter_MATSim.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Importer for networks stored in MATSim format
21 /****************************************************************************/
22 #include <config.h>
23 #include <set>
24 #include <functional>
25 #include <sstream>
27 #include <utils/common/ToString.h>
29 #include <netbuild/NBEdge.h>
30 #include <netbuild/NBEdgeCont.h>
31 #include <netbuild/NBNode.h>
32 #include <netbuild/NBNodeCont.h>
33 #include <netbuild/NBNetBuilder.h>
39 #include <utils/xml/XMLSubSys.h>
40 #include "NILoader.h"
41 #include "NIImporter_MATSim.h"
42 
43 
44 
45 // ===========================================================================
46 // static variables
47 // ===========================================================================
54 };
55 
56 
72 
74 };
75 
76 
77 // ===========================================================================
78 // method definitions
79 // ===========================================================================
80 // ---------------------------------------------------------------------------
81 // static methods
82 // ---------------------------------------------------------------------------
83 void
85  // check whether the option is set (properly)
86  if (!oc.isSet("matsim-files")) {
87  return;
88  }
89  /* Parse file(s)
90  * Each file is parsed twice: first for nodes, second for edges. */
91  std::vector<std::string> files = oc.getStringVector("matsim-files");
92  // load nodes, first
93  NodesHandler nodesHandler(nb.getNodeCont());
94  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
95  // nodes
96  if (!FileHelpers::isReadable(*file)) {
97  WRITE_ERROR("Could not open matsim-file '" + *file + "'.");
98  return;
99  }
100  nodesHandler.setFileName(*file);
101  PROGRESS_BEGIN_MESSAGE("Parsing nodes from matsim-file '" + *file + "'");
102  if (!XMLSubSys::runParser(nodesHandler, *file)) {
103  return;
104  }
106  }
107  // load edges, then
108  EdgesHandler edgesHandler(nb.getNodeCont(), nb.getEdgeCont(), oc.getBool("matsim.keep-length"),
109  oc.getBool("matsim.lanes-from-capacity"), NBCapacity2Lanes(oc.getFloat("lanes-from-capacity.norm")));
110  for (std::vector<std::string>::const_iterator file = files.begin(); file != files.end(); ++file) {
111  // edges
112  edgesHandler.setFileName(*file);
113  PROGRESS_BEGIN_MESSAGE("Parsing edges from matsim-file '" + *file + "'");
114  XMLSubSys::runParser(edgesHandler, *file);
116  }
117 }
118 
119 
120 // ---------------------------------------------------------------------------
121 // definitions of NIImporter_MATSim::NodesHandler-methods
122 // ---------------------------------------------------------------------------
124  : GenericSAXHandler(matsimTags, MATSIM_TAG_NOTHING,
125  matsimAttrs, MATSIM_ATTR_NOTHING,
126  "matsim - file"), myNodeCont(toFill) {
127 }
128 
129 
131 
132 
133 void
135  if (element != MATSIM_TAG_NODE) {
136  return;
137  }
138  // get the id, report a warning if not given or empty...
139  bool ok = true;
140  std::string id = attrs.get<std::string>(MATSIM_ATTR_ID, nullptr, ok);
141  double x = attrs.get<double>(MATSIM_ATTR_X, id.c_str(), ok);
142  double y = attrs.get<double>(MATSIM_ATTR_Y, id.c_str(), ok);
143  if (!ok) {
144  return;
145  }
146  Position pos(x, y);
148  WRITE_ERROR("Unable to project coordinates for node '" + id + "'.");
149  }
150  NBNode* node = new NBNode(id, pos);
151  if (!myNodeCont.insert(node)) {
152  delete node;
153  WRITE_ERROR("Could not add node '" + id + "'. Probably declared twice.");
154  }
155 }
156 
157 
158 
159 // ---------------------------------------------------------------------------
160 // definitions of NIImporter_MATSim::EdgesHandler-methods
161 // ---------------------------------------------------------------------------
163  bool keepEdgeLengths, bool lanesFromCapacity,
164  NBCapacity2Lanes capacity2Lanes)
166  matsimAttrs, MATSIM_ATTR_NOTHING, "matsim - file"),
167  myNodeCont(nc), myEdgeCont(toFill), myCapacityNorm(3600),
168  myKeepEdgeLengths(keepEdgeLengths), myLanesFromCapacity(lanesFromCapacity),
169  myCapacity2Lanes(capacity2Lanes) {
170 }
171 
172 
174 }
175 
176 
177 void
178 NIImporter_MATSim::EdgesHandler::insertEdge(const std::string& id, NBNode* fromNode, NBNode* toNode, double freeSpeed, int numLanes, double capacity, double length) {
179  NBEdge* edge = new NBEdge(id, fromNode, toNode, "", freeSpeed, numLanes, -1, NBEdge::UNSPECIFIED_WIDTH, NBEdge::UNSPECIFIED_OFFSET, LaneSpreadFunction::RIGHT);
180  edge->setParameter("capacity", toString(capacity));
181  if (myKeepEdgeLengths) {
182  edge->setLoadedLength(length);
183  }
184  if (!myEdgeCont.insert(edge)) {
185  delete edge;
186  WRITE_ERROR("Could not add edge '" + id + "'. Probably declared twice.");
187  }
188 }
189 
190 
191 void
193  const SUMOSAXAttributes& attrs) {
194  if (element == MATSIM_TAG_NETWORK) {
196  bool ok = true;
197  int capDivider = attrs.get<int>(MATSIM_ATTR_CAPDIVIDER, "network", ok);
198  if (ok) {
199  myCapacityNorm = (double)(capDivider * 3600);
200  }
201  }
202  }
203  if (element == MATSIM_TAG_LINKS) {
204  bool ok = true;
205  std::string capperiod = attrs.get<std::string>(MATSIM_ATTR_CAPPERIOD, "links", ok);
206  StringTokenizer st(capperiod, ":");
207  if (st.size() != 3) {
208  WRITE_ERROR("Bogus capacity period format; requires 'hh:mm:ss'.");
209  return;
210  }
211  try {
212  int hours = StringUtils::toInt(st.next());
213  int minutes = StringUtils::toInt(st.next());
214  int seconds = StringUtils::toInt(st.next());
215  myCapacityNorm = (double)(hours * 3600 + minutes * 60 + seconds);
216  } catch (NumberFormatException&) {
217  } catch (EmptyData&) {
218  }
219  return;
220  }
221 
222  // parse "link" elements
223  if (element != MATSIM_TAG_LINK) {
224  return;
225  }
226  bool ok = true;
227  std::string id = attrs.get<std::string>(MATSIM_ATTR_ID, nullptr, ok);
228  std::string fromNodeID = attrs.get<std::string>(MATSIM_ATTR_FROM, id.c_str(), ok);
229  std::string toNodeID = attrs.get<std::string>(MATSIM_ATTR_TO, id.c_str(), ok);
230  double length = attrs.get<double>(MATSIM_ATTR_LENGTH, id.c_str(), ok); // override computed?
231  double freeSpeed = attrs.get<double>(MATSIM_ATTR_FREESPEED, id.c_str(), ok); //
232  double capacity = attrs.get<double>(MATSIM_ATTR_CAPACITY, id.c_str(), ok); // override permLanes?
233  double permLanes = attrs.get<double>(MATSIM_ATTR_PERMLANES, id.c_str(), ok);
234  //bool oneWay = attrs.getOpt<bool>(MATSIM_ATTR_ONEWAY, id.c_str(), ok, true); // mandatory?
235  std::string modes = attrs.getOpt<std::string>(MATSIM_ATTR_MODES, id.c_str(), ok, ""); // which values?
236  std::string origid = attrs.getOpt<std::string>(MATSIM_ATTR_ORIGID, id.c_str(), ok, "");
237  NBNode* fromNode = myNodeCont.retrieve(fromNodeID);
238  NBNode* toNode = myNodeCont.retrieve(toNodeID);
239  if (fromNode == nullptr) {
240  WRITE_ERROR("Could not find from-node for edge '" + id + "'.");
241  }
242  if (toNode == nullptr) {
243  WRITE_ERROR("Could not find to-node for edge '" + id + "'.");
244  }
245  if (fromNode == nullptr || toNode == nullptr) {
246  return;
247  }
248  if (myLanesFromCapacity) {
249  permLanes = myCapacity2Lanes.get(capacity);
250  }
251  if (fromNode == toNode) {
252  // adding node and edge with a different naming scheme to keep the original edge id for easier route repair
253  NBNode* intermediate = new NBNode(id + ".0", toNode->getPosition() + Position(POSITION_EPS, POSITION_EPS));
254  if (myNodeCont.insert(intermediate)) {
255  insertEdge(id + ".0", intermediate, toNode, freeSpeed, (int)(permLanes + 0.5), capacity, length);
256  toNode = intermediate;
257  } else {
258  delete intermediate;
259  WRITE_ERROR("Could not add intermediate node to split loop edge '" + id + "'.");
260  }
261  }
262  insertEdge(id, fromNode, toNode, freeSpeed, (int)(permLanes + 0.5), capacity, length);
263 }
264 
265 
266 /****************************************************************************/
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:288
#define PROGRESS_DONE_MESSAGE()
Definition: MsgHandler.h:284
#define PROGRESS_BEGIN_MESSAGE(msg)
Definition: MsgHandler.h:283
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
static bool isReadable(std::string path)
Checks whether the given file is readable.
Definition: FileHelpers.cpp:49
A handler which converts occuring elements and attributes into enums.
void setFileName(const std::string &name)
Sets the current file name.
A helper class which computes the lane number from given capacity.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:59
The representation of a single edge during network building.
Definition: NBEdge.h:91
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:349
static const double UNSPECIFIED_OFFSET
unspecified lane offset
Definition: NBEdge.h:352
void setLoadedLength(double val)
set loaded length
Definition: NBEdge.cpp:4037
Instance responsible for building networks.
Definition: NBNetBuilder.h:107
static bool transformCoordinate(Position &from, bool includeInBoundary=true, GeoConvHelper *from_srs=0)
transforms loaded coordinates handles projections, offsets (using GeoConvHelper) and import of height...
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:148
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:153
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:58
Represents a single node (junction) during network building.
Definition: NBNode.h:66
const Position & getPosition() const
Definition: NBNode.h:248
A class which extracts MATSIM-edges from a parsed MATSIM-file.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
EdgesHandler(NBNodeCont &nc, NBEdgeCont &toFill, bool keepEdgeLengths, bool lanesFromCapacity, NBCapacity2Lanes capacity2Lanes)
Constructor.
void insertEdge(const std::string &id, NBNode *fromNode, NBNode *toNode, double freeSpeed, int numLanes, double capacity, double length)
A class which extracts MATSIM-nodes from a parsed MATSIM-file.
NodesHandler(NBNodeCont &toFill)
Contructor.
void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
static StringBijection< int >::Entry matsimAttrs[]
The names of MATSIM-XML attributes (for passing to GenericSAXHandler)
static void loadNetwork(const OptionsCont &oc, NBNetBuilder &nb)
Loads content of the optionally given MATSIM network files.
static StringBijection< int >::Entry matsimTags[]
The names of MATSIM-XML elements (for passing to GenericSAXHandler)
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const StringVector & getStringVector(const std::string &name) const
Returns the list of string-value of the named option (only for Option_StringVector)
virtual void setParameter(const std::string &key, const std::string &value)
Sets a parameter.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
Encapsulated SAX-Attributes.
T getOpt(int attr, const char *objectid, bool &ok, T defaultValue, bool report=true) const
Tries to read given attribute assuming it is an int.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool runParser(GenericSAXHandler &handler, const std::string &file, const bool isNet=false, const bool isRoute=false)
Runs the given handler on the given file; returns if everything's ok.
Definition: XMLSubSys.cpp:149