SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RONetHandler.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // The handler for SUMO-Networks
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 
25 // ===========================================================================
26 // included modules
27 // ===========================================================================
28 #ifdef _MSC_VER
29 #include <windows_config.h>
30 #else
31 #include <config.h>
32 #endif
33 
34 #include <string>
39 #include <utils/common/ToString.h>
43 #include "ROEdge.h"
44 #include "ROLane.h"
45 #include "RONode.h"
46 #include "RONet.h"
47 #include "RONetHandler.h"
48 #include "ROAbstractEdgeBuilder.h"
49 
50 #ifdef CHECK_MEMORY_LEAKS
51 #include <foreign/nvwa/debug_new.h>
52 #endif // CHECK_MEMORY_LEAKS
53 
54 
55 // ===========================================================================
56 // method definitions
57 // ===========================================================================
60  : SUMOSAXHandler("sumo-network"),
61  myNet(net), myCurrentName(),
62  myCurrentEdge(0), myEdgeBuilder(eb) {}
63 
64 
66 
67 
68 void
70  const SUMOSAXAttributes& attrs) {
71  switch (element) {
72  case SUMO_TAG_EDGE:
73  // in the first step, we do need the name to allocate the edge
74  // in the second, we need it to know to which edge we have to add
75  // the following edges to
76  parseEdge(attrs);
77  break;
78  case SUMO_TAG_LANE:
79  if (myProcess) {
80  parseLane(attrs);
81  }
82  break;
83  case SUMO_TAG_JUNCTION:
84  parseJunction(attrs);
85  break;
87  parseConnection(attrs);
88  break;
89  case SUMO_TAG_BUS_STOP:
90  parseBusStop(attrs);
91  break;
92  case SUMO_TAG_TAZ:
93  parseDistrict(attrs);
94  break;
95  case SUMO_TAG_TAZSOURCE:
96  parseDistrictEdge(attrs, true);
97  break;
98  case SUMO_TAG_TAZSINK:
99  parseDistrictEdge(attrs, false);
100  break;
101  default:
102  break;
103  }
104 }
105 
106 
107 void
109  // get the id, report an error if not given or empty...
110  bool ok = true;
111  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
112  if (!ok) {
113  throw ProcessError();
114  }
115  const SumoXMLEdgeFunc type = attrs.getEdgeFunc(ok);
116  if (!ok) {
117  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
118  return;
119  }
120  // get the edge
121  RONode* fromNode;
122  RONode* toNode;
123  int priority;
124  myCurrentEdge = 0;
125  if (type == EDGEFUNC_INTERNAL) {
126  // this is an internal edge - for now we only us it the ensure a match
127  // between numerical edge ids in router and simulation
128  // !!! recheck this; internal edges may be of importance during the dua
129  fromNode = 0;
130  toNode = 0;
131  priority = 0;
132  } else {
133  const std::string from = attrs.get<std::string>(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
134  const std::string to = attrs.get<std::string>(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
135  priority = attrs.get<int>(SUMO_ATTR_PRIORITY, myCurrentName.c_str(), ok);
136  if (!ok) {
137  return;
138  }
139  fromNode = myNet.getNode(from);
140  if (fromNode == 0) {
141  fromNode = new RONode(from);
142  myNet.addNode(fromNode);
143  }
144  toNode = myNet.getNode(to);
145  if (toNode == 0) {
146  toNode = new RONode(to);
147  myNet.addNode(toNode);
148  }
149  }
150  // build the edge
151  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode, priority);
152  // set the type
153  myProcess = true;
154  switch (type) {
155  case EDGEFUNC_CONNECTOR:
156  case EDGEFUNC_NORMAL:
158  break;
159  case EDGEFUNC_SOURCE:
161  break;
162  case EDGEFUNC_SINK:
164  break;
165  case EDGEFUNC_INTERNAL:
167  myProcess = false;
168  break;
169  default:
170  throw ProcessError("Unhandled EdgeFunk " + toString(type));
171  }
172 
173  if (!myNet.addEdge(myCurrentEdge)) {
174  myCurrentEdge = 0;
175  }
176 }
177 
178 
179 void
181  if (myCurrentEdge == 0) {
182  // was an internal edge to skip or an error occured
183  return;
184  }
185  bool ok = true;
186  // get the id, report an error if not given or empty...
187  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
188  if (!ok) {
189  return;
190  }
191  // get the speed
192  SUMOReal maxSpeed = attrs.get<SUMOReal>(SUMO_ATTR_SPEED, id.c_str(), ok);
193  SUMOReal length = attrs.get<SUMOReal>(SUMO_ATTR_LENGTH, id.c_str(), ok);
194  std::string allow = attrs.getOpt<std::string>(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
195  std::string disallow = attrs.getOpt<std::string>(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
196  if (!ok) {
197  return;
198  }
199  // get the length
200  // get the vehicle classes
201  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
202  if (permissions != SVCFreeForAll) {
204  }
205  // add when both values are valid
206  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
207  myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, permissions));
208  }
209 }
210 
211 
212 void
214  bool ok = true;
215  // get the id, report an error if not given or empty...
216  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
217  if (!ok) {
218  return;
219  }
220  // get the position of the node
221  SUMOReal x = attrs.get<SUMOReal>(SUMO_ATTR_X, id.c_str(), ok);
222  SUMOReal y = attrs.get<SUMOReal>(SUMO_ATTR_Y, id.c_str(), ok);
223  if (ok) {
224  RONode* n = myNet.getNode(id);
225  if (n == 0) {
226  n = new RONode(id);
227  myNet.addNode(n);
228  }
229  n->setPosition(Position(x, y));
230  } else {
231  throw ProcessError();
232  }
233 }
234 
235 
236 void
238  bool ok = true;
239  std::string fromID = attrs.get<std::string>(SUMO_ATTR_FROM, 0, ok);
240  std::string toID = attrs.get<std::string>(SUMO_ATTR_TO, 0, ok);
241  std::string dir = attrs.get<std::string>(SUMO_ATTR_DIR, 0, ok);
242  if (fromID[0] == ':') { // skip inner lane connections
243  return;
244  }
245  ROEdge* from = myNet.getEdge(fromID);
246  ROEdge* to = myNet.getEdge(toID);
247  if (from == 0) {
248  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
249  }
250  if (to == 0) {
251  throw ProcessError("unknown to-edge '" + toID + "' in connection");
252  }
253  from->addFollower(to, dir);
254 }
255 
256 
257 void
259  bool ok = true;
261  // get the id, throw if not given or empty...
262  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, "busStop", ok);
263  // get the lane
264  stop->lane = attrs.get<std::string>(SUMO_ATTR_LANE, "busStop", ok);
265  if (!ok) {
266  throw ProcessError();
267  }
268  const ROEdge* edge = myNet.getEdge(stop->lane.substr(0, stop->lane.rfind("_")));
269  if (edge == 0) {
270  throw InvalidArgument("Unknown lane '" + stop->lane + "' for bus stop '" + id + "'.");
271  }
272  // get the positions
273  stop->startPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_STARTPOS, id.c_str(), ok, 0);
274  stop->endPos = attrs.getOpt<SUMOReal>(SUMO_ATTR_ENDPOS, id.c_str(), ok, edge->getLength());
275  const bool friendlyPos = attrs.getOpt<bool>(SUMO_ATTR_FRIENDLY_POS, id.c_str(), ok, false);
276  if (!ok || !SUMORouteHandler::checkStopPos(stop->startPos, stop->endPos, edge->getLength(), POSITION_EPS, friendlyPos)) {
277  throw InvalidArgument("Invalid position for bus stop '" + id + "'.");
278  }
279  myNet.addBusStop(id, stop);
280 }
281 
282 
283 void
285  myCurrentEdge = 0;
286  bool ok = true;
287  myCurrentName = attrs.get<std::string>(SUMO_ATTR_ID, 0, ok);
288  if (!ok) {
289  return;
290  }
291  ROEdge* sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", 0, 0, 0);
293  myNet.addEdge(sink);
294  ROEdge* source = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0, 0);
295  source->setType(ROEdge::ET_DISTRICT);
296  myNet.addEdge(source);
297  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
298  std::vector<std::string> desc = attrs.getStringVector(SUMO_ATTR_EDGES);
299  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
300  ROEdge* edge = myNet.getEdge(*i);
301  // check whether the edge exists
302  if (edge == 0) {
303  throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
304  }
305  source->addFollower(edge);
306  edge->addFollower(sink);
307  }
308  }
309 }
310 
311 
312 void
314  bool ok = true;
315  std::string id = attrs.get<std::string>(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
316  ROEdge* succ = myNet.getEdge(id);
317  if (succ != 0) {
318  // connect edge
319  if (isSource) {
320  myNet.getEdge(myCurrentName + "-source")->addFollower(succ);
321  } else {
322  succ->addFollower(myNet.getEdge(myCurrentName + "-sink"));
323  }
324  } else {
325  WRITE_ERROR("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
326  }
327 }
328 
329 
330 
331 /****************************************************************************/
332