Eclipse SUMO - Simulation of Urban MObility
NBAlgorithms.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2012-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // Algorithms for network computation
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <sstream>
26 #include <iostream>
27 #include <cassert>
28 #include <algorithm>
30 #include <utils/common/ToString.h>
32 #include "NBEdge.h"
33 #include "NBOwnTLDef.h"
35 #include "NBNodeCont.h"
36 #include "NBTypeCont.h"
37 #include "NBNode.h"
38 #include "NBAlgorithms.h"
39 
40 
41 // ===========================================================================
42 // method definitions
43 // ===========================================================================
44 // ---------------------------------------------------------------------------
45 // NBTurningDirectionsComputer
46 // ---------------------------------------------------------------------------
47 void
49  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
50  computeTurnDirectionsForNode(i->second, warn);
51  }
52 }
53 
54 void
56  const std::vector<NBEdge*>& incoming = node->getIncomingEdges();
57  const std::vector<NBEdge*>& outgoing = node->getOutgoingEdges();
58  // reset turning directions since this may be called multiple times
59  for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
60  (*k)->setTurningDestination(nullptr);
61  }
62  std::vector<Combination> combinations;
63  const bool geometryLike = node->geometryLike();
64  for (std::vector<NBEdge*>::const_iterator j = outgoing.begin(); j != outgoing.end(); ++j) {
65  NBEdge* outedge = *j;
66  for (std::vector<NBEdge*>::const_iterator k = incoming.begin(); k != incoming.end(); ++k) {
67  NBEdge* e = *k;
68  // @todo: check whether NBHelpers::relAngle is properly defined and whether it should really be used, here
69  const double signedAngle = NBHelpers::normRelAngle(e->getAngleAtNode(node), outedge->getAngleAtNode(node));
70  if (signedAngle > 0 && signedAngle < 177 && e->getGeometry().back().distanceTo2D(outedge->getGeometry().front()) < POSITION_EPS) {
71  // backwards curving edges can only be turnaround when there are
72  // non-default endpoints
73  continue;
74  }
75  double angle = fabs(signedAngle);
76  // std::cout << "incoming=" << e->getID() << " outgoing=" << outedge->getID() << " relAngle=" << NBHelpers::relAngle(e->getAngleAtNode(node), outedge->getAngleAtNode(node)) << "\n";
77  const bool badPermissions = ((outedge->getPermissions() & e->getPermissions() & ~SVC_PEDESTRIAN) == 0
78  && !geometryLike
79  && outedge->getPermissions() != e->getPermissions());
80  if (e->getFromNode() == outedge->getToNode() && angle > 120 && !badPermissions) {
81  // they connect the same nodes; should be the turnaround direction
82  // we'll assign a maximum number
83  //
84  // @todo: indeed, we have observed some pathological intersections
85  // see "294831560" in OSM/adlershof. Here, several edges are connecting
86  // same nodes. We have to do the angle check before...
87  //
88  // @todo: and well, there are some other as well, see plain import
89  // of delphi_muenchen (elmar), intersection "59534191". Not that it would
90  // be realistic in any means; we will warn, here.
91  angle += 360;
92  }
93  if (angle < 160) {
94  continue;
95  }
96  if (badPermissions) {
97  // penalty
98  angle -= 90;
99  }
100  Combination c;
101  c.from = e;
102  c.to = outedge;
103  c.angle = angle;
104  combinations.push_back(c);
105  }
106  }
107  // sort combinations so that the ones with the highest angle are at the begin
108  std::sort(combinations.begin(), combinations.end(), combination_by_angle_sorter());
109  std::set<NBEdge*> seen;
110  //std::cout << "check combinations at " << node->getID() << "\n";
111  for (std::vector<Combination>::const_iterator j = combinations.begin(); j != combinations.end(); ++j) {
112  //std::cout << " from=" << (*j).from->getID() << " to=" << (*j).to->getID() << " a=" << (*j).angle << "\n";
113  if (seen.find((*j).from) != seen.end() || seen.find((*j).to) != seen.end()) {
114  // do not regard already set edges
115  if ((*j).angle > 360 && warn) {
116  WRITE_WARNING("Ambiguity in turnarounds computation at junction '" + node->getID() + "'.");
117  //std::cout << " already seen: " << toString(seen) << "\n";
118  warn = false;
119  }
120  continue;
121  }
122  // mark as seen
123  seen.insert((*j).from);
124  seen.insert((*j).to);
125  // set turnaround information
126  bool onlyPossible = (*j).from->getConnections().size() != 0 && !(*j).from->isConnectedTo((*j).to);
127  //std::cout << " setTurningDestination from=" << (*j).from->getID() << " to=" << (*j).to->getID() << " onlyPossible=" << onlyPossible << "\n";
128  (*j).from->setTurningDestination((*j).to, onlyPossible);
129  }
130 }
131 
132 
133 // ---------------------------------------------------------------------------
134 // NBNodesEdgesSorter
135 // ---------------------------------------------------------------------------
136 void
138  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
139  i->second->sortEdges(useNodeShape);
140  }
141 }
142 
143 
144 void
146  const std::vector<NBEdge*>::iterator& i1,
147  const std::vector<NBEdge*>::iterator& i2) {
148  NBEdge* e1 = *i1;
149  NBEdge* e2 = *i2;
150  // @todo: The difference between "isTurningDirectionAt" and "isTurnaround"
151  // is not nice. Maybe we could get rid of it if we would always mark edges
152  // as turnarounds, even if they do not have to be added, as mentioned in
153  // notes on NBTurningDirectionsComputer::computeTurnDirectionsForNode
154  if (e2->getToNode() == n && e2->isTurningDirectionAt(e1)) {
155  std::swap(*i1, *i2);
156  }
157 }
158 
159 
160 // ---------------------------------------------------------------------------
161 // NBNodeTypeComputer
162 // ---------------------------------------------------------------------------
163 void
165  validateRailCrossings(nc, tlc);
166  const double rightBeforeLeftSpeed = OptionsCont::getOptions().getFloat("junctions.right-before-left.speed-threshold");
167  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
168  NBNode* n = (*i).second;
169  // the type may already be set from the data
170  if (n->myType != NODETYPE_UNKNOWN && n->myType != NODETYPE_DEAD_END) {
171  n->myTypeWasGuessed = false;
172  continue;
173  }
174  // check whether the node is a waterway node. Set to unregulated by default
175  bool waterway = true;
176  for (EdgeVector::const_iterator i = n->getEdges().begin(); i != n->getEdges().end(); ++i) {
177  if (!isWaterway((*i)->getPermissions())) {
178  waterway = false;
179  break;
180  }
181  }
182  if (waterway && (n->myType == NODETYPE_UNKNOWN || n->myType == NODETYPE_DEAD_END)) {
184  continue;
185  }
186 
187  // check whether the junction is not a real junction
188  if (n->myIncomingEdges.size() == 1) {
190  continue;
191  }
192  // @todo "isSimpleContinuation" should be revalidated
193  if (n->isSimpleContinuation()) {
195  continue;
196  }
197  // determine the type
199  for (EdgeVector::const_iterator i = n->myIncomingEdges.begin(); i != n->myIncomingEdges.end(); i++) {
200  for (EdgeVector::const_iterator j = i + 1; j != n->myIncomingEdges.end(); j++) {
201  // @todo "getOppositeIncoming" should probably be refactored into something the edge knows
202  if (n->getOppositeIncoming(*j) == *i && n->myIncomingEdges.size() > 2) {
203  continue;
204  }
205  // @todo check against a legal document
206  // @todo figure out when NODETYPE_PRIORITY_STOP is appropriate
207  const double s1 = (*i)->getSpeed();
208  const double s2 = (*j)->getSpeed();
209  const int p1 = (*i)->getPriority();
210  const int p2 = (*j)->getPriority();
211  if (fabs(s1 - s2) > (9.5 / 3.6) || MAX2(s1, s2) >= rightBeforeLeftSpeed || p1 != p2) {
212  type = NODETYPE_PRIORITY;
213  break;
214  }
215  }
216  }
217  // save type
218  n->myType = type;
219  n->myTypeWasGuessed = true;
220  }
221 }
222 
223 
224 void
226  for (std::map<std::string, NBNode*>::const_iterator i = nc.begin(); i != nc.end(); ++i) {
227  NBNode* n = (*i).second;
228  if (n->myType == NODETYPE_RAIL_CROSSING) {
229  // check if it really is a rail crossing
230  int numRailway = 0;
231  int numNonRailway = 0;
232  int numNonRailwayNonPed = 0;
233  for (NBEdge* e : n->getIncomingEdges()) {
234  if ((e->getPermissions() & ~SVC_RAIL_CLASSES) != 0) {
235  numNonRailway++;
236  if (e->getPermissions() != SVC_PEDESTRIAN) {
237  numNonRailwayNonPed++;
238  }
239  } else if ((e->getPermissions() & SVC_RAIL_CLASSES) != 0) {
240  numRailway++;
241  }
242  }
243  for (NBEdge* e : n->getOutgoingEdges()) {
244  if (e->getPermissions() == SVC_PEDESTRIAN) {
245  numNonRailway++;
246  }
247  }
248  if (numNonRailway == 0 || numRailway == 0) {
249  // not a crossing (maybe unregulated or rail_signal)
251  } else if (numNonRailwayNonPed > 2) {
252  // does not look like a rail crossing (roads in conflict). maybe a traffic light?
253  WRITE_WARNING("Converting invalid rail_crossing to traffic_light at junction '" + n->getID() + "'");
255  NBTrafficLightDefinition* tlDef = new NBOwnTLDef(n->getID(), n, 0, type);
257  if (!tlc.insert(tlDef)) {
258  // actually, nothing should fail here
259  n->removeTrafficLight(tlDef);
261  delete tlDef;
262  WRITE_WARNING("Could not allocate tls '" + n->getID() + "'.");
263  }
264  }
265  }
266  }
267 }
268 
269 
270 bool
272  int numRailway = 0;
273  int numNonRailway = 0;
274  for (NBEdge* e : n->getIncomingEdges()) {
275  if ((e->getPermissions() & ~SVC_RAIL_CLASSES) != 0) {
276  numNonRailway++;
277  } else if ((e->getPermissions() & SVC_RAIL_CLASSES) != 0) {
278  numRailway++;
279  }
280  }
281  return numRailway > 0 && numNonRailway == 0;
282 }
283 
284 // ---------------------------------------------------------------------------
285 // NBEdgePriorityComputer
286 // ---------------------------------------------------------------------------
287 void
289  for (const auto& node : nc) {
290  // preset all junction's edge priorities to zero
291  for (NBEdge* const edge : node.second->myAllEdges) {
292  edge->setJunctionPriority(node.second, NBEdge::MINOR_ROAD);
293  }
294  node.second->markBentPriority(false);
295  // check if the junction is not a real junction
296  if (node.second->myIncomingEdges.size() == 1 && node.second->myOutgoingEdges.size() == 1) {
297  continue;
298  }
299  // compute the priorities on junction when needed
300  if (node.second->getType() != NODETYPE_RIGHT_BEFORE_LEFT && node.second->getType() != NODETYPE_ALLWAY_STOP && node.second->getType() != NODETYPE_NOJUNCTION) {
301  if (node.second->getRightOfWay() == RIGHT_OF_WAY_EDGEPRIORITY) {
302  for (NBEdge* e : node.second->getIncomingEdges()) {
303  e->setJunctionPriority(node.second, e->getPriority());
304  }
305  } else {
306  setPriorityJunctionPriorities(*node.second);
307  }
308  }
309  }
310 }
311 
312 
313 void
315  if (n.myIncomingEdges.size() == 0 || n.myOutgoingEdges.size() == 0) {
316  return;
317  }
318  EdgeVector incoming = n.myIncomingEdges;
319  EdgeVector outgoing = n.myOutgoingEdges;
320  // what we do want to have is to extract the pair of roads that are
321  // the major roads for this junction
322  // let's get the list of incoming edges with the highest priority
323  std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_by_priority_sorter());
324  EdgeVector bestIncoming;
325  NBEdge* best = incoming[0];
326  while (incoming.size() > 0 && samePriority(best, incoming[0])) {
327  bestIncoming.push_back(*incoming.begin());
328  incoming.erase(incoming.begin());
329  }
330  // now, let's get the list of best outgoing
331  assert(outgoing.size() != 0);
332  sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_by_priority_sorter());
333  EdgeVector bestOutgoing;
334  best = outgoing[0];
335  while (outgoing.size() > 0 && samePriority(best, outgoing[0])) { //->getPriority()==best->getPriority()) {
336  bestOutgoing.push_back(*outgoing.begin());
337  outgoing.erase(outgoing.begin());
338  }
339  // special case: user input makes mainDirection unambiguous
340  const bool mainDirectionExplicit = (
341  bestIncoming.size() == 1 && n.myIncomingEdges.size() <= 2
342  && (incoming.size() == 0 || bestIncoming[0]->getPriority() > incoming[0]->getPriority())
343  && bestOutgoing.size() == 1 && n.myOutgoingEdges.size() <= 2
344  && (outgoing.size() == 0 || bestOutgoing[0]->getPriority() > outgoing[0]->getPriority())
345  && !bestIncoming[0]->isTurningDirectionAt(bestOutgoing[0]));
346  // now, let's compute for each of the best incoming edges
347  // the incoming which is most opposite
348  // the outgoing which is most opposite
349  EdgeVector::iterator i;
350  std::map<NBEdge*, NBEdge*> counterIncomingEdges;
351  std::map<NBEdge*, NBEdge*> counterOutgoingEdges;
352  incoming = n.myIncomingEdges;
353  outgoing = n.myOutgoingEdges;
354  for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
355  std::sort(incoming.begin(), incoming.end(), NBContHelper::edge_opposite_direction_sorter(*i, &n, true));
356  counterIncomingEdges[*i] = *incoming.begin();
357  std::sort(outgoing.begin(), outgoing.end(), NBContHelper::edge_opposite_direction_sorter(*i, &n, true));
358  counterOutgoingEdges[*i] = *outgoing.begin();
359  }
360  //std::cout << "n=" << n.getID() << " best=" << best->getID() << " bestIncoming=" << toString(bestIncoming) << "\n incoming=" << toString(incoming) << "\n outgoing=" << toString(outgoing) << "\n mainExplicit=" << mainDirectionExplicit << " counterBest=" << counterIncomingEdges.find(bestIncoming[0])->second->getID() << "\n";
361  // ok, let's try
362  // 1) there is one best incoming road
363  if (bestIncoming.size() == 1) {
364  // let's mark this road as the best
365  NBEdge* best1 = extractAndMarkFirst(n, bestIncoming);
366  if (!mainDirectionExplicit && counterIncomingEdges.find(best1) != counterIncomingEdges.end()) {
367  // ok, look, what we want is the opposit of the straight continuation edge
368  // but, what if such an edge does not exist? By now, we'll determine it
369  // geometrically
370  NBEdge* s = counterIncomingEdges.find(best1)->second;
371  const double minAngleDiff = GeomHelper::getMinAngleDiff(best1->getAngleAtNode(&n), s->getAngleAtNode(&n));
372  if (minAngleDiff > 180 - 45
373  || (minAngleDiff > 75 && s->getPriority() == best1->getPriority() && hasDifferentPriorities(incoming, best1))) {
375  }
376  }
377  markBestParallel(n, best1, nullptr);
378  assert(bestOutgoing.size() != 0);
379  // mark the best outgoing as the continuation
380  sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(best1));
381  // assign extra priority if the priorities are unambiguous (regardless of geometry)
382  NBEdge* bestOut = extractAndMarkFirst(n, bestOutgoing);
383  if (!mainDirectionExplicit && counterOutgoingEdges.find(bestOut) != counterOutgoingEdges.end()) {
384  NBEdge* s = counterOutgoingEdges.find(bestOut)->second;
385  if (GeomHelper::getMinAngleDiff(bestOut->getAngleAtNode(&n), s->getAngleAtNode(&n)) > 180 - 45) {
386  s->setJunctionPriority(&n, 1);
387  }
388  }
389  n.markBentPriority(n.getDirection(best1, bestOut) != LINKDIR_STRAIGHT);
390  return;
391  }
392 
393  // ok, what we want to do in this case is to determine which incoming
394  // has the best continuation...
395  // This means, when several incoming roads have the same priority,
396  // we want a (any) straight connection to be more priorised than a turning
397  double bestAngle = 0;
398  NBEdge* bestFirst = nullptr;
399  NBEdge* bestSecond = nullptr;
400  bool hadBest = false;
401  for (i = bestIncoming.begin(); i != bestIncoming.end(); ++i) {
402  EdgeVector::iterator j;
403  NBEdge* t1 = *i;
404  double angle1 = t1->getAngleAtNode(&n) + 180;
405  if (angle1 >= 360) {
406  angle1 -= 360;
407  }
408  for (j = i + 1; j != bestIncoming.end(); ++j) {
409  NBEdge* t2 = *j;
410  double angle2 = t2->getAngleAtNode(&n) + 180;
411  if (angle2 >= 360) {
412  angle2 -= 360;
413  }
414  double angle = GeomHelper::getMinAngleDiff(angle1, angle2);
415  if (!hadBest || angle > bestAngle) {
416  bestAngle = angle;
417  bestFirst = *i;
418  bestSecond = *j;
419  hadBest = true;
420  }
421  }
422  }
423  bestFirst->setJunctionPriority(&n, 1);
424  sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestFirst));
425  if (bestOutgoing.size() != 0) {
426  extractAndMarkFirst(n, bestOutgoing);
427  }
428  bestSecond->setJunctionPriority(&n, 1);
429  sort(bestOutgoing.begin(), bestOutgoing.end(), NBContHelper::edge_similar_direction_sorter(bestSecond));
430  if (bestOutgoing.size() != 0) {
431  extractAndMarkFirst(n, bestOutgoing);
432  }
433  n.markBentPriority(GeomHelper::getMinAngleDiff(bestFirst->getAngleAtNode(&n), bestSecond->getAngleAtNode(&n)) < 135);
434  markBestParallel(n, bestFirst, bestSecond);
435 }
436 
437 
438 void
439 NBEdgePriorityComputer::markBestParallel(const NBNode& n, NBEdge* bestFirst, NBEdge* bestSecond) {
440  // edges running parallel to the main direction should also be prioritised
441  const double a1 = bestFirst->getAngleAtNode(&n);
442  const double a2 = bestSecond == nullptr ? a1 : bestSecond->getAngleAtNode(&n);
443  SVCPermissions p1 = bestFirst->getPermissions();
444  SVCPermissions p2 = bestSecond == nullptr ? p1 : bestSecond->getPermissions();
445  for (NBEdge* e : n.getIncomingEdges()) {
446  // @note: this rule might also apply if there are common permissions but
447  // then we would not further rules to resolve the priority between the best edge and its parallel edge
448  SVCPermissions perm = e->getPermissions();
449  if (((GeomHelper::getMinAngleDiff(e->getAngleAtNode(&n), a1) < 10
450  || GeomHelper::getMinAngleDiff(e->getAngleAtNode(&n), a2) < 10))
451  && (p1 & perm) == 0 && (p2 & perm) == 0) {
452  e->setJunctionPriority(&n, 1);
453  }
454  }
455 }
456 
457 
458 NBEdge*
459 NBEdgePriorityComputer::extractAndMarkFirst(NBNode& n, std::vector<NBEdge*>& s, int prio) {
460  if (s.size() == 0) {
461  return nullptr;
462  }
463  NBEdge* ret = s.front();
464  s.erase(s.begin());
465  ret->setJunctionPriority(&n, prio);
466  return ret;
467 }
468 
469 
470 bool
471 NBEdgePriorityComputer::samePriority(const NBEdge* const e1, const NBEdge* const e2) {
472  if (e1 == e2) {
473  return true;
474  }
475  if (e1->getPriority() != e2->getPriority()) {
476  return false;
477  }
478  if ((int) e1->getSpeed() != (int) e2->getSpeed()) {
479  return false;
480  }
481  return (int) e1->getNumLanes() == (int) e2->getNumLanes();
482 }
483 
484 
485 bool
487  if (edges.size() < 2) {
488  return false;
489  }
490  int prio = edges[0] == excluded ? edges[1]->getPriority() : edges[0]->getPriority();
491  for (auto e : edges) {
492  if (e != excluded && e->getPriority() != prio) {
493  return true;
494  }
495  }
496  return false;
497 }
498 
499 
501  // reorder based on getAngleAtNodeToCenter
502  myOrdering = ordering;
503  sort(myOrdering.begin(), myOrdering.end(), NBContHelper::edge_by_angle_to_nodeShapeCentroid_sorter(node));
504  // let the first edge remain the first
505  rotate(myOrdering.begin(), std::find(myOrdering.begin(), myOrdering.end(), ordering.front()), myOrdering.end());
506 }
507 
508 
509 /****************************************************************************/
510 
static double getMinAngleDiff(double angle1, double angle2)
Returns the minimum distance (clockwise/counter-clockwise) between both angles.
Definition: GeomHelper.cpp:175
bool isSimpleContinuation(bool checkLaneNumbers=true, bool checkWidth=false) const
check if node is a simple continuation
Definition: NBNode.cpp:469
static void validateRailCrossings(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Checks rail_crossing for validity.
std::map< std::string, NBNode * >::const_iterator begin() const
Returns the pointer to the begin of the stored nodes.
Definition: NBNodeCont.h:116
EdgeVector getIncomingEdges() const
Returns the list of incoming edges unsorted.
Definition: NBEdge.cpp:1238
static void markBestParallel(const NBNode &n, NBEdge *bestFirst, NBEdge *bestSecond)
set priority for edges that are parallel to the best edges
std::map< std::string, NBNode * >::const_iterator end() const
Returns the pointer to the end of the stored nodes.
Definition: NBNodeCont.h:121
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
Definition: NBHelpers.cpp:60
SumoXMLNodeType myType
The type of the junction.
Definition: NBNode.h:835
A container for traffic light definitions and built programs.
int getPriority() const
Returns the priority of the edge.
Definition: NBEdge.h:472
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
The representation of a single edge during network building.
Definition: NBEdge.h:86
Class to sort edges by their angle in relation to the given edge.
Definition: NBContHelper.h:141
The base class for traffic light logic definitions.
void markBentPriority(bool isBent)
mark whether a priority road turns at this node
Definition: NBNode.h:758
T MAX2(T a, T b)
Definition: StdDefs.h:80
const std::string & getID() const
Returns the id.
Definition: Named.h:77
void removeTrafficLight(NBTrafficLightDefinition *tlDef)
Removes the given traffic light from this node.
Definition: NBNode.cpp:369
static void sortNodesEdges(NBNodeCont &nc, bool useNodeShape=false)
Sorts a node&#39;s edges clockwise regarding driving direction.
Stores the information about the angle between an incoming ("from") and an outgoing ("to") edge...
Definition: NBAlgorithms.h:68
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:239
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:58
const EdgeVector & getOutgoingEdges() const
Returns this node&#39;s outgoing edges (The edges which start at this node)
Definition: NBNode.h:264
The link is a straight direction.
static bool hasDifferentPriorities(const EdgeVector &edges, const NBEdge *excluded)
return whether the priorite attribute can be used to distinguish the edges
bool myTypeWasGuessed
whether the node type was guessed rather than loaded
Definition: NBNode.h:882
static void swapWhenReversed(const NBNode *const n, const std::vector< NBEdge *>::iterator &i1, const std::vector< NBEdge *>::iterator &i2)
Assures correct order for same-angle opposite-direction edges.
static StringBijection< TrafficLightType > TrafficLightTypes
traffic light types
int getNumLanes() const
Returns the number of lanes.
Definition: NBEdge.h:465
classes which drive on tracks
static void computeEdgePriorities(NBNodeCont &nc)
Computes edge priorities within a node.
bool isWaterway(SVCPermissions permissions)
Returns whether an edge with the given permission is a waterway edge.
T get(const std::string &str) const
const EdgeVector & getEdges() const
Returns all edges which participate in this node (Edges that start or end at this node) ...
Definition: NBNode.h:269
bool geometryLike() const
whether this is structurally similar to a geometry node
Definition: NBNode.cpp:3046
#define POSITION_EPS
Definition: config.h:169
double getAngleAtNode(const NBNode *const node) const
Returns the angle of the edge&#39;s geometry at the given node.
Definition: NBEdge.cpp:1863
crossing_by_junction_angle_sorter(const NBNode *node, const EdgeVector &ordering)
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:3441
EdgeVector myIncomingEdges
Vector of incoming edges.
Definition: NBNode.h:817
static void computeTurnDirectionsForNode(NBNode *node, bool warn)
Computes turnaround destinations for all incoming edges of the given nodes (if any) ...
static bool samePriority(const NBEdge *const e1, const NBEdge *const e2)
Returns whether both edges have the same priority.
LinkDirection getDirection(const NBEdge *const incoming, const NBEdge *const outgoing, bool leftHand=false) const
Returns the representation of the described stream&#39;s direction.
Definition: NBNode.cpp:1936
double getSpeed() const
Returns the speed allowed on this edge.
Definition: NBEdge.h:559
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:680
EdgeVector myOutgoingEdges
Vector of outgoing edges.
Definition: NBNode.h:820
const EdgeVector & getIncomingEdges() const
Returns this node&#39;s incoming edges (The edges which yield in this node)
Definition: NBNode.h:259
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
void setJunctionPriority(const NBNode *const node, int prio)
Sets the junction priority of the edge.
Definition: NBEdge.cpp:1853
bool isTurningDirectionAt(const NBEdge *const edge) const
Returns whether the given edge is the opposite direction to this edge.
Definition: NBEdge.cpp:2783
Represents a single node (junction) during network building.
Definition: NBNode.h:68
static void computeTurnDirections(NBNodeCont &nc, bool warn=true)
Computes turnaround destinations for all edges (if exist)
bool insert(NBTrafficLightDefinition *logic, bool forceInsert=false)
Adds a logic definition to the dictionary.
static bool isRailwayNode(const NBNode *n)
whether the given node only has rail edges
static NBEdge * extractAndMarkFirst(NBNode &n, std::vector< NBEdge *> &s, int prio=1)
Sets the priorites in case of a priority junction.
NBEdge * getOppositeIncoming(NBEdge *e) const
returns the opposite incoming edge of certain edge
Definition: NBNode.cpp:1546
Sorts "Combination"s by decreasing angle.
Definition: NBAlgorithms.h:78
static void setPriorityJunctionPriorities(NBNode &n)
Sets the priorites in case of a priority junction.
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:479
Container for nodes during the netbuilding process.
Definition: NBNodeCont.h:60
static void computeNodeTypes(NBNodeCont &nc, NBTrafficLightLogicCont &tlc)
Computes node types.
A traffic light logics which must be computed (only nodes/edges are given)
Definition: NBOwnTLDef.h:47
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:486
TrafficLightType