Eclipse 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-2019 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>
39 #include "ROEdge.h"
40 #include "ROLane.h"
41 #include "RONode.h"
42 #include "RONet.h"
43 #include "RONetHandler.h"
44 #include "ROAbstractEdgeBuilder.h"
45 
46 
47 // ===========================================================================
48 // method definitions
49 // ===========================================================================
50 RONetHandler::RONetHandler(RONet& net, ROAbstractEdgeBuilder& eb, const bool ignoreInternal, const double minorPenalty) :
51  SUMOSAXHandler("sumo-network"),
52  myNet(net),
53  myNetworkVersion(0),
54  myEdgeBuilder(eb), myIgnoreInternal(ignoreInternal),
55  myCurrentName(), myCurrentEdge(nullptr), myCurrentStoppingPlace(nullptr),
56  myMinorPenalty(minorPenalty)
57 {}
58 
59 
61 
62 
63 void
65  const SUMOSAXAttributes& attrs) {
66  switch (element) {
67  case SUMO_TAG_LOCATION:
68  setLocation(attrs);
69  break;
70  case SUMO_TAG_NET: {
71  bool ok;
72  myNetworkVersion = attrs.get<double>(SUMO_ATTR_VERSION, nullptr, ok, false);
73  break;
74  }
75  case SUMO_TAG_EDGE:
76  // in the first step, we do need the name to allocate the edge
77  // in the second, we need it to know to which edge we have to add
78  // the following edges to
79  parseEdge(attrs);
80  break;
81  case SUMO_TAG_LANE:
82  parseLane(attrs);
83  break;
84  case SUMO_TAG_JUNCTION:
85  parseJunction(attrs);
86  break;
88  parseConnection(attrs);
89  break;
90  case SUMO_TAG_BUS_STOP:
94  parseStoppingPlace(attrs, (SumoXMLTag)element);
95  break;
96  case SUMO_TAG_ACCESS:
97  parseAccess(attrs);
98  break;
99  case SUMO_TAG_TAZ:
100  parseDistrict(attrs);
101  break;
102  case SUMO_TAG_TAZSOURCE:
103  parseDistrictEdge(attrs, true);
104  break;
105  case SUMO_TAG_TAZSINK:
106  parseDistrictEdge(attrs, false);
107  break;
108  case SUMO_TAG_TYPE: {
109  bool ok = true;
110  myCurrentTypeID = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
111  break;
112  }
113  case SUMO_TAG_RESTRICTION: {
114  bool ok = true;
115  const SUMOVehicleClass svc = getVehicleClassID(attrs.get<std::string>(SUMO_ATTR_VCLASS, myCurrentTypeID.c_str(), ok));
116  const double speed = attrs.get<double>(SUMO_ATTR_SPEED, myCurrentTypeID.c_str(), ok);
117  if (ok) {
118  myNet.addRestriction(myCurrentTypeID, svc, speed);
119  }
120  break;
121  }
122  default:
123  break;
124  }
125 }
126 
127 
128 void
130  switch (element) {
131  case SUMO_TAG_NET:
132  // build junction graph
133  for (std::set<std::string>::const_iterator it = myUnseenNodeIDs.begin(); it != myUnseenNodeIDs.end(); ++it) {
134  WRITE_ERROR("Unknown node '" + *it + "'.");
135  }
136  break;
137  default:
138  break;
139  }
140 }
141 
142 
143 void
145  // get the id, report an error if not given or empty...
146  bool ok = true;
147  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
148  if (!ok) {
149  throw ProcessError();
150  }
151  const SumoXMLEdgeFunc func = attrs.getEdgeFunc(ok);
152  if (!ok) {
153  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
154  return;
155  }
156  // get the edge
157  std::string from;
158  std::string to;
159  int priority;
160  myCurrentEdge = nullptr;
161  if (func == EDGEFUNC_INTERNAL || func == EDGEFUNC_CROSSING || func == EDGEFUNC_WALKINGAREA) {
162  assert(myCurrentName[0] == ':');
163  const std::string junctionID = myCurrentName.substr(1, myCurrentName.rfind('_') - 1);
164  from = junctionID;
165  to = junctionID;
166  priority = 0;
167  } else {
168  from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
169  to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
170  priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
171  if (!ok) {
172  return;
173  }
174  }
175  RONode* fromNode = myNet.getNode(from);
176  if (fromNode == nullptr) {
177  myUnseenNodeIDs.insert(from);
178  fromNode = new RONode(from);
179  myNet.addNode(fromNode);
180  }
181  RONode* toNode = myNet.getNode(to);
182  if (toNode == nullptr) {
183  myUnseenNodeIDs.insert(to);
184  toNode = new RONode(to);
185  myNet.addNode(toNode);
186  }
187  // build the edge
188  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
189  // set the type
190  myCurrentEdge->setRestrictions(myNet.getRestrictions(attrs.getOpt<std::string>(SUMO_ATTR_TYPE, myCurrentName.c_str(), ok, "")));
191  myCurrentEdge->setFunction(func);
192 
193  if (myNet.addEdge(myCurrentEdge)) {
194  fromNode->addOutgoing(myCurrentEdge);
195  toNode->addIncoming(myCurrentEdge);
196  } else {
197  myCurrentEdge = nullptr;
198  }
199 }
200 
201 
202 void
204  if (myCurrentEdge == nullptr) {
205  // was an internal edge to skip or an error occurred
206  return;
207  }
208  bool ok = true;
209  // get the id, report an error if not given or empty...
210  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
211  if (!ok) {
212  return;
213  }
214  // get the speed
215  double maxSpeed = attrs.get<double>(SUMO_ATTR_SPEED, id.c_str(), ok);
216  double length = attrs.get<double>(SUMO_ATTR_LENGTH, id.c_str(), ok);
217  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
218  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
219  const PositionVector shape = attrs.get<PositionVector>(SUMO_ATTR_SHAPE, id.c_str(), ok);
220  if (!ok) {
221  return;
222  }
223  if (shape.size() < 2) {
224  WRITE_ERROR("Ignoring lane '" + id + "' with broken shape.");
225  return;
226  }
227  // get the length
228  // get the vehicle classes
229  SVCPermissions permissions = parseVehicleClasses(allow, disallow, myNetworkVersion);
230  if (permissions != SVCAll) {
232  }
233  // add when both values are valid
234  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
235  myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions, shape));
236  } else {
237  WRITE_WARNING("Ignoring lane '" + id + "' with speed " + toString(maxSpeed) + " and length " + toString(length));
238  }
239 }
240 
241 
242 void
244  bool ok = true;
245  // get the id, report an error if not given or empty...
246  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
247  if (attrs.getNodeType(ok) == NODETYPE_INTERNAL) {
248  return;
249  }
250  myUnseenNodeIDs.erase(id);
251  // get the position of the node
252  const double x = attrs.get<double>(SUMO_ATTR_X, id.c_str(), ok);
253  const double y = attrs.get<double>(SUMO_ATTR_Y, id.c_str(), ok);
254  const double z = attrs.getOpt<double>(SUMO_ATTR_Z, id.c_str(), ok, 0.);
255  if (!ok) {
256  return;
257  }
258  RONode* n = myNet.getNode(id);
259  if (n == nullptr) {
260  WRITE_WARNING("Skipping isolated junction '" + id + "'.");
261  } else {
262  n->setPosition(Position(x, y, z));
263  }
264 }
265 
266 
267 void
269  bool ok = true;
270  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, nullptr, ok);
271  std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, nullptr, ok);
272  const int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, nullptr, ok);
273  const int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, nullptr, ok);
274  std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, nullptr, ok);
275  std::string viaID = attrs.getOpt<std::string>(SUMO_ATTR_VIA, nullptr, ok, "");
276  ROEdge* from = myNet.getEdge(fromID);
277  ROEdge* to = myNet.getEdge(toID);
278  if (from == nullptr) {
279  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
280  }
281  if (to == nullptr) {
282  throw ProcessError("unknown to-edge '" + toID + "' in connection");
283  }
284  if ((int)from->getLanes().size() <= fromLane) {
285  throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
286  }
287  if ((int)to->getLanes().size() <= toLane) {
288  throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
289  }
290  if (myIgnoreInternal || viaID == "") {
291  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane]);
292  from->addSuccessor(to, nullptr, dir);
293  } else {
294  ROEdge* const via = myNet.getEdge(viaID.substr(0, viaID.rfind('_')));
295  if (via == nullptr) {
296  throw ProcessError("unknown via-edge '" + viaID + "' in connection");
297  }
298  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane], via);
299  from->addSuccessor(to, via, dir);
300  via->addSuccessor(to, nullptr, dir);
301  LinkState state = SUMOXMLDefinitions::LinkStates.get(attrs.get<std::string>(SUMO_ATTR_STATE, nullptr, ok));
302  if (state == LINKSTATE_MINOR || state == LINKSTATE_EQUAL || state == LINKSTATE_STOP || state == LINKSTATE_ALLWAY_STOP) {
304  }
305  }
306 }
307 
308 
309 void
311  bool ok = true;
313  // get the id, throw if not given or empty...
314  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, toString(element).c_str(), ok);
315  // get the lane
316  myCurrentStoppingPlace->lane = attrs.get<std::string>(SUMO_ATTR_LANE, toString(element).c_str(), ok);
317  if (!ok) {
318  throw ProcessError();
319  }
321  if (edge == nullptr) {
322  throw InvalidArgument("Unknown lane '" + myCurrentStoppingPlace->lane + "' for " + toString(element) + " '" + id + "'.");
323  }
324  // get the positions
325  myCurrentStoppingPlace->startPos = attrs.getOpt<double>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0.);
326  myCurrentStoppingPlace->endPos = attrs.getOpt<double>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
327  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
329  throw InvalidArgument("Invalid position for " + toString(element) + " '" + id + "'.");
330  }
331  // 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
332  myCurrentStoppingPlace->busstop = attrs.getOpt<std::string>(SUMO_ATTR_NAME, id.c_str(), ok, "");
334 }
335 
336 
337 void
339  bool ok = true;
340  const std::string lane = attrs.get<std::string>(SUMO_ATTR_LANE, "access", ok);
341  const ROEdge* edge = myNet.getEdgeForLaneID(lane);
342  if (edge == nullptr) {
343  throw InvalidArgument("Unknown lane '" + lane + "' for access.");
344  }
345  if ((edge->getPermissions() & SVC_PEDESTRIAN) == 0) {
346  WRITE_WARNING("Ignoring invalid access from non-pedestrian edge '" + edge->getID() + "'.");
347  return;
348  }
349  double pos = attrs.getOpt<double>(SUMO_ATTR_POSITION, "access", ok, 0.);
350  const double length = attrs.getOpt<double>(SUMO_ATTR_LENGTH, "access", ok, -1);
351  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, "access", ok, false);
352  if (!ok || !SUMORouteHandler::checkStopPos(pos, pos, edge->getLength(), 0., friendlyPos)) {
353  throw InvalidArgument("Invalid position " + toString(pos) + " for access on lane '" + lane + "'.");
354  }
355  if (!ok) {
356  throw ProcessError();
357  }
358  myCurrentStoppingPlace->accessPos.push_back(std::make_tuple(lane, pos, length));
359 }
360 
361 
362 void
364  myCurrentEdge = nullptr;
365  bool ok = true;
366  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, nullptr, ok);
367  if (!ok) {
368  return;
369  }
370  myNet.addDistrict(myCurrentName, myEdgeBuilder.buildEdge(myCurrentName + "-source", nullptr, nullptr, 0), myEdgeBuilder.buildEdge(myCurrentName + "-sink", nullptr, nullptr, 0));
371  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
372  std::vector<std::string> desc = attrs.getStringVector(SUMO_ATTR_EDGES);
373  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
375  myNet.addDistrictEdge(myCurrentName, *i, false);
376  }
377  }
378 }
379 
380 
381 void
383  bool ok = true;
384  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
385  myNet.addDistrictEdge(myCurrentName, id, isSource);
386 }
387 
388 void
390  bool ok = true;
391  PositionVector s = attrs.get<PositionVector>(SUMO_ATTR_NET_OFFSET, nullptr, ok);
392  Boundary convBoundary = attrs.get<Boundary>(SUMO_ATTR_CONV_BOUNDARY, nullptr, ok);
393  Boundary origBoundary = attrs.get<Boundary>(SUMO_ATTR_ORIG_BOUNDARY, nullptr, ok);
394  std::string proj = attrs.get<std::string>(SUMO_ATTR_ORIG_PROJ, nullptr, ok);
395  if (ok) {
396  Position networkOffset = s[0];
397  GeoConvHelper::init(proj, networkOffset, origBoundary, convBoundary);
398  }
399 }
400 
401 /****************************************************************************/
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:185
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:195
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:189
std::string lane
The lane to stop at.
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:163
A single lane the router may use.
Definition: ROLane.h:51
SUMOVehicleParameter::Stop * myCurrentStoppingPlace
The currently built stopping place.
Definition: RONetHandler.h:204
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:192
void addNode(RONode *node)
Definition: RONet.cpp:191
connectio between two lanes
This is an uncontrolled, minor link, has to stop.
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:92
std::string busstop
(Optional) bus stop if one is assigned to the stop
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
virtual void parseLane(const SUMOSAXAttributes &attrs)
Parses and builds a lane.
This is an uncontrolled, right-before-left link.
double getLength() const
Returns the length of the edge.
Definition: ROEdge.h:203
static StringBijection< LinkState > LinkStates
link states
const SVCPermissions SVCAll
all VClasses are allowed
begin/end of the description of an edge restriction
SAX-handler base for SUMO-files.
This is an uncontrolled, all-way stop link.
Interface for building instances of router-edges.
RONetHandler(RONet &net, ROAbstractEdgeBuilder &eb, const bool ignoreInternal, const double minorPenalty)
Constructor.
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:207
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:42
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
The state of a link.
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:48
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.
This is an uncontrolled, minor link, has to brake.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:39
A list of positions.
T get(const std::string &str) const
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic, in MSLink and GNEInternalLane.
static bool init(OptionsCont &oc)
Initialises the processing and the final instance using the given options.
void setTimePenalty(double value)
Definition: ROEdge.h:143
#define POSITION_EPS
Definition: config.h:169
edge: the shape in xml-definition
SVCPermissions parseVehicleClasses(const std::string &allowedS)
Parses the given definition of allowed vehicle classes into the given containers Deprecated classes g...
void setPosition(const Position &p)
Sets the position of the node.
Definition: RONode.cpp:40
double endPos
The stopping position end.
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:73
begin/end of the description of an edge
Definition of vehicle stop (position and duration)
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:245
virtual ROEdge * buildEdge(const std::string &name, RONode *from, RONode *to, const int priority)=0
Builds an edge with the given name.
double startPos
The stopping position start.
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:64
bool addDistrict(const std::string id, ROEdge *source, ROEdge *sink)
Definition: RONet.cpp:152
A train stop (alias for bus stop)
void addStoppingPlace(const std::string &id, const SumoXMLTag category, SUMOVehicleParameter::Stop *stop)
Definition: RONet.cpp:200
std::vector< std::tuple< std::string, double, double > > accessPos
lanes and positions connected to this stop (only used by duarouter where Stop is used to store stoppi...
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:105
const std::vector< std::string > getStringVector(int attr) const
Tries to read given attribute assuming it is a string vector.
SumoXMLEdgeFunc
Numbers representing special SUMO-XML-attribute values for representing edge functions used in netbui...
const double myMinorPenalty
time penalty for passing a minor link
Definition: RONetHandler.h:210
The abstract direction of a link.
const std::vector< ROLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: ROEdge.h:475
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:138
RONet & myNet
The net to store the information into.
Definition: RONetHandler.h:183
void parseConnection(const SUMOSAXAttributes &attrs)
void setLocation(const SUMOSAXAttributes &attrs)
Parses network location description.
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:198
void parseAccess(const SUMOSAXAttributes &attrs)
double myNetworkVersion
the loaded network version
Definition: RONetHandler.h:186
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:153
void setRestrictions(const std::map< SUMOVehicleClass, double > *restrictions)
Sets the vehicle class specific speed limits of the edge.
Definition: ROEdge.h:139
An access point for a train stop.
ROEdge * myCurrentEdge
The currently built edge.
Definition: RONetHandler.h:201
void parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
void parseEdge(const SUMOSAXAttributes &attrs)
Parses and builds an edge.
void setPermissionsFound()
Definition: RONet.cpp:699
void parseStoppingPlace(const SUMOSAXAttributes &attrs, const SumoXMLTag element)
void setFunction(SumoXMLEdgeFunc func)
Sets the function of the edge.
Definition: ROEdge.h:115