SUMO - Simulation of Urban MObility
RONetHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
11 // The handler for SUMO-Networks
12 /****************************************************************************/
13 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
14 // Copyright (C) 2002-2017 DLR (http://www.dlr.de/) and contributors
15 /****************************************************************************/
16 //
17 // This file is part of SUMO.
18 // SUMO is free software: you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation, either version 3 of the License, or
21 // (at your option) any later version.
22 //
23 /****************************************************************************/
24 
25 
26 // ===========================================================================
27 // included modules
28 // ===========================================================================
29 #ifdef _MSC_VER
30 #include <windows_config.h>
31 #else
32 #include <config.h>
33 #endif
34 
35 #include <string>
40 #include <utils/common/ToString.h>
44 #include "ROEdge.h"
45 #include "ROLane.h"
46 #include "RONode.h"
47 #include "RONet.h"
48 #include "RONetHandler.h"
49 #include "ROAbstractEdgeBuilder.h"
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
57  : SUMOSAXHandler("sumo-network"),
58  myNet(net), myCurrentName(),
59  myCurrentEdge(0), myCurrentStoppingPlace(0),
60  myEdgeBuilder(eb) {}
61 
62 
64 
65 
66 void
68  const SUMOSAXAttributes& attrs) {
69  switch (element) {
70  case SUMO_TAG_EDGE:
71  // in the first step, we do need the name to allocate the edge
72  // in the second, we need it to know to which edge we have to add
73  // the following edges to
74  parseEdge(attrs);
75  break;
76  case SUMO_TAG_LANE:
77  parseLane(attrs);
78  break;
79  case SUMO_TAG_JUNCTION:
80  parseJunction(attrs);
81  break;
83  parseConnection(attrs);
84  break;
85  case SUMO_TAG_BUS_STOP:
89  parseStoppingPlace(attrs, (SumoXMLTag)element);
90  break;
91  case SUMO_TAG_ACCESS:
92  parseAccess(attrs);
93  break;
94  case SUMO_TAG_TAZ:
95  parseDistrict(attrs);
96  break;
97  case SUMO_TAG_TAZSOURCE:
98  parseDistrictEdge(attrs, true);
99  break;
100  case SUMO_TAG_TAZSINK:
101  parseDistrictEdge(attrs, false);
102  break;
103  case SUMO_TAG_TYPE: {
104  bool ok = true;
105  myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
106  break;
107  }
108  case SUMO_TAG_RESTRICTION: {
109  bool ok = true;
110  const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
111  const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
112  if (ok) {
113  myNet.addRestriction(myCurrentTypeID, svc, speed);
114  }
115  break;
116  }
117  default:
118  break;
119  }
120 }
121 
122 
123 void
125  switch (element) {
126  case SUMO_TAG_NET:
127  // build junction graph
128  for (std::set<std::string>::const_iterator it = myUnseenNodeIDs.begin(); it != myUnseenNodeIDs.end(); ++it) {
129  WRITE_ERROR("Unknown node '" + *it + "'.");
130  }
131  break;
132  default:
133  break;
134  }
135 }
136 
137 
138 void
140  // get the id, report an error if not given or empty...
141  bool ok = true;
142  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
143  if (!ok) {
144  throw ProcessError();
145  }
146  const SumoXMLEdgeFunc func = attrs.getEdgeFunc(ok);
147  if (!ok) {
148  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
149  return;
150  }
151  // get the edge
152  std::string from;
153  std::string to;
154  int priority;
155  myCurrentEdge = 0;
156  if (func == EDGEFUNC_INTERNAL || func == EDGEFUNC_CROSSING || func == EDGEFUNC_WALKINGAREA) {
157  assert(myCurrentName[0] == ':');
158  const std::string junctionID = myCurrentName.substr(1, myCurrentName.rfind('_') - 1);
159  from = junctionID;
160  to = junctionID;
161  priority = 0;
162  } else {
163  from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
164  to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
165  priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
166  if (!ok) {
167  return;
168  }
169  }
170  RONode* fromNode = myNet.getNode(from);
171  if (fromNode == 0) {
172  myUnseenNodeIDs.insert(from);
173  fromNode = new RONode(from);
174  myNet.addNode(fromNode);
175  }
176  RONode* toNode = myNet.getNode(to);
177  if (toNode == 0) {
178  myUnseenNodeIDs.insert(to);
179  toNode = new RONode(to);
180  myNet.addNode(toNode);
181  }
182  // build the edge
183  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
184  // set the type
185  myCurrentEdge->setRestrictions(myNet.getRestrictions(attrs.getOpt<std::string>(SUMO_ATTR_TYPE, myCurrentName.c_str(), ok, "")));
186  myCurrentEdge->setFunction(func);
187 
188  if (myNet.addEdge(myCurrentEdge)) {
189  fromNode->addOutgoing(myCurrentEdge);
190  toNode->addIncoming(myCurrentEdge);
191  } else {
192  myCurrentEdge = 0;
193  }
194 }
195 
196 
197 void
199  if (myCurrentEdge == 0) {
200  // was an internal edge to skip or an error occured
201  return;
202  }
203  bool ok = true;
204  // get the id, report an error if not given or empty...
205  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
206  if (!ok) {
207  return;
208  }
209  // get the speed
210  double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
211  double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
212  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
213  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
214  if (!ok) {
215  return;
216  }
217  // get the length
218  // get the vehicle classes
219  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
220  if (permissions != SVCAll) {
222  }
223  // add when both values are valid
224  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
225  myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions));
226  }
227 }
228 
229 
230 void
232  bool ok = true;
233  // get the id, report an error if not given or empty...
234  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
235  if (attrs.getNodeType(ok) == NODETYPE_INTERNAL) {
236  return;
237  }
238  myUnseenNodeIDs.erase(id);
239  // get the position of the node
240  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
241  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
242  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
243  if (!ok) {
244  return;
245  }
246  RONode* n = myNet.getNode(id);
247  if (n == 0) {
248  WRITE_WARNING("Skipping isolated junction '" + id + "'.");
249  } else {
250  n->setPosition(Position(x, y, z));
251  }
252 }
253 
254 
255 void
257  bool ok = true;
258  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
259  std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
260  int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
261  int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
262  std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, 0, ok);
263  std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, 0, ok, "");
264  ROEdge* from = myNet.getEdge(fromID);
265  ROEdge* to = myNet.getEdge(toID);
266  if (from == 0) {
267  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
268  }
269  if (to == 0) {
270  throw ProcessError("unknown to-edge '" + toID + "' in connection");
271  }
272  if ((int)from->getLanes().size() <= fromLane) {
273  throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
274  }
275  if ((int)to->getLanes().size() <= toLane) {
276  throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
277  }
278  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane]);
279  from->addSuccessor(to, dir);
280  if (viaID != "") {
281  ROEdge* via = myNet.getEdge(viaID.substr(0, viaID.rfind('_')));
282  if (via == 0) {
283  throw ProcessError("unknown via-edge '" + viaID + "' in connection");
284  }
285  from->addSuccessor(via, dir);
286  return;
287  }
288 }
289 
290 
291 void
293  bool ok = true;
295  // get the id, throw if not given or empty...
296  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, toString(element).c_str(), ok);
297  // get the lane
298  myCurrentStoppingPlace->lane = attrs.get<std::string>(SUMO_ATTR_LANE, toString(element).c_str(), ok);
299  if (!ok) {
300  throw ProcessError();
301  }
303  if (edge == 0) {
304  throw InvalidArgument("Unknown lane '" + myCurrentStoppingPlace->lane + "' for " + toString(element) + " '" + id + "'.");
305  }
306  // get the positions
307  myCurrentStoppingPlace->startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
308  myCurrentStoppingPlace->endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
309  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
311  throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
312  }
313  if (element == SUMO_TAG_CONTAINER_STOP) {
315  } else if (element == SUMO_TAG_PARKING_AREA) {
317  } else {
319  }
320 }
321 
322 
323 void
325  bool ok = true;
326  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
327  const ROEdge* edge = myNet.getEdgeForLaneID(lane);
328  if (edge == 0) {
329  throw InvalidArgument("Unknown lane '" + lane + "' for access.");
330  }
331  const double pos = attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0);
332  if (!ok) {
333  throw ProcessError();
334  }
335  myCurrentStoppingPlace->accessPos.insert(std::make_pair(lane, pos));
336 }
337 
338 
339 void
341  myCurrentEdge = 0;
342  bool ok = true;
343  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
344  if (!ok) {
345  return;
346  }
348  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
349  std::vector<std::string> desc = attrs.getStringVector(SUMO_ATTR_EDGES);
350  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
352  myNet.addDistrictEdge(myCurrentName, *i, false);
353  }
354  }
355 }
356 
357 
358 void
360  bool ok = true;
361  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
362  myNet.addDistrictEdge(myCurrentName, id, isSource);
363 }
364 
365 
366 
367 /****************************************************************************/
368 
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource)
Definition: RONet.cpp:169
std::string myCurrentName
The name of the edge/node that is currently processed.
Definition: RONetHandler.h:191
void addOutgoing(ROEdge *edge)
Definition: RONode.h:91
SumoXMLTag
Numbers representing SUMO-XML - element names.
ROAbstractEdgeBuilder & myEdgeBuilder
The object used to build of edges of the desired type.
Definition: RONetHandler.h:203
virtual SumoXMLNodeType getNodeType(bool &ok) const =0
Returns the value of the named attribute.
a source within a district (connection road)
A single lane the router may use.
Definition: ROLane.h:57
SUMOVehicleParameter::Stop * myCurrentStoppingPlace
The currently built stopping place.
Definition: RONetHandler.h:200
root element of a network file
begin/end of the description of a junction
begin/end of the description of a single lane
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types...
const std::map< SUMOVehicleClass, double > * getRestrictions(const std::string &id) const
Returns the restrictions for an edge type If no restrictions are present, 0 is returned.
Definition: RONet.cpp:128
void parseDistrict(const SUMOSAXAttributes &attrs)
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:205
a traffic assignment zone
void addNode(RONode *node)
Definition: RONet.cpp:191
connectio between two lanes
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:165
void parseJunction(const SUMOSAXAttributes &attrs)
Parses a junction&#39;s position.
virtual void addLane(ROLane *lane)
Adds a lane to the edge while loading.
Definition: ROEdge.cpp:94
virtual void parseLane(const SUMOSAXAttributes &attrs)
Parses and builds a lane.
const SVCPermissions SVCAll
all VClasses are allowed
begin/end of the description of an edge restriction
SAX-handler base for SUMO-files.
Interface for building instances of router-edges.
const std::vector< ROLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: ROEdge.h:477
std::set< std::string > myUnseenNodeIDs
temporary data for checking node initialisation after network parsing is finished ...
Definition: RONetHandler.h:206
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
void addParkingArea(const std::string &id, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:222
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
RONetHandler(RONet &net, ROAbstractEdgeBuilder &eb)
Constructor.
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: RONet.cpp:122
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
double startPos
The stopping position start.
Encapsulated SAX-Attributes.
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
std::multimap< std::string, double > accessPos
lanes and positions connected to this stop
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
#define POSITION_EPS
Definition: config.h:176
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
double endPos
The stopping position end.
void setPosition(const Position &p)
Sets the position of the node.
Definition: RONode.cpp:47
virtual ~RONetHandler()
Destructor.
void addIncoming(ROEdge *edge)
Definition: RONode.h:87
A basic edge for routing applications.
Definition: ROEdge.h:78
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
begin/end of the description of an edge
std::string lane
The lane to stop at.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
ROEdge * getEdgeForLaneID(const std::string &laneID) const
Retrieves an edge from the network when the lane id is given.
Definition: RONet.h:175
virtual ROEdge * buildEdge(const std::string &name, RONode *from, RONode *to, const int priority)=0
Builds an edge with the given name.
static bool checkStopPos(double &startPos, double &endPos, const double laneLength, const double minLength, const bool friendlyPos)
check start and end position of a stop
The router&#39;s network representation.
Definition: RONet.h:76
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition: RONet.cpp:152
A train stop (alias for bus stop)
a sink within a district (connection road)
Definition of vehicle stop (position and duration)
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
void addBusStop(const std::string &id, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:200
RONode * getNode(const std::string &id) const
Retrieves an node from the network.
Definition: RONet.h:197
The abstract direction of a link.
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:138
RONet & myNet
The net to store the information into.
Definition: RONetHandler.h:188
void parseConnection(const SUMOSAXAttributes &attrs)
virtual void myEndElement(int element)
Called when a closing tag occurs.
Base class for nodes used by the router.
Definition: RONode.h:53
std::string myCurrentTypeID
The id of the currently processed edge type.
Definition: RONetHandler.h:194
void parseAccess(const SUMOSAXAttributes &attrs)
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.
void setRestrictions(const std::map< SUMOVehicleClass, double > *restrictions)
Sets the vehicle class specific speed limits of the edge.
Definition: ROEdge.h:144
An access point for a train stop.
void addContainerStop(const std::string &id, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:211
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
ROEdge * myCurrentEdge
The currently built edge.
Definition: RONetHandler.h:197
void parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
void parseEdge(const SUMOSAXAttributes &attrs)
Parses and builds an edge.
void setPermissionsFound()
Definition: RONet.cpp:703
void parseStoppingPlace(const SUMOSAXAttributes &attrs, const SumoXMLTag element)
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition: ROEdge.h:120