SUMO - Simulation of Urban MObility
NBAlgorithms_Ramps.cpp
Go to the documentation of this file.
1 /****************************************************************************/
9 // Algorithms for highway on-/off-ramps computation
10 /****************************************************************************/
11 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
12 // Copyright (C) 2012-2017 DLR (http://www.dlr.de/) and contributors
13 /****************************************************************************/
14 //
15 // This file is part of SUMO.
16 // SUMO is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <cassert>
36 #include <utils/common/ToString.h>
37 #include "NBNetBuilder.h"
38 #include "NBNodeCont.h"
39 #include "NBNode.h"
40 #include "NBEdge.h"
41 #include "NBAlgorithms_Ramps.h"
42 
43 
44 // ===========================================================================
45 // static members
46 // ===========================================================================
47 const std::string NBRampsComputer::ADDED_ON_RAMP_EDGE("-AddedOnRampEdge");
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 // ---------------------------------------------------------------------------
53 // NBRampsComputer
54 // ---------------------------------------------------------------------------
55 void
57  double minHighwaySpeed = oc.getFloat("ramps.min-highway-speed");
58  double maxRampSpeed = oc.getFloat("ramps.max-ramp-speed");
59  double rampLength = oc.getFloat("ramps.ramp-length");
60  bool dontSplit = oc.getBool("ramps.no-split");
61  std::set<NBEdge*> incremented;
62  // check whether on-off ramps shall be guessed
63  if (oc.getBool("ramps.guess")) {
64  NBNodeCont& nc = nb.getNodeCont();
65  NBEdgeCont& ec = nb.getEdgeCont();
67  // collect join exclusions
68  std::set<std::string> noramps;
69  if (oc.isSet("ramps.unset")) {
70  std::vector<std::string> edges = oc.getStringVector("ramps.unset");
71  noramps.insert(edges.begin(), edges.end());
72  }
73  // exclude roundabouts
74  const std::set<EdgeSet>& roundabouts = ec.getRoundabouts();
75  for (std::set<EdgeSet>::const_iterator it_round = roundabouts.begin();
76  it_round != roundabouts.end(); ++it_round) {
77  for (EdgeSet::const_iterator it_edge = it_round->begin(); it_edge != it_round->end(); ++it_edge) {
78  noramps.insert((*it_edge)->getID());
79  }
80  }
81  // if an edge is part of two ramps, ordering is important
82  std::set<NBNode*, Named::ComparatorIdLess> potOnRamps;
83  std::set<NBNode*, Named::ComparatorIdLess> potOffRamps;
84  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
85  NBNode* cur = (*i).second;
86  if (mayNeedOnRamp(cur, minHighwaySpeed, maxRampSpeed, noramps)) {
87  potOnRamps.insert(cur);
88  }
89  if (mayNeedOffRamp(cur, minHighwaySpeed, maxRampSpeed, noramps)) {
90  potOffRamps.insert(cur);
91  }
92  }
93  for (std::set<NBNode*, Named::ComparatorIdLess>::const_iterator i = potOnRamps.begin(); i != potOnRamps.end(); ++i) {
94  buildOnRamp(*i, nc, ec, dc, rampLength, dontSplit);
95  }
96  for (std::set<NBNode*, Named::ComparatorIdLess>::const_iterator i = potOffRamps.begin(); i != potOffRamps.end(); ++i) {
97  buildOffRamp(*i, nc, ec, dc, rampLength, dontSplit);
98  }
99  }
100  // check whether on-off ramps are specified
101  if (oc.isSet("ramps.set")) {
102  std::vector<std::string> edges = oc.getStringVector("ramps.set");
103  NBNodeCont& nc = nb.getNodeCont();
104  NBEdgeCont& ec = nb.getEdgeCont();
105  NBDistrictCont& dc = nb.getDistrictCont();
106  for (std::vector<std::string>::iterator i = edges.begin(); i != edges.end(); ++i) {
107  NBEdge* e = ec.retrieve(*i);
108  if (e == 0) {
109  WRITE_WARNING("Can not build on ramp on edge '" + *i + "' - the edge is not known.");
110  continue;
111  }
112  NBNode* from = e->getFromNode();
113  if (from->getIncomingEdges().size() == 2 && from->getOutgoingEdges().size() == 1) {
114  buildOnRamp(from, nc, ec, dc, rampLength, dontSplit);
115  }
116  // load edge again to check offramps
117  e = ec.retrieve(*i);
118  if (e == 0) {
119  WRITE_WARNING("Can not build off ramp on edge '" + *i + "' - the edge is not known.");
120  continue;
121  }
122  NBNode* to = e->getToNode();
123  if (to->getIncomingEdges().size() == 1 && to->getOutgoingEdges().size() == 2) {
124  buildOffRamp(to, nc, ec, dc, rampLength, dontSplit);
125  }
126  }
127  }
128 }
129 
130 
131 bool
132 NBRampsComputer::mayNeedOnRamp(NBNode* cur, double minHighwaySpeed, double maxRampSpeed, const std::set<std::string>& noramps) {
133  if (cur->getOutgoingEdges().size() != 1 || cur->getIncomingEdges().size() != 2) {
134  return false;
135  }
136  NBEdge* potHighway, *potRamp, *cont;
137  getOnRampEdges(cur, &potHighway, &potRamp, &cont);
138  // may be an on-ramp
139  return fulfillsRampConstraints(potHighway, potRamp, cont, minHighwaySpeed, maxRampSpeed, noramps);
140 }
141 
142 
143 bool
144 NBRampsComputer::mayNeedOffRamp(NBNode* cur, double minHighwaySpeed, double maxRampSpeed, const std::set<std::string>& noramps) {
145  if (cur->getIncomingEdges().size() != 1 || cur->getOutgoingEdges().size() != 2) {
146  return false;
147  }
148  // may be an off-ramp
149  NBEdge* potHighway, *potRamp, *prev;
150  getOffRampEdges(cur, &potHighway, &potRamp, &prev);
151  return fulfillsRampConstraints(potHighway, potRamp, prev, minHighwaySpeed, maxRampSpeed, noramps);
152 }
153 
154 
155 void
156 NBRampsComputer::buildOnRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, double rampLength, bool dontSplit) {
157  NBEdge* potHighway, *potRamp, *cont;
158  getOnRampEdges(cur, &potHighway, &potRamp, &cont);
159  // compute the number of lanes to append
160  const int firstLaneNumber = cont->getNumLanes();
161  int toAdd = (potRamp->getNumLanes() + potHighway->getNumLanes()) - firstLaneNumber;
162  NBEdge* first = cont;
163  NBEdge* last = cont;
164  NBEdge* curr = cont;
165  std::set<NBEdge*> incremented;
166  if (toAdd > 0 && find(incremented.begin(), incremented.end(), cont) == incremented.end()) {
167  double currLength = 0;
168  while (curr != 0 && currLength + curr->getGeometry().length() - POSITION_EPS < rampLength) {
169  if (find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
170  curr->incLaneNo(toAdd);
171  if (curr->getStep() < NBEdge::LANES2LANES_USER) {
172  curr->invalidateConnections(true);
173  }
174  incremented.insert(curr);
175  moveRampRight(curr, toAdd);
176  currLength += curr->getGeometry().length(); // !!! loaded length?
177  last = curr;
178  // mark acceleration lanes
179  for (int i = 0; i < curr->getNumLanes() - potHighway->getNumLanes(); ++i) {
180  curr->setAcceleration(i, true);
181  }
182  }
183  NBNode* nextN = curr->getToNode();
184  if (nextN->getOutgoingEdges().size() == 1) {
185  curr = nextN->getOutgoingEdges()[0];
186  if (curr->getNumLanes() != firstLaneNumber) {
187  // the number of lanes changes along the computation; we'll stop...
188  curr = 0;
189  } else if (curr->isTurningDirectionAt(last)) {
190  // turnarounds certainly should not be included in a ramp
191  curr = 0;
192  } else if (curr == potHighway || curr == potRamp) {
193  // circular connectivity. do not split!
194  curr = 0;
195  }
196  } else {
197  // ambigous; and, in fact, what should it be? ...stop
198  curr = 0;
199  }
200  }
201  // check whether a further split is necessary
202  if (curr != 0 && !dontSplit && currLength - POSITION_EPS < rampLength && curr->getNumLanes() == firstLaneNumber && find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
203  // there is enough place to build a ramp; do it
204  bool wasFirst = first == curr;
205  NBNode* rn = new NBNode(curr->getID() + "-AddedOnRampNode", curr->getGeometry().positionAtOffset(rampLength - currLength));
206  if (!nc.insert(rn)) {
207  throw ProcessError("Ups - could not build on-ramp for edge '" + curr->getID() + "' (node could not be build)!");
208  }
209  std::string name = curr->getID();
210  bool ok = ec.splitAt(dc, curr, rn, curr->getID() + ADDED_ON_RAMP_EDGE, curr->getID(), curr->getNumLanes() + toAdd, curr->getNumLanes());
211  if (!ok) {
212  WRITE_ERROR("Ups - could not build on-ramp for edge '" + curr->getID() + "'!");
213  return;
214  }
215  //ec.retrieve(name)->invalidateConnections();
216  curr = ec.retrieve(name + ADDED_ON_RAMP_EDGE);
217  incremented.insert(curr);
218  last = curr;
219  moveRampRight(curr, toAdd);
220  if (wasFirst) {
221  first = curr;
222  }
223  // mark acceleration lanes
224  for (int i = 0; i < curr->getNumLanes() - potHighway->getNumLanes(); ++i) {
225  curr->setAcceleration(i, true);
226  }
227  }
228  if (curr == cont && dontSplit) {
229  WRITE_WARNING("Could not build on-ramp for edge '" + curr->getID() + "' due to option '--ramps.no-split'");
230  return;
231  }
232  } else {
233  // mark acceleration lanes
234  for (int i = 0; i < firstLaneNumber - potHighway->getNumLanes(); ++i) {
235  cont->setAcceleration(i, true);
236  }
237  }
238  // set connections from ramp/highway to added ramp
239  if (potHighway->getStep() < NBEdge::LANES2LANES_USER) {
240  if (!potHighway->addLane2LaneConnections(0, first, potRamp->getNumLanes(), MIN2(first->getNumLanes() - potRamp->getNumLanes(), potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true, true)) {
241  throw ProcessError("Could not set connection!");
242  }
243  }
244  if (potRamp->getStep() < NBEdge::LANES2LANES_USER) {
245  if (!potRamp->addLane2LaneConnections(0, first, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, true, true)) {
246  throw ProcessError("Could not set connection!");
247  }
248  }
249  // patch ramp geometry
250  PositionVector p = potRamp->getGeometry();
251  p.pop_back();
252  p.push_back(first->getLaneShape(0)[0]);
253  potRamp->setGeometry(p);
254 
255 }
256 
257 
258 void
259 NBRampsComputer::buildOffRamp(NBNode* cur, NBNodeCont& nc, NBEdgeCont& ec, NBDistrictCont& dc, double rampLength, bool dontSplit) {
260  NBEdge* potHighway, *potRamp, *prev;
261  getOffRampEdges(cur, &potHighway, &potRamp, &prev);
262  // compute the number of lanes to append
263  const int firstLaneNumber = prev->getNumLanes();
264  int toAdd = (potRamp->getNumLanes() + potHighway->getNumLanes()) - firstLaneNumber;
265  NBEdge* first = prev;
266  NBEdge* last = prev;
267  NBEdge* curr = prev;
268  std::set<NBEdge*> incremented;
269  if (toAdd > 0 && find(incremented.begin(), incremented.end(), prev) == incremented.end()) {
270  double currLength = 0;
271  while (curr != 0 && currLength + curr->getGeometry().length() - POSITION_EPS < rampLength) {
272  if (find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
273  curr->incLaneNo(toAdd);
274  if (curr->getStep() < NBEdge::LANES2LANES_USER) {
275  curr->invalidateConnections(true);
276  }
277  incremented.insert(curr);
278  moveRampRight(curr, toAdd);
279  currLength += curr->getGeometry().length(); // !!! loaded length?
280  last = curr;
281  }
282  NBNode* prevN = curr->getFromNode();
283  if (prevN->getIncomingEdges().size() == 1) {
284  curr = prevN->getIncomingEdges()[0];
285  if (curr->getStep() < NBEdge::LANES2LANES_USER && toAdd != 0) {
286  // curr might be an onRamp. In this case connections need to be rebuilt
287  curr->invalidateConnections();
288  }
289  if (curr->getNumLanes() != firstLaneNumber) {
290  // the number of lanes changes along the computation; we'll stop...
291  curr = 0;
292  } else if (last->isTurningDirectionAt(curr)) {
293  // turnarounds certainly should not be included in a ramp
294  curr = 0;
295  } else if (curr == potHighway || curr == potRamp) {
296  // circular connectivity. do not split!
297  curr = 0;
298  }
299  } else {
300  // ambigous; and, in fact, what should it be? ...stop
301  curr = 0;
302  }
303  }
304  // check whether a further split is necessary
305  if (curr != 0 && !dontSplit && currLength - POSITION_EPS < rampLength && curr->getNumLanes() == firstLaneNumber && find(incremented.begin(), incremented.end(), curr) == incremented.end()) {
306  // there is enough place to build a ramp; do it
307  bool wasFirst = first == curr;
308  Position pos = curr->getGeometry().positionAtOffset(curr->getGeometry().length() - (rampLength - currLength));
309  NBNode* rn = new NBNode(curr->getID() + "-AddedOffRampNode", pos);
310  if (!nc.insert(rn)) {
311  throw ProcessError("Ups - could not build off-ramp for edge '" + curr->getID() + "' (node could not be build)!");
312  }
313  std::string name = curr->getID();
314  bool ok = ec.splitAt(dc, curr, rn, curr->getID(), curr->getID() + "-AddedOffRampEdge", curr->getNumLanes(), curr->getNumLanes() + toAdd);
315  if (!ok) {
316  WRITE_ERROR("Ups - could not build off-ramp for edge '" + curr->getID() + "'!");
317  return;
318  }
319  curr = ec.retrieve(name + "-AddedOffRampEdge");
320  incremented.insert(curr);
321  last = curr;
322  moveRampRight(curr, toAdd);
323  if (wasFirst) {
324  first = curr;
325  }
326  }
327  if (curr == prev && dontSplit) {
328  WRITE_WARNING("Could not build off-ramp for edge '" + curr->getID() + "' due to option '--ramps.no-split'");
329  return;
330  }
331  }
332  // set connections from added ramp to ramp/highway
333  if (first->getStep() < NBEdge::LANES2LANES_USER) {
334  if (!first->addLane2LaneConnections(potRamp->getNumLanes(), potHighway, 0, MIN2(first->getNumLanes() - 1, potHighway->getNumLanes()), NBEdge::L2L_VALIDATED, true)) {
335  throw ProcessError("Could not set connection!");
336  }
337  if (!first->addLane2LaneConnections(0, potRamp, 0, potRamp->getNumLanes(), NBEdge::L2L_VALIDATED, false)) {
338  throw ProcessError("Could not set connection!");
339  }
340  }
341  // patch ramp geometry
342  PositionVector p = potRamp->getGeometry();
343  p[0] = first->getLaneShape(0)[-1];
344  potRamp->setGeometry(p);
345 }
346 
347 
348 void
349 NBRampsComputer::moveRampRight(NBEdge* ramp, int addedLanes) {
350  if (ramp->getLaneSpreadFunction() != LANESPREAD_CENTER) {
351  return;
352  }
353  try {
354  PositionVector g = ramp->getGeometry();
355  const double offset = (0.5 * addedLanes *
357  g.move2side(offset);
358  ramp->setGeometry(g);
359  } catch (InvalidArgument&) {
360  WRITE_WARNING("For edge '" + ramp->getID() + "': could not compute shape.");
361  }
362 }
363 
364 
365 bool
367  if (fabs((*potHighway)->getSpeed() - (*potRamp)->getSpeed()) < .1) {
368  return false;
369  }
370  if ((*potHighway)->getSpeed() < (*potRamp)->getSpeed()) {
371  std::swap(*potHighway, *potRamp);
372  }
373  return true;
374 }
375 
376 
377 bool
379  if ((*potHighway)->getNumLanes() == (*potRamp)->getNumLanes()) {
380  return false;
381  }
382  if ((*potHighway)->getNumLanes() < (*potRamp)->getNumLanes()) {
383  std::swap(*potHighway, *potRamp);
384  }
385  return true;
386 }
387 
388 
389 void
390 NBRampsComputer::getOnRampEdges(NBNode* n, NBEdge** potHighway, NBEdge** potRamp, NBEdge** other) {
391  *other = n->getOutgoingEdges()[0];
392  const std::vector<NBEdge*>& edges = n->getIncomingEdges();
393  assert(edges.size() == 2);
394  *potHighway = edges[0];
395  *potRamp = edges[1];
396  /*
397  // heuristic: highway is faster than ramp
398  if(determinedBySpeed(potHighway, potRamp)) {
399  return;
400  }
401  // heuristic: highway has more lanes than ramp
402  if(determinedByLaneNumber(potHighway, potRamp)) {
403  return;
404  }
405  */
406  // heuristic: ramp comes from right
407  if (NBContHelper::relative_incoming_edge_sorter(*other)(*potRamp, *potHighway)) {
408  std::swap(*potHighway, *potRamp);
409  }
410 }
411 
412 
413 void
414 NBRampsComputer::getOffRampEdges(NBNode* n, NBEdge** potHighway, NBEdge** potRamp, NBEdge** other) {
415  *other = n->getIncomingEdges()[0];
416  const std::vector<NBEdge*>& edges = n->getOutgoingEdges();
417  *potHighway = edges[0];
418  *potRamp = edges[1];
419  assert(edges.size() == 2);
420  /*
421  // heuristic: highway is faster than ramp
422  if(determinedBySpeed(potHighway, potRamp)) {
423  return;
424  }
425  // heuristic: highway has more lanes than ramp
426  if(determinedByLaneNumber(potHighway, potRamp)) {
427  return;
428  }
429  */
430  // heuristic: ramp goes to right
431  const std::vector<NBEdge*>& edges2 = n->getEdges();
432  std::vector<NBEdge*>::const_iterator i = std::find(edges2.begin(), edges2.end(), *other);
433  NBContHelper::nextCW(edges2, i);
434  if ((*i) == *potRamp) {
435  std::swap(*potHighway, *potRamp);
436  }
437  // the following would be better but runs afoul of misleading angles when both edges
438  // have the same geometry start point but different references lanes are
439  // chosen for NBEdge::computeAngle()
440  //if (NBContHelper::relative_outgoing_edge_sorter(*other)(*potHighway, *potRamp)) {
441  // std::swap(*potHighway, *potRamp);
442  //}
443 }
444 
445 
446 bool
448  NBEdge* potHighway, NBEdge* potRamp, NBEdge* other, double minHighwaySpeed, double maxRampSpeed,
449  const std::set<std::string>& noramps) {
450  // check modes that are not appropriate for rampsdo not build ramps on rail edges
451  if (hasWrongMode(potHighway) || hasWrongMode(potRamp) || hasWrongMode(other)) {
452  return false;
453  }
454  // do not build ramps on connectors
455  if (potHighway->isMacroscopicConnector() || potRamp->isMacroscopicConnector() || other->isMacroscopicConnector()) {
456  return false;
457  }
458  // check whether a lane is missing
459  if (potHighway->getNumLanes() + potRamp->getNumLanes() < other->getNumLanes()) {
460  return false;
461  }
462  // is it really a highway?
463  double maxSpeed = MAX3(potHighway->getSpeed(), other->getSpeed(), potRamp->getSpeed());
464  if (maxSpeed < minHighwaySpeed) {
465  return false;
466  }
467  // is any of the connections a turnaround?
468  if (other->getToNode() == potHighway->getFromNode()) {
469  // off ramp
470  if (other->isTurningDirectionAt(potHighway) ||
471  other->isTurningDirectionAt(potRamp)) {
472  return false;
473  }
474  } else {
475  // on ramp
476  if (other->isTurningDirectionAt(potHighway) ||
477  other->isTurningDirectionAt(potRamp)) {
478  return false;
479  }
480  }
481  // are the angles between highway and other / ramp and other more or less straight?
482  const NBNode* node = potHighway->getToNode() == potRamp->getToNode() ? potHighway->getToNode() : potHighway->getFromNode();
483  double angle = fabs(NBHelpers::relAngle(potHighway->getAngleAtNode(node), other->getAngleAtNode(node)));
484  if (angle >= 60) {
485  return false;
486  }
487  angle = fabs(NBHelpers::relAngle(potRamp->getAngleAtNode(node), other->getAngleAtNode(node)));
488  if (angle >= 60) {
489  return false;
490  }
491  /*
492  if (potHighway->getSpeed() < minHighwaySpeed || other->getSpeed() < minHighwaySpeed) {
493  return false;
494  }
495  */
496  // is it really a ramp?
497  if (maxRampSpeed > 0 && maxRampSpeed < potRamp->getSpeed()) {
498  return false;
499  }
500  if (noramps.find(other->getID()) != noramps.end()) {
501  return false;
502  }
503  return true;
504 }
505 
506 
507 bool
509  // must allow passenger vehicles
510  if ((edge->getPermissions() & SVC_PASSENGER) == 0) {
511  return true;
512  }
513  // must not have a green verge or a lane that is only for soft modes
514  for (int i = 0; i < (int)edge->getNumLanes(); ++i) {
515  if ((edge->getPermissions(i) & ~(SVC_PEDESTRIAN | SVC_BICYCLE)) == 0) {
516  return true;
517  }
518  }
519  return false;
520 }
521 
522 /****************************************************************************/
523 
static double relAngle(double angle1, double angle2)
computes the relative angle between the two angles
Definition: NBHelpers.cpp:52
LaneSpreadFunction getLaneSpreadFunction() const
Returns how this edge&#39;s lanes&#39; lateral offset is computed.
Definition: NBEdge.h:677
void invalidateConnections(bool reallowSetting=false)
invalidate current connections of edge
Definition: NBEdge.cpp:1238
is a pedestrian
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:114
static bool determinedBySpeed(NBEdge **potHighway, NBEdge **potRamp)
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:119
vehicle is a bicycle
const double SUMO_const_laneWidth
Definition: StdDefs.h:48
The representation of a single edge during network building.
Definition: NBEdge.h:71
A container for districts.
static bool mayNeedOffRamp(NBNode *cur, double minHighwaySpeed, double maxRampSpeed, const std::set< std::string > &noramps)
Determines whether the given node may be an off-ramp end.
bool splitAt(NBDistrictCont &dc, NBEdge *edge, NBNode *node)
Splits the edge at the position nearest to the given node.
Definition: NBEdgeCont.cpp:416
static void moveRampRight(NBEdge *ramp, int addedLanes)
Moves the ramp to the right, as new lanes were added.
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
const std::string & getID() const
Returns the id.
Definition: Named.h:66
void setGeometry(const PositionVector &g, bool inner=false)
(Re)sets the edge&#39;s geometry
Definition: NBEdge.cpp:512
T MAX3(T a, T b, T c)
Definition: StdDefs.h:84
static const double UNSPECIFIED_WIDTH
unspecified lane width
Definition: NBEdge.h:255
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:200
The connection was computed and validated.
Definition: NBEdge.h:117
void setAcceleration(int lane, bool accelRamp)
marks one lane as acceleration lane
Definition: NBEdge.cpp:2877
static bool determinedByLaneNumber(NBEdge **potHighway, NBEdge **potRamp)
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:245
static const std::string ADDED_ON_RAMP_EDGE
suffix for newly generated on-ramp edges
bool isSet(const std::string &name, bool failOnNonExistant=true) const
Returns the information whether the named option is set.
void incLaneNo(int by)
increment lane
Definition: NBEdge.cpp:2723
Lanes to lanes - relationships are loaded; no recheck is necessary/wished.
Definition: NBEdge.h:104
static bool fulfillsRampConstraints(NBEdge *potHighway, NBEdge *potRamp, NBEdge *other, double minHighwaySpeed, double maxRampSpeed, const std::set< std::string > &noramps)
Checks whether an on-/off-ramp can be bult here.
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:413
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
NBEdgeCont & getEdgeCont()
Definition: NBNetBuilder.h:155
A list of positions.
bool addLane2LaneConnections(int fromLane, NBEdge *dest, int toLane, int no, Lane2LaneInfoType type, bool invalidatePrevious=false, bool mayDefinitelyPass=false)
Builds no connections starting at the given lanes.
Definition: NBEdge.cpp:924
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:250
static bool mayNeedOnRamp(NBNode *cur, double minHighwaySpeed, double maxRampSpeed, const std::set< std::string > &noramps)
Determines whether the given node may be an on-ramp begin.
Storage for edges, including some functionality operating on multiple edges.
Definition: NBEdgeCont.h:66
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) ...
T MIN2(T a, T b)
Definition: StdDefs.h:64
#define POSITION_EPS
Definition: config.h:175
EdgeBuildingStep getStep() const
The building step of this edge.
Definition: NBEdge.h:516
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge&#39;s geometry at the given node.
Definition: NBEdge.cpp:1576
const std::set< EdgeSet > getRoundabouts() const
Returns the determined roundabouts.
double getFloat(const std::string &name) const
Returns the double-value of the named option (only for Option_Float)
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:2913
void move2side(double amount)
move position vector to side using certain ammount
vehicle is a passenger car (a "normal" car)
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:507
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:595
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
double getLaneWidth() const
Returns the default width of lanes of this edge.
Definition: NBEdge.h:523
static void computeRamps(NBNetBuilder &nb, OptionsCont &oc)
Computes highway on-/off-ramps (if wished)
double length() const
Returns the length.
static void getOffRampEdges(NBNode *n, NBEdge **potHighway, NBEdge **potRamp, NBEdge **other)
static void buildOffRamp(NBNode *cur, NBNodeCont &nc, NBEdgeCont &ec, NBDistrictCont &dc, double rampLength, bool dontSplit)
Builds an off-ramp ending at the given node.
const PositionVector & getLaneShape(int i) const
Returns the shape of the nth lane.
Definition: NBEdge.cpp:757
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:240
NBNodeCont & getNodeCont()
Returns a reference to the node container.
Definition: NBNetBuilder.h:160
Instance responsible for building networks.
Definition: NBNetBuilder.h:114
NBEdge * retrieve(const std::string &id, bool retrieveExtracted=false) const
Returns the edge that has the given id.
Definition: NBEdgeCont.cpp:251
A storage for options typed value containers)
Definition: OptionsCont.h:99
static void buildOnRamp(NBNode *cur, NBNodeCont &nc, NBEdgeCont &ec, NBDistrictCont &dc, double rampLength, bool dontSplit)
Builds an on-ramp starting at the given node.
bool insert(const std::string &id, const Position &position, NBDistrict *district=0)
Inserts a node into the map.
Definition: NBNodeCont.cpp:77
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:2367
Represents a single node (junction) during network building.
Definition: NBNode.h:75
static void getOnRampEdges(NBNode *n, NBEdge **potHighway, NBEdge **potRamp, NBEdge **other)
bool isMacroscopicConnector() const
Returns whether this edge was marked as a macroscopic connector.
Definition: NBEdge.h:929
static bool hasWrongMode(NBEdge *edge)
whether the edge has a mode that does not indicate a ramp edge
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:427
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:63
NBDistrictCont & getDistrictCont()
Returns a reference the districts container.
Definition: NBNetBuilder.h:175
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:434