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 /****************************************************************************/
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