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-sim.org/
14 // Copyright (C) 2002-2014 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 #ifdef CHECK_MEMORY_LEAKS
52 #include <foreign/nvwa/debug_new.h>
53 #endif // CHECK_MEMORY_LEAKS
54 
55 
56 // ===========================================================================
57 // method definitions
58 // ===========================================================================
61  : SUMOSAXHandler("sumo-network"),
62  myNet(net), myCurrentName(),
63  myCurrentEdge(0), myProcess(true), myEdgeBuilder(eb) {}
64 
65 
67 
68 
69 void
71  const SUMOSAXAttributes& attrs) {
72  switch (element) {
73  case SUMO_TAG_EDGE:
74  // in the first step, we do need the name to allocate the edge
75  // in the second, we need it to know to which edge we have to add
76  // the following edges to
77  parseEdge(attrs);
78  break;
79  case SUMO_TAG_LANE:
80  if (myProcess) {
81  parseLane(attrs);
82  }
83  break;
84  case SUMO_TAG_JUNCTION:
85  parseJunction(attrs);
86  break;
88  parseConnection(attrs);
89  break;
90  case SUMO_TAG_BUS_STOP:
91  parseBusStop(attrs);
92  break;
93  case SUMO_TAG_TAZ:
94  parseDistrict(attrs);
95  break;
96  case SUMO_TAG_TAZSOURCE:
97  parseDistrictEdge(attrs, true);
98  break;
99  case SUMO_TAG_TAZSINK:
100  parseDistrictEdge(attrs, false);
101  break;
102  default:
103  break;
104  }
105 }
106 
107 
108 void
110  switch (element) {
111  case SUMO_TAG_NET:
112  // build junction graph
113  for (JunctionGraph::iterator it = myJunctionGraph.begin(); it != myJunctionGraph.end(); ++it) {
114  ROEdge* edge = myNet.getEdge(it->first);
115  RONode* from = myNet.getNode(it->second.first);
116  RONode* to = myNet.getNode(it->second.second);
117  if (edge != 0 && from != 0 && to != 0) {
118  edge->setJunctions(from, to);
119  from->addOutgoing(edge);
120  to->addIncoming(edge);
121  }
122  }
123  break;
124  default:
125  break;
126  }
127 }
128 
129 
130 void
132  // get the id, report an error if not given or empty...
133  bool ok = true;
134  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
135  if (!ok) {
136  throw ProcessError();
137  }
138  const SumoXMLEdgeFunc type = attrs.getEdgeFunc(ok);
139  if (!ok) {
140  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
141  return;
142  }
143  // get the edge
144  std::string from;
145  std::string to;
146  RONode* fromNode;
147  RONode* toNode;
148  int priority;
149  myCurrentEdge = 0;
150  if (type == EDGEFUNC_INTERNAL || type == EDGEFUNC_CROSSING || type == EDGEFUNC_WALKINGAREA) {
151  assert(myCurrentName[0] == ':');
152  std::string junctionID = myCurrentName.substr(1, myCurrentName.rfind('_') - 1);
153  myJunctionGraph[myCurrentName] = std::make_pair(junctionID, junctionID);
154  from = junctionID;
155  to = junctionID;
156  priority = 0;
157  } else {
158  from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
159  to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
160  priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
161  if (!ok) {
162  return;
163  }
164  }
165  myJunctionGraph[myCurrentName] = std::make_pair(from, to);
166  fromNode = myNet.getNode(from);
167  if (fromNode == 0) {
168  fromNode = new RONode(from);
169  myNet.addNode(fromNode);
170  }
171  toNode = myNet.getNode(to);
172  if (toNode == 0) {
173  toNode = new RONode(to);
174  myNet.addNode(toNode);
175  }
176  // build the edge
177  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
178  // set the type
179  myProcess = true;
180  switch (type) {
181  case EDGEFUNC_CONNECTOR:
182  case EDGEFUNC_NORMAL:
184  break;
185  case EDGEFUNC_SOURCE:
187  break;
188  case EDGEFUNC_SINK:
190  break;
193  break;
194  case EDGEFUNC_CROSSING:
196  break;
197  case EDGEFUNC_INTERNAL:
199  myProcess = false;
200  break;
201  default:
202  throw ProcessError("Unhandled EdgeFunk " + toString(type));
203  }
204 
205  if (!myNet.addEdge(myCurrentEdge)) {
206  myCurrentEdge = 0;
207  }
208 }
209 
210 
211 void
213  if (myCurrentEdge == 0) {
214  // was an internal edge to skip or an error occured
215  return;
216  }
217  bool ok = true;
218  // get the id, report an error if not given or empty...
219  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
220  if (!ok) {
221  return;
222  }
223  // get the speed
224  SUMOReal maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_SPEED, id.c_str(), ok);
225  SUMOReal length = attrs.get<SUMOReal>(SUMO_ATTR_LENGTH, id.c_str(), ok);
226  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
227  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
228  if (!ok) {
229  return;
230  }
231  // get the length
232  // get the vehicle classes
233  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
234  if (permissions != SVCAll) {
236  }
237  // add when both values are valid
238  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
239  myCurrentEdge->addLane(new ROLane(id, myCurrentEdge, length, maxSpeed, permissions));
240  }
241 }
242 
243 
244 void
246  bool ok = true;
247  // get the id, report an error if not given or empty...
248  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
249  if (!ok) {
250  return;
251  }
252  // get the position of the node
253  SUMOReal x = attrs.get<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok);
254  SUMOReal y = attrs.get<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok);
255  if (ok) {
256  RONode* n = myNet.getNode(id);
257  if (n == 0) {
258  n = new RONode(id);
259  myNet.addNode(n);
260  }
261  n->setPosition(Position(x, y));
262  } else {
263  throw ProcessError();
264  }
265 }
266 
267 
268 void
270  bool ok = true;
271  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
272  std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
273  int fromLane = attrs.get<int>(SUMO_ATTR_FROM_LANE, 0, ok);
274  int toLane = attrs.get<int>(SUMO_ATTR_TO_LANE, 0, ok);
275  std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, 0, ok);
276  ROEdge* from = myNet.getEdge(fromID);
277  ROEdge* to = myNet.getEdge(toID);
278  if (from == 0) {
279  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
280  }
281  if (to == 0) {
282  throw ProcessError("unknown to-edge '" + toID + "' in connection");
283  }
284  if (from->getType() == ROEdge::ET_INTERNAL) { // skip inner lane connections
285  return;
286  }
287  if (from->getLanes().size() <= (size_t)fromLane) {
288  throw ProcessError("invalid fromLane '" + toString(fromLane) + "' in connection from '" + fromID + "'.");
289  }
290  if (to->getLanes().size() <= (size_t)toLane) {
291  throw ProcessError("invalid toLane '" + toString(toLane) + "' in connection to '" + toID + "'.");
292  }
293  from->getLanes()[fromLane]->addOutgoingLane(to->getLanes()[toLane]);
294  from->addFollower(to, dir);
295 }
296 
297 
298 void
300  bool ok = true;
302  // get the id, throw if not given or empty...
303  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "busStop", ok);
304  // get the lane
305  stop->lane = attrs.get<std::string>(SUMO_ATTR_LANE, "busStop", ok);
306  if (!ok) {
307  throw ProcessError();
308  }
309  const ROEdge* edge = myNet.getEdge(stop->lane.substr(0, stop->lane.rfind("_")));
310  if (edge == 0) {
311  throw InvalidArgument("Unknown lane '" + stop->lane + "' for bus stop '" + id + "'.");
312  }
313  // get the positions
314  stop->startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
315  stop->endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
316  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
317  if (!ok || !SUMORouteHandler::checkStopPos(stop->startPos, stop->endPos, edge->getLength(), POSITION_EPS, friendlyPos)) {
318  throw InvalidArgument("Invalid position for bus stop '" + id + "'.");
319  }
320  myNet.addBusStop(id, stop);
321 }
322 
323 
324 void
326  myCurrentEdge = 0;
327  bool ok = true;
328  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
329  if (!ok) {
330  return;
331  }
332  ROEdge* sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", 0, 0, 0);
334  myNet.addEdge(sink);
335  ROEdge* source = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0, 0);
336  source->setType(ROEdge::ET_DISTRICT);
337  myNet.addEdge(source);
338  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
339  std::vector<std::string> desc = attrs.getStringVector(SUMO_ATTR_EDGES);
340  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
341  ROEdge* edge = myNet.getEdge(*i);
342  // check whether the edge exists
343  if (edge == 0) {
344  throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
345  }
346  source->addFollower(edge);
347  edge->addFollower(sink);
348  }
349  }
350 }
351 
352 
353 void
355  bool ok = true;
356  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
357  ROEdge* succ = myNet.getEdge(id);
358  if (succ != 0) {
359  // connect edge
360  if (isSource) {
361  myNet.getEdge(myCurrentName + "-source")->addFollower(succ);
362  } else {
363  succ->addFollower(myNet.getEdge(myCurrentName + "-sink"));
364  }
365  } else {
366  WRITE_ERROR("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
367  }
368 }
369 
370 
371 
372 /****************************************************************************/
373 
std::string myCurrentName
The name of the edge/node that is currently processed.
Definition: RONetHandler.h:183
void addOutgoing(ROEdge *edge)
Definition: RONode.h:89
ROAbstractEdgeBuilder & myEdgeBuilder
The object used to build of edges of the desired type.
Definition: RONetHandler.h:192
A single lane the router may use.
Definition: ROLane.h:52
void parseDistrict(const SUMOSAXAttributes &attrs)
void setJunctions(RONode *from, RONode *to)
Definition: ROEdge.h:390
void addNode(RONode *node)
Definition: RONet.cpp:94
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:102
void parseJunction(const SUMOSAXAttributes &attrs)
Parses a junction's position.
static bool checkStopPos(SUMOReal &startPos, SUMOReal &endPos, const SUMOReal laneLength, const SUMOReal minLength, const bool friendlyPos)
check start and end position of a stop
virtual void addLane(ROLane *lane)
Adds a lane to the edge while loading.
Definition: ROEdge.cpp:90
An internal edge which models vehicles driving across a junction. This is currently not used for rout...
Definition: ROEdge.h:89
virtual void parseLane(const SUMOSAXAttributes &attrs)
Parses and builds a lane.
const SVCPermissions SVCAll
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...
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition: ROEdge.h:399
virtual SumoXMLEdgeFunc getEdgeFunc(bool &ok) const =0
Returns the value of the named attribute.
JunctionGraph myJunctionGraph
Definition: RONetHandler.h:196
An internal edge which models walking areas for pedestrians.
Definition: ROEdge.h:85
virtual void myStartElement(int element, const SUMOSAXAttributes &attrs)
Called on the opening of a tag;.
An edge where vehicles are inserted at (no vehicle may come from back)
Definition: ROEdge.h:81
RONetHandler(RONet &net, ROAbstractEdgeBuilder &eb)
Constructor.
void setType(EdgeType type)
Sets the type of te edge.
Definition: ROEdge.cpp:303
SUMOReal startPos
The stopping position start.
the edges of a route
Encapsulated SAX-Attributes.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
SUMOReal endPos
The stopping position end.
#define POSITION_EPS
Definition: config.h:186
An edge representing a whole district.
Definition: ROEdge.h:79
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:51
void parseBusStop(const SUMOSAXAttributes &attrs)
virtual ~RONetHandler()
Destructor.
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
Definition: ToString.h:53
void addIncoming(ROEdge *edge)
Definition: RONode.h:85
A basic edge for routing applications.
Definition: ROEdge.h:69
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:205
virtual ROEdge * buildEdge(const std::string &name, RONode *from, RONode *to, const int priority)=0
Builds an edge with the given name.
The router's network representation.
Definition: RONet.h:67
void setRestrictionFound()
Definition: RONet.cpp:419
SUMOReal getLength() const
Returns the length of the edge.
Definition: ROEdge.h:180
A normal edge.
Definition: ROEdge.h:77
Definition of vehicle stop (position and duration)
An internal edge which models pedestrian crossings.
Definition: ROEdge.h:87
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:103
RONode * getNode(const std::string &id) const
Retrieves an node from the network.
Definition: RONet.h:124
The abstract direction of a link.
virtual bool addEdge(ROEdge *edge)
Definition: RONet.cpp:80
RONet & myNet
The net to store the information into.
Definition: RONetHandler.h:180
void parseConnection(const SUMOSAXAttributes &attrs)
#define SUMOReal
Definition: config.h:215
virtual void myEndElement(int element)
Called when a closing tag occurs.
Base class for nodes used by the router.
Definition: RONode.h:51
An edge where vehicles disappear (no vehicle may leave this edge)
Definition: ROEdge.h:83
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.
bool myProcess
An indicator whether the next edge shall be read (internal edges are not read by now) ...
Definition: RONetHandler.h:189
T get(int attr, const char *objectid, bool &ok, bool report=true) const
Tries to read given attribute assuming it is an int.
virtual void addFollower(ROEdge *s, std::string dir="")
Adds information about a connected edge.
Definition: ROEdge.cpp:103
ROEdge * myCurrentEdge
The currently built edge.
Definition: RONetHandler.h:186
void parseDistrictEdge(const SUMOSAXAttributes &attrs, bool isSource)
void parseEdge(const SUMOSAXAttributes &attrs)
Parses and builds an edge.