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.sourceforge.net/
13 // Copyright (C) 2001-2012 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>
42 #include "ROEdge.h"
43 #include "ROLane.h"
44 #include "RONode.h"
45 #include "RONet.h"
46 #include "RONetHandler.h"
47 #include "ROAbstractEdgeBuilder.h"
48 
49 #ifdef CHECK_MEMORY_LEAKS
50 #include <foreign/nvwa/debug_new.h>
51 #endif // CHECK_MEMORY_LEAKS
52 
53 
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
59  : SUMOSAXHandler("sumo-network"),
60  myNet(net), myCurrentName(),
61  myCurrentEdge(0), myEdgeBuilder(eb),
62  myHaveWarnedAboutDeprecatedDistrict(false), myHaveWarnedAboutDeprecatedDSource(false), myHaveWarnedAboutDeprecatedDSink(false) {}
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;
86  case SUMO_TAG_SUCC:
87  parseConnectingEdge(attrs);
88  break;
89  case SUMO_TAG_SUCCLANE:
90  parseConnectedEdge(attrs);
91  break;
93  parseConnection(attrs);
94  break;
98  WRITE_WARNING("'" + toString(SUMO_TAG_DISTRICT__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZ) + "'.");
99  }
100  case SUMO_TAG_TAZ:
101  parseDistrict(attrs);
102  break;
106  WRITE_WARNING("'" + toString(SUMO_TAG_DSOURCE__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSOURCE) + "'.");
107  }
108  case SUMO_TAG_TAZSOURCE:
109  parseDistrictEdge(attrs, true);
110  break;
114  WRITE_WARNING("'" + toString(SUMO_TAG_DSINK__DEPRECATED) + "' is deprecated, please use '" + toString(SUMO_TAG_TAZSINK) + "'.");
115  }
116  case SUMO_TAG_TAZSINK:
117  parseDistrictEdge(attrs, false);
118  break;
119  default:
120  break;
121  }
122 }
123 
124 
125 void
127  // get the id, report an error if not given or empty...
128  bool ok = true;
130  if (!ok) {
131  throw ProcessError();
132  }
133  // get the edge
134  myCurrentEdge = 0;
135  if (myCurrentName[0] == ':') {
136  // this is an internal edge - we will not use it
137  // !!! recheck this; internal edges may be of importance during the dua
138  return;
139  }
140  std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
141  std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
142  std::string type = attrs.hasAttribute(SUMO_ATTR_FUNCTION) ? attrs.getStringReporting(SUMO_ATTR_FUNCTION, myCurrentName.c_str(), ok) : "";
143  if (!ok) {
144  return;
145  }
146  RONode* fromNode = myNet.getNode(from);
147  if (fromNode == 0) {
148  fromNode = new RONode(from);
149  myNet.addNode(fromNode);
150  }
151  RONode* toNode = myNet.getNode(to);
152  if (toNode == 0) {
153  toNode = new RONode(to);
154  myNet.addNode(toNode);
155  }
156  // build the edge
157  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode);
158  if (myNet.addEdge(myCurrentEdge)) {
159  // get the type of the edge
160  myProcess = true;
161  if (type == "" || type == "normal" || type == "connector") {
163  } else if (type == "source") {
165  } else if (type == "sink") {
167  } else if (type == "internal") {
168  myProcess = false;
169  } else {
170  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
171  return;
172  }
173  } else {
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.getStringReporting(SUMO_ATTR_ID, 0, ok);
188  if (!ok) {
189  return;
190  }
191  // get the speed
192  SUMOReal maxSpeed = attrs.hasAttribute(SUMO_ATTR_SPEED)
193  ? attrs.getSUMORealReporting(SUMO_ATTR_SPEED, id.c_str(), ok)
194  : attrs.getSUMORealReporting(SUMO_ATTR_MAXSPEED__DEPRECATED, id.c_str(), ok);
195  SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
196  std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
197  std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
198  if (!ok) {
199  return;
200  }
201  // get the length
202  // get the vehicle classes
203  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
204  if (permissions != SVCFreeForAll) {
206  }
207  // add when both values are valid
208  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
209  myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, permissions));
210  }
211 }
212 
213 
214 void
216  bool ok = true;
217  // get the id, report an error if not given or empty...
218  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
219  if (!ok) {
220  return;
221  }
222  // get the position of the node
223  SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
224  SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
225  if (ok) {
226  RONode* n = myNet.getNode(id);
227  if (n == 0) {
228  n = new RONode(id);
229  myNet.addNode(n);
230  }
231  n->setPosition(Position(x, y));
232  } else {
233  throw ProcessError();
234  }
235 }
236 
237 
238 void
240  bool ok = true;
241  std::string id = attrs.getStringReporting(SUMO_ATTR_EDGE, 0, ok);
242  if (id[0] == ':') {
243  myCurrentEdge = 0;
244  return;
245  }
247  if (myCurrentEdge == 0) {
248  throw ProcessError("An unknown edge occured (id='" + id + "').");
249  }
250 }
251 
252 
253 void
255  if (myCurrentEdge == 0) {
256  // earlier error or internal link
257  return;
258  }
259  bool ok = true;
260  std::string id = attrs.getStringReporting(SUMO_ATTR_LANE, myCurrentName.c_str(), ok);
261  if (id == "SUMO_NO_DESTINATION") {
262  return;
263  }
264  ROEdge* succ = myNet.getEdge(id.substr(0, id.rfind('_')));
265  if (succ != 0) {
266  // connect edge
267  myCurrentEdge->addFollower(succ);
268  } else {
269  WRITE_ERROR("At edge '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
270  }
271 }
272 
273 
274 void
276  bool ok = true;
277  std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
278  std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
279  std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok);
280  if (fromID[0] == ':') { // skip inner lane connections
281  return;
282  }
283  ROEdge* from = myNet.getEdge(fromID);
284  ROEdge* to = myNet.getEdge(toID);
285  if (from == 0) {
286  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
287  }
288  if (to == 0) {
289  throw ProcessError("unknown to-edge '" + toID + "' in connection");
290  }
291  from->addFollower(to, dir);
292 }
293 
294 
295 void
297  myCurrentEdge = 0;
298  bool ok = true;
300  if (!ok) {
301  return;
302  }
303  ROEdge* sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", 0, 0);
305  myNet.addEdge(sink);
306  ROEdge* source = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0);
307  source->setType(ROEdge::ET_DISTRICT);
308  myNet.addEdge(source);
309  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
310  std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
311  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
312  ROEdge* edge = myNet.getEdge(*i);
313  // check whether the edge exists
314  if (edge == 0) {
315  throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
316  }
317  source->addFollower(edge);
318  edge->addFollower(sink);
319  }
320  }
321 }
322 
323 
324 void
326  bool ok = true;
327  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
328  ROEdge* succ = myNet.getEdge(id);
329  if (succ != 0) {
330  // connect edge
331  if (isSource) {
332  myNet.getEdge(myCurrentName + "-source")->addFollower(succ);
333  } else {
334  succ->addFollower(myNet.getEdge(myCurrentName + "-sink"));
335  }
336  } else {
337  WRITE_ERROR("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
338  }
339 }
340 
341 
342 
343 /****************************************************************************/
344