Eclipse SUMO - Simulation of Urban MObility
NBContHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
20 // Some methods for traversing lists of edges
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <vector>
25 #include <map>
26 #include <cassert>
27 #include "NBContHelper.h"
28 #include <utils/geom/GeomHelper.h>
29 
30 
31 // ===========================================================================
32 // method definitions
33 // ===========================================================================
34 /* -------------------------------------------------------------------------
35  * utility methods
36  * ----------------------------------------------------------------------- */
37 void
38 NBContHelper::nextCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
39  from++;
40  if (from == edges.end()) {
41  from = edges.begin();
42  }
43 }
44 
45 
46 void
47 NBContHelper::nextCCW(const EdgeVector& edges, EdgeVector::const_iterator& from) {
48  if (from == edges.begin()) {
49  from = edges.end() - 1;
50  } else {
51  --from;
52  }
53 }
54 
55 
56 std::ostream&
57 NBContHelper::out(std::ostream& os, const std::vector<bool>& v) {
58  for (std::vector<bool>::const_iterator i = v.begin(); i != v.end(); i++) {
59  os << *i;
60  }
61  return os;
62 }
63 
64 
65 NBEdge*
67  NBNode* from, NBNode* to) {
68  for (EdgeVector::const_iterator i = edges.begin(); i != edges.end(); i++) {
69  if ((*i)->getToNode() == to && (*i)->getFromNode() == from) {
70  return *i;
71  }
72  }
73  return nullptr;
74 }
75 
76 
77 
78 double
80  assert(ev.size() > 0);
81  double max = (*(ev.begin()))->getSpeed();
82  for (EdgeVector::const_iterator i = ev.begin() + 1; i != ev.end(); i++) {
83  max =
84  max > (*i)->getSpeed()
85  ? max : (*i)->getSpeed();
86  }
87  return max;
88 }
89 
90 
91 
92 /* -------------------------------------------------------------------------
93  * methods from node_with_incoming_finder
94  * ----------------------------------------------------------------------- */
96  : myEdge(e) {}
97 
98 
99 bool
101  const EdgeVector& incoming = n->getIncomingEdges();
102  return std::find(incoming.begin(), incoming.end(), myEdge) != incoming.end();
103 }
104 
105 
106 
107 /* -------------------------------------------------------------------------
108  * methods from node_with_outgoing_finder
109  * ----------------------------------------------------------------------- */
111  : myEdge(e) {}
112 
113 
114 bool
116  const EdgeVector& outgoing = n->getOutgoingEdges();
117  return std::find(outgoing.begin(), outgoing.end(), myEdge) != outgoing.end();
118 }
119 
120 
121 /* -------------------------------------------------------------------------
122  * methods from edge_with_destination_finder
123  * ----------------------------------------------------------------------- */
125  : myDestinationNode(dest) {}
126 
127 
128 bool
130  return e->getToNode() == myDestinationNode;
131 }
132 
133 
134 /* -------------------------------------------------------------------------
135  * methods from relative_outgoing_edge_sorter
136  * ----------------------------------------------------------------------- */
137 bool
139  assert(e1 != nullptr && e2 != nullptr);
140  double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getStartAngle());
141  double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getStartAngle());
142  const double length1 = e1->getGeometry().length2D();
143  const double length2 = e2->getGeometry().length2D();
144 
145  double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
146  while (fabs(relAngle1 - relAngle2) < 3.0) {
147  // look at further geometry segments to resolve ambiguity
148  const double offset1 = MAX2(0.0, MIN2(length1, lookAhead));
149  const double offset2 = MAX2(0.0, MIN2(length2, lookAhead));
150  const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
151  const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
152  const double angle1 = GeomHelper::legacyDegree(e1->getFromNode()->getPosition().angleTo2D(referencePos1), true);
153  const double angle2 = GeomHelper::legacyDegree(e2->getFromNode()->getPosition().angleTo2D(referencePos2), true);
154  relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
155  relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
156  if (lookAhead > MAX2(length1, length2)) {
157  break;
158  }
159  lookAhead *= 2;
160  }
161  if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
162  // need to break ties for windows debug version, numerical id may be -1 for both
163  return e1->getID() > e2->getID();
164  }
165  return relAngle1 > relAngle2;
166 }
167 
168 
169 /* -------------------------------------------------------------------------
170  * methods from relative_incoming_edge_sorter
171  * ----------------------------------------------------------------------- */
172 bool
174  assert(e1 != nullptr && e2 != nullptr);
175  double relAngle1 = NBHelpers::normRelAngle(myAngle, e1->getEndAngle());
176  double relAngle2 = NBHelpers::normRelAngle(myAngle, e2->getEndAngle());
177  const double length1 = e1->getGeometry().length2D();
178  const double length2 = e2->getGeometry().length2D();
179 
180  double lookAhead = 2 * NBEdge::ANGLE_LOOKAHEAD;
181  while (fabs(relAngle1 - relAngle2) < 3.0) {
182  // look at further geometry segments to resolve ambiguity
183  const double offset1 = MAX2(0.0, MIN2(length1, length1 - lookAhead));
184  const double offset2 = MAX2(0.0, MIN2(length2, length2 - lookAhead));
185  const Position referencePos1 = e1->getGeometry().positionAtOffset2D(offset1);
186  const Position referencePos2 = e2->getGeometry().positionAtOffset2D(offset2);
187  const double angle1 = GeomHelper::legacyDegree(referencePos1.angleTo2D(e1->getToNode()->getPosition()), true);
188  const double angle2 = GeomHelper::legacyDegree(referencePos2.angleTo2D(e2->getToNode()->getPosition()), true);
189  relAngle1 = NBHelpers::normRelAngle(myAngle, angle1);
190  relAngle2 = NBHelpers::normRelAngle(myAngle, angle2);
191  if (lookAhead > MAX2(length1, length2)) {
192  break;
193  }
194  lookAhead *= 2;
195  }
196  if (fabs(relAngle1 - relAngle2) < NUMERICAL_EPS) {
197  // need to break ties for windows debug version, numerical id may be -1 for both
198  return e1->getID() > e2->getID();
199  }
200  return relAngle1 > relAngle2;
201 }
202 
203 
204 std::ostream&
205 operator<<(std::ostream& os, const EdgeVector& ev) {
206  for (EdgeVector::const_iterator i = ev.begin(); i != ev.end(); i++) {
207  if (i != ev.begin()) {
208  os << ", ";
209  }
210  os << (*i)->getID();
211  }
212  return os;
213 }
214 
215 
216 double
218  if (edges.size() == 0) {
219  return -1;
220  }
221  double ret = (*(edges.begin()))->getSpeed();
222  for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
223  if ((*i)->getSpeed() > ret) {
224  ret = (*i)->getSpeed();
225  }
226  }
227  return ret;
228 }
229 
230 
231 double
233  if (edges.size() == 0) {
234  return -1;
235  }
236  double ret = (*(edges.begin()))->getSpeed();
237  for (EdgeVector::const_iterator i = edges.begin() + 1; i != edges.end(); i++) {
238  if ((*i)->getSpeed() < ret) {
239  ret = (*i)->getSpeed();
240  }
241  }
242  return ret;
243 }
244 
245 
246 bool
248  assert(e1->getFromNode() == myNode || e1->getToNode() == myNode);
249  assert(e2->getFromNode() == myNode || e2->getToNode() == myNode);
250  const double angle1 = e1->getAngleAtNodeToCenter(myNode);
251  const double angle2 = e2->getAngleAtNodeToCenter(myNode);
252  const double absDiff = fabs(angle1 - angle2);
253 
254  // cannot trust the angle difference hence a heuristic:
255  if (absDiff < 2 || absDiff > (360 - 2)) {
256  const bool sameDir = ((e1->getFromNode() == myNode && e2->getFromNode() == myNode)
257  || (e1->getToNode() == myNode && e2->getToNode() == myNode));
258  if (sameDir) {
259  // put edges that allow pedestrians on the 'outside', but be aware if both allow / disallow
260  const bool e1Peds = (e1->getPermissions() & SVC_PEDESTRIAN) != 0;
261  const bool e2Peds = (e2->getPermissions() & SVC_PEDESTRIAN) != 0;
262  if (e1->getToNode() == myNode) {
263  if (e1Peds && !e2Peds) {
264  return true;
265  } else if (!e1Peds && e2Peds) {
266  return false;
267  }
268  } else {
269  if (!e1Peds && e2Peds) {
270  return true;
271  } else if (e1Peds && !e2Peds) {
272  return false;
273  }
274  }
275  // break ties to ensure strictly weak ordering
276  return e1->getID() < e2->getID();
277  } else {
278  // sort incoming before outgoing, no need to break ties here
279  return e1->getToNode() == myNode;
280  }
281  }
282  return angle1 < angle2;
283 }
284 
285 
286 /****************************************************************************/
std::vector< NBEdge * > EdgeVector
container for (sorted) edges
Definition: NBCont.h:35
@ SVC_PEDESTRIAN
pedestrian
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
static double legacyDegree(const double angle, const bool positive=false)
Definition: GeomHelper.cpp:214
bool operator()(const NBEdge *e1, const NBEdge *e2) const
comparing operation
edge_with_destination_finder(NBNode *dest)
constructor
bool operator()(const NBNode *const n) const
node_with_incoming_finder(const NBEdge *const e)
constructor
bool operator()(const NBNode *const n) const
node_with_outgoing_finder(const NBEdge *const e)
constructor
bool operator()(const NBEdge *e1, const NBEdge *e2) const
comparing operation
bool operator()(const NBEdge *e1, const NBEdge *e2) const
comparing operation
static NBEdge * findConnectingEdge(const EdgeVector &edges, NBNode *from, NBNode *to)
static double getMaxSpeed(const EdgeVector &edges)
static void nextCCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
static void nextCW(const EdgeVector &edges, EdgeVector::const_iterator &from)
static double getMinSpeed(const EdgeVector &edges)
static double maxSpeed(const EdgeVector &ev)
static std::ostream & out(std::ostream &os, const std::vector< bool > &v)
friend std::ostream & operator<<(std::ostream &os, const EdgeVector &ev)
The representation of a single edge during network building.
Definition: NBEdge.h:92
SVCPermissions getPermissions(int lane=-1) const
get the union of allowed classes over all lanes or for a specific lane
Definition: NBEdge.cpp:4308
const std::string & getID() const
Definition: NBEdge.h:1522
NBNode * getToNode() const
Returns the destination node of the edge.
Definition: NBEdge.h:542
const PositionVector & getGeometry() const
Returns the geometry of the edge.
Definition: NBEdge.h:779
static const double ANGLE_LOOKAHEAD
the distance at which to take the default angle
Definition: NBEdge.h:366
double getStartAngle() const
Returns the angle at the start of the edge (relative to the node shape center) The angle is computed ...
Definition: NBEdge.h:551
double getAngleAtNodeToCenter(const NBNode *const node) const
Returns the angle of from the node shape center to where the edge meets the node shape.
Definition: NBEdge.cpp:2136
double getEndAngle() const
Returns the angle at the end of the edge (relative to the node shape center) The angle is computed in...
Definition: NBEdge.h:560
NBNode * getFromNode() const
Returns the origin node of the edge.
Definition: NBEdge.h:535
static double normRelAngle(double angle1, double angle2)
ensure that reverse relAngles (>=179.999) always count as turnarounds (-180)
Definition: NBHelpers.cpp:58
Represents a single node (junction) during network building.
Definition: NBNode.h:66
const EdgeVector & getOutgoingEdges() const
Returns this node's outgoing edges (The edges which start at this node)
Definition: NBNode.h:273
const EdgeVector & getIncomingEdges() const
Returns this node's incoming edges (The edges which yield in this node)
Definition: NBNode.h:268
const Position & getPosition() const
Definition: NBNode.h:260
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position (in radians bet...
Definition: Position.h:281
double length2D() const
Returns the length.
Position positionAtOffset2D(double pos, double lateralOffset=0) const
Returns the position at the given length.