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 
63 
65 
66 
67 void
69  const SUMOSAXAttributes& attrs) {
70  switch (element) {
71  case SUMO_TAG_EDGE:
72  // in the first step, we do need the name to allocate the edge
73  // in the second, we need it to know to which edge we have to add
74  // the following edges to
75  parseEdge(attrs);
76  break;
77  case SUMO_TAG_LANE:
78  if (myProcess) {
79  parseLane(attrs);
80  }
81  break;
82  case SUMO_TAG_JUNCTION:
83  parseJunction(attrs);
84  break;
86  parseConnection(attrs);
87  break;
88  case SUMO_TAG_TAZ:
89  parseDistrict(attrs);
90  break;
91  case SUMO_TAG_TAZSOURCE:
92  parseDistrictEdge(attrs, true);
93  break;
94  case SUMO_TAG_TAZSINK:
95  parseDistrictEdge(attrs, false);
96  break;
97  default:
98  break;
99  }
100 }
101 
102 
103 void
105  // get the id, report an error if not given or empty...
106  bool ok = true;
108  if (!ok) {
109  throw ProcessError();
110  }
111  // get the edge
112  myCurrentEdge = 0;
113  if (myCurrentName[0] == ':') {
114  // this is an internal edge - we will not use it
115  // !!! recheck this; internal edges may be of importance during the dua
116  return;
117  }
118  std::string from = attrs.getStringReporting(SUMO_ATTR_FROM, myCurrentName.c_str(), ok);
119  std::string to = attrs.getStringReporting(SUMO_ATTR_TO, myCurrentName.c_str(), ok);
120  std::string type = attrs.hasAttribute(SUMO_ATTR_FUNCTION) ? attrs.getStringReporting(SUMO_ATTR_FUNCTION, myCurrentName.c_str(), ok) : "";
121  if (!ok) {
122  return;
123  }
124  RONode* fromNode = myNet.getNode(from);
125  if (fromNode == 0) {
126  fromNode = new RONode(from);
127  myNet.addNode(fromNode);
128  }
129  RONode* toNode = myNet.getNode(to);
130  if (toNode == 0) {
131  toNode = new RONode(to);
132  myNet.addNode(toNode);
133  }
134  // build the edge
135  myCurrentEdge = myEdgeBuilder.buildEdge(myCurrentName, fromNode, toNode);
136  if (myNet.addEdge(myCurrentEdge)) {
137  // get the type of the edge
138  myProcess = true;
139  if (type == "" || type == "normal" || type == "connector") {
141  } else if (type == "source") {
143  } else if (type == "sink") {
145  } else if (type == "internal") {
146  myProcess = false;
147  } else {
148  WRITE_ERROR("Edge '" + myCurrentName + "' has an unknown type.");
149  return;
150  }
151  } else {
152  myCurrentEdge = 0;
153  }
154 }
155 
156 
157 void
159  if (myCurrentEdge == 0) {
160  // was an internal edge to skip or an error occured
161  return;
162  }
163  bool ok = true;
164  // get the id, report an error if not given or empty...
165  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
166  if (!ok) {
167  return;
168  }
169  // get the speed
170  SUMOReal maxSpeed = attrs.getSUMORealReporting(SUMO_ATTR_SPEED, id.c_str(), ok);
171  SUMOReal length = attrs.getSUMORealReporting(SUMO_ATTR_LENGTH, id.c_str(), ok);
172  std::string allow = attrs.getOptStringReporting(SUMO_ATTR_ALLOW, id.c_str(), ok, "");
173  std::string disallow = attrs.getOptStringReporting(SUMO_ATTR_DISALLOW, id.c_str(), ok, "");
174  if (!ok) {
175  return;
176  }
177  // get the length
178  // get the vehicle classes
179  SVCPermissions permissions = parseVehicleClasses(allow, disallow);
180  if (permissions != SVCFreeForAll) {
182  }
183  // add when both values are valid
184  if (maxSpeed > 0 && length > 0 && id.length() > 0) {
185  myCurrentEdge->addLane(new ROLane(id, length, maxSpeed, permissions));
186  }
187 }
188 
189 
190 void
192  bool ok = true;
193  // get the id, report an error if not given or empty...
194  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, 0, ok);
195  if (!ok) {
196  return;
197  }
198  // get the position of the node
199  SUMOReal x = attrs.getSUMORealReporting(SUMO_ATTR_X, id.c_str(), ok);
200  SUMOReal y = attrs.getSUMORealReporting(SUMO_ATTR_Y, id.c_str(), ok);
201  if (ok) {
202  RONode* n = myNet.getNode(id);
203  if (n == 0) {
204  n = new RONode(id);
205  myNet.addNode(n);
206  }
207  n->setPosition(Position(x, y));
208  } else {
209  throw ProcessError();
210  }
211 }
212 
213 
214 void
216  bool ok = true;
217  std::string fromID = attrs.getStringReporting(SUMO_ATTR_FROM, 0, ok);
218  std::string toID = attrs.getStringReporting(SUMO_ATTR_TO, 0, ok);
219  std::string dir = attrs.getStringReporting(SUMO_ATTR_DIR, 0, ok);
220  if (fromID[0] == ':') { // skip inner lane connections
221  return;
222  }
223  ROEdge* from = myNet.getEdge(fromID);
224  ROEdge* to = myNet.getEdge(toID);
225  if (from == 0) {
226  throw ProcessError("unknown from-edge '" + fromID + "' in connection");
227  }
228  if (to == 0) {
229  throw ProcessError("unknown to-edge '" + toID + "' in connection");
230  }
231  from->addFollower(to, dir);
232 }
233 
234 
235 void
237  myCurrentEdge = 0;
238  bool ok = true;
240  if (!ok) {
241  return;
242  }
243  ROEdge* sink = myEdgeBuilder.buildEdge(myCurrentName + "-sink", 0, 0);
245  myNet.addEdge(sink);
246  ROEdge* source = myEdgeBuilder.buildEdge(myCurrentName + "-source", 0, 0);
247  source->setType(ROEdge::ET_DISTRICT);
248  myNet.addEdge(source);
249  if (attrs.hasAttribute(SUMO_ATTR_EDGES)) {
250  std::vector<std::string> desc = StringTokenizer(attrs.getString(SUMO_ATTR_EDGES)).getVector();
251  for (std::vector<std::string>::const_iterator i = desc.begin(); i != desc.end(); ++i) {
252  ROEdge* edge = myNet.getEdge(*i);
253  // check whether the edge exists
254  if (edge == 0) {
255  throw ProcessError("The edge '" + *i + "' within district '" + myCurrentName + "' is not known.");
256  }
257  source->addFollower(edge);
258  edge->addFollower(sink);
259  }
260  }
261 }
262 
263 
264 void
266  bool ok = true;
267  std::string id = attrs.getStringReporting(SUMO_ATTR_ID, myCurrentName.c_str(), ok);
268  ROEdge* succ = myNet.getEdge(id);
269  if (succ != 0) {
270  // connect edge
271  if (isSource) {
272  myNet.getEdge(myCurrentName + "-source")->addFollower(succ);
273  } else {
274  succ->addFollower(myNet.getEdge(myCurrentName + "-sink"));
275  }
276  } else {
277  WRITE_ERROR("At district '" + myCurrentName + "': succeeding edge '" + id + "' does not exist.");
278  }
279 }
280 
281 
282 
283 /****************************************************************************/
284