SUMO - Simulation of Urban MObility
RONetHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2018 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
19 // The handler for SUMO-Networks
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #include <config.h>
27 
28 #include <string>
32 #include <utils/common/ToString.h>
37 #include "ROEdge.h"
38 #include "ROLane.h"
39 #include "RONode.h"
40 #include "RONet.h"
41 #include "RONetHandler.h"
42 #include "ROAbstractEdgeBuilder.h"
43 
44 
45 // ===========================================================================
46 // method definitions
47 // ===========================================================================
48 RONetHandler::RONetHandler(RONet& net, ROAbstractEdgeBuilder& eb, const bool ignoreInternal)
49  : SUMOSAXHandler("sumo-network"),
50  myNet(net), myEdgeBuilder(eb), myIgnoreInternal(ignoreInternal),
51  myCurrentName(), myCurrentEdge(nullptr), myCurrentStoppingPlace(nullptr) {}
52 
53 
55 
56 
57 void
59  const SUMOSAXAttributes& attrs) {
60  switch (element) {
61  case SUMO_TAG_EDGE:
62  // in the first step, we do need the name to allocate the edge
63  // in the second, we need it to know to which edge we have to add
64  // the following edges to
65  parseEdge(attrs);
66  break;
67  case SUMO_TAG_LANE:
68  parseLane(attrs);
69  break;
70  case SUMO_TAG_JUNCTION:
71  parseJunction(attrs);
72  break;
74  parseConnection(attrs);
75  break;
76  case SUMO_TAG_BUS_STOP:
80  parseStoppingPlace(attrs, (SumoXMLTag)element);
81  break;
82  case SUMO_TAG_ACCESS:
83  parseAccess(attrs);
84  break;
85  case SUMO_TAG_TAZ:
86  parseDistrict(attrs);
87  break;
88  case SUMO_TAG_TAZSOURCE:
89  parseDistrictEdge(attrs, true);
90  break;
91  case SUMO_TAG_TAZSINK:
92  parseDistrictEdge(attrs, false);
93  break;
94  case SUMO_TAG_TYPE: {
95  bool ok = true;
96  myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
97  break;
98  }
99  case SUMO_TAG_RESTRICTION: {
100  bool ok = true;
101  const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
102  const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
103  if (ok) {
104  myNet.addRestriction(myCurrentTypeID, svc, speed);
105  }
106  break;
107  }
108  default:
109  break;
110  }
111 }
112 
113 
114 void
116  switch (element) {
117  case SUMO_TAG_NET:
118  // build junction graph
119  for (std::set<std::string>::const_iterator it = myUnseenNodeIDs.begin(); it != myUnseenNodeIDs.end(); ++it) {
120  WRITE_ERROR("Unknown node '" + *it + "'.");
121  }
122  break;
123  default:
124  break;
125  }
126 }
127 
128 
129 void
131  // get the id, report an error if not given or empty...
132  bool ok = true;
133  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
134  if (!ok) {
135  throw ProcessError();
136  }
137  const SumoXMLEdgeFunc func = attrs.getEdgeFunc(ok);
138  if (!ok) {
139  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
140  return;
141  }
142  // get the edge
143  std::string from;
144  std::string to;
145  int priority;
146  myCurrentEdge = nullptr;
147  if (func == EDGEFUNC_INTERNAL || func == EDGEFUNC_CROSSING || func == EDGEFUNC_WALKINGAREA) {
148  assert(myCurrentName[0] == ':');
149  const std::string junctionID = myCurrentName.substr(1, myCurrentName.rfind('_') - 1);
150  from = junctionID;
151  to = junctionID;
152  priority = 0;
153  } else {
154  from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
155  to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
156  priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
157  if (!ok) {
158  return;
159  }
160  }
161  RONode* fromNode = myNet.getNode(from);
162  if (fromNode == nullptr) {
163  myUnseenNodeIDs.insert(from);
164  fromNode = new RONode(from);
165  myNet.addNode(fromNode);
166  }
167  RONode* toNode = myNet.getNode(to);
168  if (toNode == nullptr) {
169  myUnseenNodeIDs.insert(to);
170  toNode = new RONode(to);
171  myNet.addNode(toNode);
172  }
173  // build the edge
174  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
175  // set the type
176  myCurrentEdge->setRestrictions(myNet.getRestrictions(attrs.getOpt<std::string>(SUMO_ATTR_TYPE, myCurrentName.c_str(), ok, "")));
177  myCurrentEdge->setFunction(func);
178 
179  if (myNet.addEdge(myCurrentEdge)) {
180  fromNode->addOutgoing(myCurrentEdge);
181  toNode->addIncoming(myCurrentEdge);
182  } else {
183  myCurrentEdge = nullptr;
184  }
185 }
186 
187 
188 void
190  if (myCurrentEdge == nullptr) {
191  // was an internal edge to skip or an error occurred
192  return;
193  }
194  bool ok = true;
195  // get the id, report an error if not given or empty...
196  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
197  if (!ok) {
198  return;
199  }
200  // get the speed
201  double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
202  double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
203  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
204  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
205  if (!ok) {
206  return;
207  }
208  // get the length
209  // get the vehicle classes
210  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
211  if (permissions != SVCAll) {
213  }
214  // add when both values are valid
215  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
216  myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions));
217  } else {
218  WRITE_WARNING("Ignoring lane '" + id + "' with speed " + toString(maxSpeed) + " and length " + toString(length));
219  }
220 }
221 
222 
223 void
225  bool ok = true;
226  // get the id, report an error if not given or empty...
227  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
228  if (attrs.getNodeType(ok) == NODETYPE_INTERNAL) {
229  return;
230  }
231  myUnseenNodeIDs.erase(id);
232  // get the position of the node
233  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
234  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
235  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
236  if (!ok) {
237  return;
238  }
239  RONode* n = myNet.getNode(id);
240  if (n == nullptr) {
241  WRITE_WARNING("Skipping isolated junction '" + id + "'.");
242  } else {
243  n->setPosition(Position(x, y, z));
244  }
245 }
246 
247 
248 void
250  bool ok = true;
251  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
252  std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
253  const int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
254  const int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
255  std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok);
256  std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
257  ROEdge* from = myNet.getEdge(fromID);
258  ROEdge* to = myNet.getEdge(toID);
259  if (from == nullptr) {
260  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
261  }
262  if (to == nullptr) {
263  throw ProcessError("unknown to-edge '" + toID + "' in connection");
264  }
265  if ((int)from->getLanes().size() <= fromLane) {
266  throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
267  }
268  if ((int)to->getLanes().size() <= toLane) {
269  throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
270  }
271  if (myIgnoreInternal || viaID == "") {
272  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane]);
273  from->addSuccessor(to, nullptr, dir);
274  } else {
275  ROEdge* const via = myNet.getEdge(viaID.substr(0, viaID.rfind('_')));
276  if (via == nullptr) {
277  throw ProcessError("unknown via-edge '" + viaID + "' in connection");
278  }
279  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], via);
280  from->addSuccessor(to, via, dir);
281  via->addSuccessor(to, nullptr, dir);
282  }
283 }
284 
285 
286 void
288  bool ok = true;
290  // get the id, throw if not given or empty...
291  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, toString(element).c_str(), ok);
292  // get the lane
293  myCurrentStoppingPlace->lane = attrs.get<std::string>(SUMO_ATTR_LANE, toString(element).c_str(), ok);
294  if (!ok) {
295  throw ProcessError();
296  }
298  if (edge == nullptr) {
299  throw InvalidArgument("Unknown lane '" + myCurrentStoppingPlace->lane + "' for " + toString(element) + " '" + id + "'.");
300  }
301  // get the positions
302  myCurrentStoppingPlace->startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0.);
303  myCurrentStoppingPlace->endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
304  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
306  throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
307  }
308  // this is a hack: the busstop attribute is meant to hold the id within the simulation context but this is not used within the router context
309  myCurrentStoppingPlace->busstop = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
311 }
312 
313 
314 void
316  bool ok = true;
317  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
318  const ROEdge* edge = myNet.getEdgeForLaneID(lane);
319  if (edge == nullptr) {
320  throw InvalidArgument("Unknown lane '" + lane + "' for access.");
321  }
322  double pos = attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0.);
323  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
324  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
325  if (!ok || !SUMORouteHandler::checkStopPos(pos, pos, edge->getLength(), 0., friendlyPos)) {
326  throw InvalidArgument("Invalid position " + toString(pos) + " for access on lane '" + lane + "'.");
327  }
328  if (!ok) {
329  throw ProcessError();
330  }
331  myCurrentStoppingPlace->accessPos.push_back(std::make_tuple(lane, pos, length));
332 }
333 
334 
335 void
337  myCurrentEdge = nullptr;
338  bool ok = true;
339  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
340  if (!ok) {
341  return;
342  }
343  myNet.addDistrict(myCurrentName, myEdgeBuilder.buildEdge(myCurrentName + "-source", nullptr, nullptr, 0), myEdgeBuilder.buildEdge(myCurrentName + "-sink", nullptr, nullptr, 0));
344  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
345  std::vector<std::string> desc = attrs.getStringVector(SUMO_ATTR_EDGES);
346  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
348  myNet.addDistrictEdge(myCurrentName, *i, false);
349  }
350  }
351 }
352 
353 
354 void
356  bool ok = true;
357  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
358  myNet.addDistrictEdge(myCurrentName, id, isSource);
359 }
360 
361 
362 /****************************************************************************/
SUMOVehicleClass getVehicleClassID(const std::string &name)
Returns the class id of the abstract class given by its name.
RONode * getNode(const std::string &id) const
Retrieves an node from the network.
Definition: RONet.h:189
RONetHandler(RONet &net, ROAbstractEdgeBuilder &eb, const bool ignoreInternal)
Constructor.
bool addDistrictEdge(const std::string tazID, const std::string edgeID, const bool isSource)
Definition: RONet.cpp:168
std::string myCurrentName
The name of the edge/node that is currently processed.
Definition: RONetHandler.h:190
void addOutgoing(ROEdge *edge)
Definition: RONode.h:84
SumoXMLTag
Numbers representing SUMO-XML - element names.
ROAbstractEdgeBuilder & myEdgeBuilder
The object used to build of edges of the desired type.
Definition: RONetHandler.h:184
a source within a district (connection road)
ROEdge * getEdgeForLaneID(const std::string &laneID) const
Retrieves an edge from the network when the lane id is given.
Definition: RONet.h:167
A single lane the router may use.
Definition: ROLane.h:50
SUMOVehicleParameter::Stop * myCurrentStoppingPlace
The currently built stopping place.
Definition: RONetHandler.h:199
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...
void parseDistrict(const SUMOSAXAttributes &attrs)
a traffic assignment zone
const bool myIgnoreInternal
whether to ignore junction internal edges
Definition: RONetHandler.h:187
void addNode(RONode *node)
Definition: RONet.cpp:190
connectio between two lanes
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
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:90
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:127
virtual void parseLane(const SUMOSAXAttributes &attrs)
Parses and builds a lane.
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:199
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.
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
std::set< std::string > myUnseenNodeIDs
temporary data for checking node initialisation after network parsing is finished ...
Definition: RONetHandler.h:202
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:241
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
std::string busstop
(Optional) bus stop if one is assigned to the stop
void addRestriction(const std::string &id, const SUMOVehicleClass svc, const double speed)
Adds a restriction for an edge type.
Definition: RONet.cpp:121
the edges of a route
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:49
double startPos
The stopping position start.
Encapsulated SAX-Attributes.
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
#define POSITION_EPS
Definition: config.h:172
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:40
virtual ~RONetHandler()
Destructor.
virtual SumoXMLNodeType getNodeType(bool &ok) const =0
Returns the value of the named attribute.
void addIncoming(ROEdge *edge)
Definition: RONode.h:80
A basic edge for routing applications.
Definition: ROEdge.h:72
begin/end of the description of an edge
std::string lane
The lane to stop at.
virtual std::vector< std::string > getStringVector(int attr) const =0
Tries to read given attribute assuming it is a string vector.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:247
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
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.
The router&#39;s network representation.
Definition: RONet.h:68
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition: RONet.cpp:151
A train stop (alias for bus stop)
void addStoppingPlace(const std::string &id, const SumoXMLTag category, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:199
a sink within a district (connection road)
virtual void addSuccessor(ROEdge *s, ROEdge *via=nullptr, std::string dir="")
Adds information about a connected edge.
Definition: ROEdge.cpp:103
Definition of vehicle stop (position and duration)
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
The abstract direction of a link.
const std::vector< ROLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: ROEdge.h:473
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:137
RONet & myNet
The net to store the information into.
Definition: RONetHandler.h:181
void parseConnection(const SUMOSAXAttributes &attrs)
std::vector< std::tuple< std::string, double, double > > accessPos
lanes and positions connected to this stop
virtual void myEndElement(int element)
Called when a closing tag occurs.
Base class for nodes used by the router.
Definition: RONode.h:46
std::string myCurrentTypeID
The id of the currently processed edge type.
Definition: RONetHandler.h:193
void parseAccess(const SUMOSAXAttributes &attrs)
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
void setRestrictions(const std::map< SUMOVehicleClass, double > *restrictions)
Sets the vehicle class specific speed limits of the edge.
Definition: ROEdge.h:138
An access point for a train stop.
ROEdge * myCurrentEdge
The currently built edge.
Definition: RONetHandler.h:196
void parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
void parseEdge(const SUMOSAXAttributes &attrs)
Parses and builds an edge.
void setPermissionsFound()
Definition: RONet.cpp:697
void parseStoppingPlace(const SUMOSAXAttributes &attrs, const SumoXMLTag element)
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition: ROEdge.h:114