SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NBAlgorithms_Ramps.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // Algorithms for highway on-/off-ramps computation
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
10 // Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <cassert>
34 #include "NBNetBuilder.h"
35 #include "NBNodeCont.h"
36 #include "NBNode.h"
37 #include "NBEdge.h"
38 #include "NBAlgorithms_Ramps.h"
39 
40 #ifdef CHECK_MEMORY_LEAKS
41 #include <foreign/nvwa/debug_new.h>
42 #endif // CHECK_MEMORY_LEAKS
43 
44 
45 // ===========================================================================
46 // static members
47 // ===========================================================================
48 const std::string NBRampsComputer::ADDED_ON_RAMP_EDGE("-AddedOnRampEdge");
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 // ---------------------------------------------------------------------------
54 // NBRampsComputer
55 // ---------------------------------------------------------------------------
56 void
58  SUMOReal minHighwaySpeed = oc.getFloat("ramps.min-highway-speed");
59  SUMOReal maxRampSpeed = oc.getFloat("ramps.max-ramp-speed");
60  SUMOReal rampLength = oc.getFloat("ramps.ramp-length");
61  bool dontSplit = oc.getBool("ramps.no-split");
62  std::set<NBEdge*> incremented;
63  // check whether on-off ramps shall be guessed
64  if (oc.getBool("ramps.guess")) {
65  NBNodeCont& nc = nb.getNodeCont();
66  NBEdgeCont& ec = nb.getEdgeCont();
68  std::set<NBNode*> potOnRamps;
69  std::set<NBNode*> potOffRamps;
70  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
71  NBNode* cur = (*i).second;
72  if (mayNeedOnRamp(cur, minHighwaySpeed, maxRampSpeed)) {
73  potOnRamps.insert(cur);
74  }
75  if (mayNeedOffRamp(cur, minHighwaySpeed, maxRampSpeed)) {
76  potOffRamps.insert(cur);
77  }
78  }
79  for (std::set<NBNode*>::const_iterator i = potOnRamps.begin(); i != potOnRamps.end(); ++i) {
80  buildOnRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
81  }
82  for (std::set<NBNode*>::const_iterator i = potOffRamps.begin(); i != potOffRamps.end(); ++i) {
83  buildOffRamp(*i, nc, ec, dc, rampLength, dontSplit, incremented);
84  }
85  }
86  // check whether on-off ramps shall be guessed
87  if (oc.isSet("ramps.set")) {
88  std::vector<std::string> edges = oc.getStringVector("ramps.set");
89  NBNodeCont& nc = nb.getNodeCont();
90  NBEdgeCont& ec = nb.getEdgeCont();
92  for (std::vector<std::string>::iterator i = edges.begin(); i != edges.end(); ++i) {
93  NBEdge* e = ec.retrieve(*i);
94  if (e == 0) {
95  WRITE_WARNING("Can not build on ramp on edge '" + *i + "' - the edge is not known.");
96  continue;
97  }
98  NBNode* from = e->getFromNode();
99  if (from->getIncomingEdges().size() == 2 && from->getOutgoingEdges().size() == 1) {
100  buildOnRamp(from, nc, ec, dc, rampLength, dontSplit, incremented);
101  }
102  // load edge again to check offramps
103  e = ec.retrieve(*i);
104  if (e == 0) {
105  WRITE_WARNING("Can not build off ramp on edge '" + *i + "' - the edge is not known.");
106  continue;
107  }
108  NBNode* to = e->getToNode();
109  if (to->getIncomingEdges().size() == 1 && to->getOutgoingEdges().size() == 2) {
110  buildOffRamp(to, nc, ec, dc, rampLength, dontSplit, incremented);
111  }
112  }
113  }
114 }
115 
116 
117 bool
118 NBRampsComputer::mayNeedOnRamp(NBNode* cur, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed) {
119  if (cur->getOutgoingEdges().size() != 1 || cur->getIncomingEdges().size() != 2) {
120  return false;
121  }
122  NBEdge* potHighway, *potRamp, *cont;
123  getOnRampEdges(cur, &potHighway, &potRamp, &cont);
124  // may be an on-ramp
125  return fulfillsRampConstraints(potHighway, potRamp, cont, minHighwaySpeed, maxRampSpeed);
126 }
127 
128 
129 bool
130 NBRampsComputer::mayNeedOffRamp(NBNode* cur, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed) {
131  if (cur->getIncomingEdges().size() != 1 || cur->getOutgoingEdges().size() != 2) {
132  return false;
133  }
134  // may be an off-ramp
135  NBEdge* potHighway, *potRamp, *prev;
136  getOffRampEdges(cur, &potHighway, &potRamp, &prev);
137  return fulfillsRampConstraints(potHighway, potRamp, prev, minHighwaySpeed, maxRampSpeed);
138 }
139 
140 
141 void
142 NBRampsComputer::buildOnRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, SUMOReal rampLength, bool dontSplit, std::set<NBEdge*>& incremented) {
143  NBEdge* potHighway, *potRamp, *cont;
144  getOnRampEdges(cur, &potHighway, &potRamp, &cont);
145  // compute the number of lanes to append
146  const unsigned int firstLaneNumber = potHighway->getNumLanes();
147  int toAdd = (potRamp->getNumLanes() + firstLaneNumber) - cont->getNumLanes();
148  NBEdge* first = cont;
149  NBEdge* last = cont;
150  NBEdge* curr = cont;
151  if (toAdd > 0 && find(incremented.begin(), incremented.end(), cont) == incremented.end()) {
152  SUMOReal currLength = 0;
153  while (curr != 0 && currLength + curr->getGeometry().length() - POSITION_EPS < rampLength) {
154  if (find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
155  curr->incLaneNo(toAdd);
156  curr->invalidateConnections(true);
157  incremented.insert(curr);
158  moveRampRight(curr, toAdd);
159  currLength += curr->getLength(); // !!! loaded length?
160  last = curr;
161  }
162  NBNode* nextN = curr->getToNode();
163  if (nextN->getOutgoingEdges().size() == 1) {
164  curr = nextN->getOutgoingEdges()[0];
165  if (curr->getNumLanes() != firstLaneNumber) {
166  // the number of lanes changes along the computation; we'll stop...
167  curr = 0;
168  } else if (curr->isTurningDirectionAt(nextN, last)) {
169  // turnarounds certainly should not be included in a ramp
170  curr = 0;
171  } else if (curr == potHighway || curr == potRamp) {
172  // circular connectivity. do not split!
173  curr = 0;
174  }
175  } else {
176  // ambigous; and, in fact, what should it be? ...stop
177  curr = 0;
178  }
179  }
180  // check whether a further split is necessary
181  if (curr != 0 && !dontSplit && currLength - POSITION_EPS < rampLength && curr->getNumLanes() == firstLaneNumber && find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
182  // there is enough place to build a ramp; do it
183  bool wasFirst = first == curr;
184  NBNode* rn = new NBNode(curr->getID() + "-AddedOnRampNode", curr->getGeometry().positionAtOffset(rampLength - currLength));
185  if (!nc.insert(rn)) {
186  throw ProcessError("Ups - could not build on-ramp for edge '" + curr->getID() + "' (node could not be build)!");
187  }
188  std::string name = curr->getID();
189  bool ok = ec.splitAt(dc, curr, rn, curr->getID() + ADDED_ON_RAMP_EDGE, curr->getID(), curr->getNumLanes() + toAdd, curr->getNumLanes());
190  if (!ok) {
191  WRITE_ERROR("Ups - could not build on-ramp for edge '" + curr->getID() + "'!");
192  return;
193  }
194  //ec.retrieve(name)->invalidateConnections();
195  curr = ec.retrieve(name + ADDED_ON_RAMP_EDGE);
196  curr->invalidateConnections(true);
197  incremented.insert(curr);
198  last = curr;
199  moveRampRight(curr, toAdd);
200  if (wasFirst) {
201  first = curr;
202  }
203  }
204  if (curr == cont && dontSplit) {
205  WRITE_WARNING("Could not build on-ramp for edge '" + curr->getID() + "' due to option '--ramps.no-split'");
206  return;
207  }
208  }
209  // set connections from ramp/highway to added ramp
210  if (!potHighway->addLane2LaneConnections(0, first, potRamp->getNumLanes(), MIN2(first->getNumLanes() - potRamp->getNumLanes(), potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true, true)) {
211  throw ProcessError("Could not set connection!");
212  }
213  if (!potRamp->addLane2LaneConnections(0, first, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, true, true)) {
214  throw ProcessError("Could not set connection!");
215  }
216  // patch ramp geometry
217  PositionVector p = potRamp->getGeometry();
218  p.pop_back();
219  p.push_back(first->getLaneShape(0)[0]);
220  potRamp->setGeometry(p);
221  // set connections from added ramp to following highway
222  NBNode* nextN = last->getToNode();
223  if (nextN->getOutgoingEdges().size() == 1) {
224  NBEdge* next = nextN->getOutgoingEdges()[0];//const EdgeVector& o1 = cont->getToNode()->getOutgoingEdges();
225  if (next->getNumLanes() < last->getNumLanes()) {
226  last->addLane2LaneConnections(last->getNumLanes() - next->getNumLanes(), next, 0, next->getNumLanes(), NBEdge::L2L_VALIDATED);
227  }
228  }
229 }
230 
231 
232 void
233 NBRampsComputer::buildOffRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, SUMOReal rampLength, bool dontSplit, std::set<NBEdge*>& incremented) {
234  NBEdge* potHighway, *potRamp, *prev;
235  getOffRampEdges(cur, &potHighway, &potRamp, &prev);
236  // compute the number of lanes to append
237  const unsigned int firstLaneNumber = potHighway->getNumLanes();
238  int toAdd = (potRamp->getNumLanes() + firstLaneNumber) - prev->getNumLanes();
239  NBEdge* first = prev;
240  NBEdge* last = prev;
241  NBEdge* curr = prev;
242  if (toAdd > 0 && find(incremented.begin(), incremented.end(), prev) == incremented.end()) {
243  SUMOReal currLength = 0;
244  while (curr != 0 && currLength + curr->getGeometry().length() - POSITION_EPS < rampLength) {
245  if (find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
246  curr->incLaneNo(toAdd);
247  curr->invalidateConnections(true);
248  incremented.insert(curr);
249  moveRampRight(curr, toAdd);
250  currLength += curr->getLength(); // !!! loaded length?
251  last = curr;
252  }
253  NBNode* prevN = curr->getFromNode();
254  if (prevN->getIncomingEdges().size() == 1) {
255  curr = prevN->getIncomingEdges()[0];
256  if (curr->getNumLanes() != firstLaneNumber) {
257  // the number of lanes changes along the computation; we'll stop...
258  curr = 0;
259  } else if (last->isTurningDirectionAt(prevN, curr)) {
260  // turnarounds certainly should not be included in a ramp
261  curr = 0;
262  } else if (curr == potHighway || curr == potRamp) {
263  // circular connectivity. do not split!
264  curr = 0;
265  }
266  } else {
267  // ambigous; and, in fact, what should it be? ...stop
268  curr = 0;
269  }
270  }
271  // check whether a further split is necessary
272  if (curr != 0 && !dontSplit && currLength - POSITION_EPS < rampLength && curr->getNumLanes() == firstLaneNumber && find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
273  // there is enough place to build a ramp; do it
274  bool wasFirst = first == curr;
275  Position pos = curr->getGeometry().positionAtOffset(curr->getGeometry().length() - (rampLength - currLength));
276  NBNode* rn = new NBNode(curr->getID() + "-AddedOffRampNode", pos);
277  if (!nc.insert(rn)) {
278  throw ProcessError("Ups - could not build on-ramp for edge '" + curr->getID() + "' (node could not be build)!");
279  }
280  std::string name = curr->getID();
281  bool ok = ec.splitAt(dc, curr, rn, curr->getID(), curr->getID() + "-AddedOffRampEdge", curr->getNumLanes(), curr->getNumLanes() + toAdd);
282  if (!ok) {
283  WRITE_ERROR("Ups - could not build on-ramp for edge '" + curr->getID() + "'!");
284  return;
285  }
286  curr = ec.retrieve(name + "-AddedOffRampEdge");
287  curr->invalidateConnections(true);
288  incremented.insert(curr);
289  last = curr;
290  moveRampRight(curr, toAdd);
291  if (wasFirst) {
292  first = curr;
293  }
294  }
295  if (curr == prev && dontSplit) {
296  WRITE_WARNING("Could not build off-ramp for edge '" + curr->getID() + "' due to option '--ramps.no-split'");
297  return;
298  }
299  }
300  // set connections from added ramp to ramp/highway
301  if (!first->addLane2LaneConnections(potRamp->getNumLanes(), potHighway, 0, MIN2(first->getNumLanes() - 1, potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true)) {
302  throw ProcessError("Could not set connection!");
303  }
304  if (!first->addLane2LaneConnections(0, potRamp, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, false)) {
305  throw ProcessError("Could not set connection!");
306  }
307  // patch ramp geometry
308  PositionVector p = potRamp->getGeometry();
309  p.pop_front();
310  p.push_front(first->getLaneShape(0)[-1]);
311  potRamp->setGeometry(p);
312  // set connections from previous highway to added ramp
313  NBNode* prevN = last->getFromNode();
314  if (prevN->getIncomingEdges().size() == 1) {
315  NBEdge* prev = prevN->getIncomingEdges()[0];//const EdgeVector& o1 = cont->getToNode()->getOutgoingEdges();
316  if (prev->getNumLanes() < last->getNumLanes()) {
317  last->addLane2LaneConnections(last->getNumLanes() - prev->getNumLanes(), last, 0, prev->getNumLanes(), NBEdge::L2L_VALIDATED);
318  }
319  }
320 }
321 
322 
323 void
324 NBRampsComputer::moveRampRight(NBEdge* ramp, int addedLanes) {
325  if (ramp->getLaneSpreadFunction() != LANESPREAD_CENTER) {
326  return;
327  }
328  try {
329  PositionVector g = ramp->getGeometry();
330  SUMOReal factor = SUMO_const_laneWidthAndOffset * (SUMOReal)(addedLanes - 1) + SUMO_const_halfLaneAndOffset * (SUMOReal)(addedLanes % 2);
331  g.move2side(factor);
332  ramp->setGeometry(g);
333  } catch (InvalidArgument&) {
334  WRITE_WARNING("For edge '" + ramp->getID() + "': could not compute shape.");
335  }
336 }
337 
338 
339 bool
341  if (fabs((*potHighway)->getSpeed() - (*potRamp)->getSpeed()) < .1) {
342  return false;
343  }
344  if ((*potHighway)->getSpeed() < (*potRamp)->getSpeed()) {
345  std::swap(*potHighway, *potRamp);
346  }
347  return true;
348 }
349 
350 
351 bool
353  if ((*potHighway)->getNumLanes() == (*potRamp)->getNumLanes()) {
354  return false;
355  }
356  if ((*potHighway)->getNumLanes() < (*potRamp)->getNumLanes()) {
357  std::swap(*potHighway, *potRamp);
358  }
359  return true;
360 }
361 
362 
363 void
364 NBRampsComputer::getOnRampEdges(NBNode* n, NBEdge** potHighway, NBEdge** potRamp, NBEdge** other) {
365  *other = n->getOutgoingEdges()[0];
366  const std::vector<NBEdge*>& edges = n->getIncomingEdges();
367  assert(edges.size() == 2);
368  *potHighway = edges[0];
369  *potRamp = edges[1];
370  /*
371  // heuristic: highway is faster than ramp
372  if(determinedBySpeed(potHighway, potRamp)) {
373  return;
374  }
375  // heuristic: highway has more lanes than ramp
376  if(determinedByLaneNumber(potHighway, potRamp)) {
377  return;
378  }
379  */
380  // heuristic: ramp comes from right
381  const std::vector<NBEdge*>& edges2 = n->getEdges();
382  std::vector<NBEdge*>::const_iterator i = std::find(edges2.begin(), edges2.end(), *other);
383  NBContHelper::nextCW(edges2, i);
384  if ((*i) == *potHighway) {
385  std::swap(*potHighway, *potRamp);
386  }
387 }
388 
389 
390 void
391 NBRampsComputer::getOffRampEdges(NBNode* n, NBEdge** potHighway, NBEdge** potRamp, NBEdge** other) {
392  *other = n->getIncomingEdges()[0];
393  const std::vector<NBEdge*>& edges = n->getOutgoingEdges();
394  *potHighway = edges[0];
395  *potRamp = edges[1];
396  assert(edges.size() == 2);
397  /*
398  // heuristic: highway is faster than ramp
399  if(determinedBySpeed(potHighway, potRamp)) {
400  return;
401  }
402  // heuristic: highway has more lanes than ramp
403  if(determinedByLaneNumber(potHighway, potRamp)) {
404  return;
405  }
406  */
407  // heuristic: ramp goes to right
408  const std::vector<NBEdge*>& edges2 = n->getEdges();
409  std::vector<NBEdge*>::const_iterator i = std::find(edges2.begin(), edges2.end(), *other);
410  NBContHelper::nextCW(edges2, i);
411  if ((*i) == *potRamp) {
412  std::swap(*potHighway, *potRamp);
413  }
414 }
415 
416 
417 bool
419  NBEdge* potHighway, NBEdge* potRamp, NBEdge* other, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed) {
420  // do not build ramps on rail edges
421  if (isRailway(potHighway->getPermissions()) || isRailway(potRamp->getPermissions())) {
422  return false;
423  }
424  // do not build ramps on connectors
425  if (potHighway->isMacroscopicConnector() || potRamp->isMacroscopicConnector() || other->isMacroscopicConnector()) {
426  return false;
427  }
428  // check whether a lane is missing
429  if (potHighway->getNumLanes() + potRamp->getNumLanes() <= other->getNumLanes()) {
430  return false;
431  }
432  // is it really a highway?
433  SUMOReal maxSpeed = MAX3(potHighway->getSpeed(), other->getSpeed(), potRamp->getSpeed());
434  if (maxSpeed < minHighwaySpeed) {
435  return false;
436  }
437  // is any of the connections a turnaround?
438  if (other->getToNode() == potHighway->getFromNode()) {
439  // off ramp
440  if (other->isTurningDirectionAt(other->getToNode(), potHighway) ||
441  other->isTurningDirectionAt(other->getToNode(), potRamp)) {
442  return false;
443  }
444  } else {
445  // on ramp
446  if (other->isTurningDirectionAt(other->getFromNode(), potHighway) ||
447  other->isTurningDirectionAt(other->getFromNode(), potRamp)) {
448  return false;
449  }
450  }
451  /*
452  if (potHighway->getSpeed() < minHighwaySpeed || other->getSpeed() < minHighwaySpeed) {
453  return false;
454  }
455  */
456  // is it really a ramp?
457  if (maxRampSpeed > 0 && maxRampSpeed < potRamp->getSpeed()) {
458  return false;
459  }
460  return true;
461 }
462 
463 
464 /****************************************************************************/
465 
void invalidateConnections(bool reallowSetting=false)
Definition: NBEdge.cpp:852
const PositionVector & getLaneShape(unsigned int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:478
std::vector< std::string > getStringVector(const std::string &name) const
Returns the list of string-vector-value of the named option (only for Option_String) ...
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges.
Definition: NBNode.h:170
Position positionAtOffset(SUMOReal pos) const
Returns the position at the given length.
static bool determinedBySpeed(NBEdge **potHighway, NBEdge **potRamp)
static bool mayNeedOnRamp(NBNode *cur, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed)
Determines whether the given node may be an on-ramp begin.
const SUMOReal SUMO_const_halfLaneAndOffset
Definition: StdDefs.h:50
const SUMOReal SUMO_const_laneWidthAndOffset
Definition: StdDefs.h:49
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
The representation of a single edge during network building.
Definition: NBEdge.h:71
void incLaneNo(unsigned int by)
Definition: NBEdge.cpp:1916
A container for districts.
bool addLane2LaneConnections(unsigned int fromLane, NBEdge *dest, unsigned int toLane, unsigned int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
Definition: NBEdge.cpp:639
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:397
static void moveRampRight(NBEdge *ramp, int addedLanes)
Moves the ramp to the right, as new lanes were added.
SUMOReal getFloat(const std::string &name) const
Returns the SUMOReal-value of the named option (only for Option_Float)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool isTurningDirectionAt(const NBNode *n, const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:1597
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge's geometry
Definition: NBEdge.cpp:381
T MAX3(T a, T b, T c)
Definition: StdDefs.h:85
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:196
static void buildOnRamp(NBNode *cur, NBNodeCont &nc, NBEdgeCont &ec, NBDistrictCont &dc, SUMOReal rampLength, bool dontSplit, std::set< NBEdge * > &incremented)
Builds an on-ramp starting at the given node.
The connection was computed and validated.
Definition: NBEdge.h:116
static bool determinedByLaneNumber(NBEdge **potHighway, NBEdge **potRamp)
static const std::string ADDED_ON_RAMP_EDGE
suffix for newly generated on-ramp edges
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges.
Definition: NBNode.h:178
const std::string & getID() const
Returns the id.
Definition: Named.h:60
static void buildOffRamp(NBNode *cur, NBNodeCont &nc, NBEdgeCont &ec, NBDistrictCont &dc, SUMOReal rampLength, bool dontSplit, std::set< NBEdge * > &incremented)
Builds an off-ramp ending at the given node.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
Position pop_front()
Removes and returns the position at the fron of the list.
NBEdgeCont & getEdgeCont()
Returns the edge container.
Definition: NBNetBuilder.h:154
A list of positions.
void push_front(const Position &p)
Puts the given position at the front of the list.
unsigned int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:338
const EdgeVector & getEdges() const
Returns all edges which participate in this node.
Definition: NBNode.h:186
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
T MIN2(T a, T b)
Definition: StdDefs.h:65
#define POSITION_EPS
Definition: config.h:186
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:142
static bool mayNeedOffRamp(NBNode *cur, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed)
Determines whether the given node may be an off-ramp end.
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:201
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2093
SUMOReal length() const
Returns the length.
static bool fulfillsRampConstraints(NBEdge *potHighway, NBEdge *potRamp, NBEdge *other, SUMOReal minHighwaySpeed, SUMOReal maxRampSpeed)
Checks whether an on-/off-ramp can be bult here.
void push_back(const PositionVector &p)
Appends all positions from the given vector.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:362
static void computeRamps(NBNetBuilder &nb, OptionsCont &oc)
Computes highway on-/off-ramps (if wished)
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
static void getOffRampEdges(NBNode *n, NBEdge **potHighway, NBEdge **potRamp, NBEdge **other)
NBNodeCont & getNodeCont()
Returns the node container.
Definition: NBNetBuilder.h:162
Instance responsible for building networks.
Definition: NBNetBuilder.h:113
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:499
bool isMacroscopicConnector() const
Returns whether this edge was marked as a macroscopic connector.
Definition: NBEdge.h:813
A storage for options typed value containers)
Definition: OptionsCont.h:108
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:79
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge's lanes' lateral offset is computed.
Definition: NBEdge.h:575
Represents a single node (junction) during network building.
Definition: NBNode.h:74
static void getOnRampEdges(NBNode *n, NBEdge **potHighway, NBEdge **potRamp, NBEdge **other)
void move2side(SUMOReal amount)
#define SUMOReal
Definition: config.h:215
SUMOReal getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:422
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:64
NBDistrictCont & getDistrictCont()
Returns the districts container.
Definition: NBNetBuilder.h:186
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:134
SUMOReal getLength() const
Returns the computed length of the edge.
Definition: NBEdge.h:397
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:354