Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netbuild/NBNode.h
169666 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file NBNode.h
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Yun-Pang Floetteroed
18
/// @author Michael Behrisch
19
/// @date Tue, 20 Nov 2001
20
///
21
// The representation of a single node
22
/****************************************************************************/
23
#pragma once
24
#include <config.h>
25
26
#include <vector>
27
#include <deque>
28
#include <utility>
29
#include <string>
30
#include <set>
31
#include <memory>
32
#include <utils/common/StdDefs.h>
33
#include <utils/common/Named.h>
34
#include <utils/geom/Bresenham.h>
35
#include <utils/geom/GeomHelper.h>
36
#include <utils/common/VectorHelper.h>
37
#include <utils/geom/Position.h>
38
#include <utils/geom/PositionVector.h>
39
#include <utils/xml/SUMOXMLDefinitions.h>
40
#include "NBEdge.h"
41
#include "NBConnection.h"
42
#include "NBConnectionDefs.h"
43
#include "NBContHelper.h"
44
45
46
// ===========================================================================
47
// class declarations
48
// ===========================================================================
49
class NBRequest;
50
class NBDistrict;
51
class OptionsCont;
52
class NBTrafficLightDefinition;
53
class NBTypeCont;
54
class NBTrafficLightLogicCont;
55
class NBDistrictCont;
56
class OutputDevice;
57
58
59
// ===========================================================================
60
// class definitions
61
// ===========================================================================
62
/**
63
* @class NBNode
64
* @brief Represents a single node (junction) during network building
65
*/
66
class NBNode : public Named, public Parameterised {
67
friend class NBNodeCont;
68
friend class GNEJunction; // < used for visualization (netedit)
69
friend class NBNodesEdgesSorter; // < sorts the edges
70
friend class NBNodeTypeComputer; // < computes type
71
friend class NBEdgePriorityComputer; // < computes priorities of edges per intersection
72
73
public:
74
/**
75
* @class ApproachingDivider
76
* @brief Computes lane-2-lane connections
77
*
78
* Being a bresenham-callback, this class computes which lanes
79
* are approached by the current lane (first callback parameter).
80
* The second callback parameter is the destination lane that is the
81
* middle of the computed lanes.
82
* The lanes are spreaded from this middle position both to left and right
83
* but may also be transposed in full when there is not enough space.
84
*/
85
class ApproachingDivider : public Bresenham::BresenhamCallBack {
86
public:
87
/**@brief Constructor
88
* @param[in] approaching The list of the edges that approach the outgoing edge
89
* @param[in] currentOutgoing The outgoing edge
90
*/
91
ApproachingDivider(const EdgeVector& approaching, NBEdge* currentOutgoing);
92
93
/// @brief Destructor
94
~ApproachingDivider();
95
96
/// @ get number of available lanes
97
int numAvailableLanes() const {
98
return (int)myAvailableLanes.size();
99
}
100
101
/// @brief the bresenham-callback
102
void execute(const int src, const int dest);
103
104
/// @brief the method that spreads the wished number of lanes from the lane given by the bresenham-call to both left and right
105
std::deque<int>* spread(int numLanes, int dest) const;
106
107
private:
108
/// @brief The list of edges that approach the current edge
109
const EdgeVector& myApproaching;
110
111
/// @brief The approached current edge
112
NBEdge* myCurrentOutgoing;
113
114
/// @brief The available lanes to which connections shall be built
115
std::vector<int> myAvailableLanes;
116
117
/// directions from each incoming edge to the outgoing edge
118
std::vector<LinkDirection> myDirections;
119
120
/// @brief number of straight connections to the outgoing edge
121
int myNumStraight;
122
123
/// @brief whether the outgoing edge is exclusively used by bikes
124
bool myIsBikeEdge;
125
126
private:
127
/// @brief Invalidated assignment operator.
128
ApproachingDivider& operator=(const ApproachingDivider&) = delete;
129
130
};
131
132
/** @class Crossing
133
* @brief A definition of a pedestrian crossing
134
*/
135
class Crossing final : public Parameterised {
136
public:
137
/// @brief constructor
138
Crossing(const NBNode* _node, const EdgeVector& _edges, double _width, bool _priority, int _customTLIndex, int _customTLIndex2, const PositionVector& _customShape);
139
/// @brief The parent node of this crossing
140
const NBNode* node;
141
/// @brief The edges being crossed
142
EdgeVector edges;
143
/// @brief The crossing's shape
144
PositionVector shape;
145
/// @brief The outline shape for this crossing
146
PositionVector outlineShape;
147
/// @brief This crossing's width
148
double customWidth;
149
/// @brief This crossing's width
150
double width;
151
/// @brief the (edge)-id of this crossing
152
std::string id;
153
/// @brief the lane-id of the previous walkingArea
154
std::string prevWalkingArea;
155
/// @brief the lane-id of the next walkingArea
156
std::string nextWalkingArea;
157
/// @brief whether the pedestrians have priority
158
bool priority;
159
/// @brief optional customShape for this crossing
160
PositionVector customShape;
161
/// @brief the traffic light index of this crossing (if controlled)
162
int tlLinkIndex;
163
int tlLinkIndex2;
164
/// @brief the custom traffic light index of this crossing (if controlled)
165
int customTLIndex;
166
int customTLIndex2;
167
/// @brief The id of the traffic light that controls this connection
168
std::string tlID;
169
/// @brief whether this crossing is valid (and can be written to the net.xml). This is needed for netedit because validity can only be checked during junction computation
170
bool valid;
171
};
172
173
174
/** @struct WalkingArea
175
* @brief A definition of a pedestrian walking area
176
*/
177
struct WalkingArea {
178
/// @brief constructor
179
WalkingArea(const std::string& _id, double _width) :
180
id(_id),
181
width(_width) {
182
}
183
/// @brief the (edge)-id of this walkingArea
184
std::string id;
185
/// @brief This lane's width
186
double width;
187
/// @brief This lane's width
188
double length = INVALID_DOUBLE;
189
/// @brief The polygonal shape
190
PositionVector shape;
191
/// @brief the lane-id of the next crossing(s)
192
std::vector<std::string> nextCrossings;
193
/// @brief the lane-id of the previous crossing(s)
194
std::vector<std::string> prevCrossings;
195
/// @brief the lane-id of the next sidewalk lane or ""
196
std::vector<std::string> nextSidewalks;
197
/// @brief the lane-id of the previous sidewalk lane or ""
198
std::vector<std::string> prevSidewalks;
199
/// @brief whether this walkingArea has a custom shape
200
bool hasCustomShape = false;
201
/// @brief minimum number of edges crossed by nextCrossings
202
int minNextCrossingEdges = std::numeric_limits<int>::max();
203
/// @brief minimum number of edges crossed by incoming crossings
204
int minPrevCrossingEdges = std::numeric_limits<int>::max();
205
/// @brief reference edges that uniquely identify this walkingarea
206
std::set<const NBEdge*, ComparatorIdLess> refEdges;
207
};
208
209
struct WalkingAreaCustomShape {
210
std::set<const NBEdge*, ComparatorIdLess> edges;
211
PositionVector shape;
212
double width;
213
};
214
215
/// @brief edge directions (for pedestrian related stuff)
216
static const int FORWARD;
217
static const int BACKWARD;
218
219
/// @brief unspecified lane width
220
static const double UNSPECIFIED_RADIUS;
221
222
/// @brief flags for controlling shape generation
223
static const int AVOID_WIDE_RIGHT_TURN;
224
static const int AVOID_WIDE_LEFT_TURN;
225
static const int FOUR_CONTROL_POINTS;
226
static const int AVOID_INTERSECTING_LEFT_TURNS;
227
static const int SCURVE_IGNORE;
228
static const int INDIRECT_LEFT;
229
230
public:
231
/**@brief Constructor
232
* @param[in] id The id of the node
233
* @param[in] position The position of the node
234
* @param[in] type The type of the node
235
*/
236
NBNode(const std::string& id, const Position& position, SumoXMLNodeType type);
237
238
/**@brief Constructor
239
* @param[in] id The id of the node
240
* @param[in] position The position of the node
241
* @param[in] district The district this district node represents, 0 means no district node
242
*/
243
NBNode(const std::string& id, const Position& position, NBDistrict* district = 0);
244
245
/// @brief Destructor
246
~NBNode();
247
248
/**@brief Resets initial values
249
* @param[in] position The position of the node
250
* @param[in] type The type of the node
251
* @param[in] updateEdgeGeometries Whether the geometires of all
252
* connected edges shall be updated
253
*/
254
void reinit(const Position& position, SumoXMLNodeType type,
255
bool updateEdgeGeometries = false);
256
257
/// @name Atomar getter methods
258
/// @{
259
/// @brief Returns the position of this node
260
inline const Position& getPosition() const {
261
return myPosition;
262
}
263
264
/// @brief Returns a position that is guaranteed to lie within the node shape
265
Position getCenter() const;
266
267
/// @brief Returns this node's incoming edges (The edges which yield in this node)
268
inline const EdgeVector& getIncomingEdges() const {
269
return myIncomingEdges;
270
}
271
272
/// @brief Returns this node's outgoing edges (The edges which start at this node)
273
inline const EdgeVector& getOutgoingEdges() const {
274
return myOutgoingEdges;
275
}
276
277
/// @brief Returns all edges which participate in this node (Edges that start or end at this node)
278
inline const EdgeVector& getEdges() const {
279
return myAllEdges;
280
}
281
282
/**@brief Returns the type of this node
283
* @see SumoXMLNodeType
284
*/
285
inline SumoXMLNodeType getType() const {
286
return myType;
287
}
288
289
/// @brief Returns the turning radius of this node
290
inline double getRadius() const {
291
return myRadius;
292
}
293
294
/// @brief Returns the keepClear flag
295
inline bool getKeepClear() const {
296
return myKeepClear;
297
}
298
299
/// @brief Returns hint on how to compute right of way
300
inline RightOfWay getRightOfWay() const {
301
return myRightOfWay;
302
}
303
304
/// @brief Returns fringe type
305
inline FringeType getFringeType() const {
306
return myFringeType;
307
}
308
309
/// @brief Returns intersection name
310
inline const std::string& getName() const {
311
return myName;
312
}
313
/// @}
314
315
/// @name Methods for dealing with assigned traffic lights
316
/// @{
317
/**@brief Adds a traffic light to the list of traffic lights that control this node
318
* @param[in] tld The traffic light that controls this node
319
*/
320
void addTrafficLight(NBTrafficLightDefinition* tlDef);
321
322
/// @brief Removes the given traffic light from this node
323
void removeTrafficLight(NBTrafficLightDefinition* tlDef);
324
325
/// @brief Removes all references to traffic lights that control this tls
326
void removeTrafficLights(bool setAsPriority = false);
327
328
/**@brief Returns whether this node is controlled by any tls
329
* @return Whether a traffic light was assigned to this node
330
*/
331
bool isTLControlled() const {
332
return myTrafficLights.size() != 0;
333
}
334
335
336
/// @brief whether this node was marked as having a signal in the (OSM) input
337
bool hadSignal() const;
338
339
/// @brief Returns the traffic lights that were assigned to this node (The set of tls that control this node)
340
const std::set<NBTrafficLightDefinition*>& getControllingTLS() const {
341
return myTrafficLights;
342
}
343
344
/// @brief causes the traffic light to be computed anew
345
void invalidateTLS(NBTrafficLightLogicCont& tlCont, bool addedConnections, bool removedConnections);
346
347
/// @brief patches loaded signal plans by modifying lane indices above threshold by the given offset
348
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1);
349
/// @}
350
351
352
/// @name Prunning the input
353
/// @{
354
355
/**@brief Removes edges which are both incoming and outgoing into this node
356
*
357
* If given, the connections to other edges participating in this node are updated
358
*
359
* @param[in, opt. changed] dc The districts container to update
360
* @param[in, opt. changed] ec The edge container to remove the edges from
361
* @param[in, opt. changed] tc The traffic lights container to update
362
* @return The number of removed edges
363
*/
364
int removeSelfLoops(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc);
365
/// @}
366
367
368
/// @name Applying offset
369
/// @{
370
/**@brief Applies an offset to the node
371
* @param[in] xoff The x-offset to apply
372
* @param[in] yoff The y-offset to apply
373
*/
374
void reshiftPosition(double xoff, double yoff);
375
376
/// @brief ensure consistency between input and output geometries
377
void roundGeometry();
378
379
/// @brief mirror coordinates along the x-axis
380
void mirrorX();
381
/// @}
382
383
/// @brief adds an incoming edge
384
void addIncomingEdge(NBEdge* edge);
385
386
/// @brief adds an outgoing edge
387
void addOutgoingEdge(NBEdge* edge);
388
389
/// @brief computes the connections of lanes to edges
390
void computeLanes2Lanes();
391
392
/// @brief computes the node's type, logic and traffic light
393
void computeLogic(const NBEdgeCont& ec);
394
395
/// @brief compute right-of-way logic for all lane-to-lane connections
396
void computeLogic2(bool checkLaneFoes);
397
398
/// @brief compute keepClear status for all connections
399
void computeKeepClear();
400
401
/// @brief writes the XML-representation of the logic as a bitset-logic XML representation
402
bool writeLogic(OutputDevice& into) const;
403
404
/// @brief get the 'foes' string (conflict bit set) of the right-of-way logic
405
const std::string getFoes(int linkIndex) const;
406
407
/// @brief get the 'response' string (right-of-way bit set) of the right-of-way logic
408
const std::string getResponse(int linkIndex) const;
409
410
/// @brief whether there are conflicting streams of traffic at this node
411
bool hasConflict() const;
412
413
/// @brief whether the given edge has a conflicting stream of traffic at this node
414
bool hasConflict(const NBEdge* e) const;
415
416
/// @brief Returns something like the most unused direction Should only be used to add source or sink nodes
417
Position getEmptyDir() const;
418
419
/**@brief Returns whether the given edge ends at this node
420
* @param[in] e The edge
421
* @return Whether the given edge is one of this node's incoming edges
422
*/
423
bool hasIncoming(const NBEdge* const e) const;
424
425
/**@brief Returns whether the given edge starts at this node
426
* @param[in] e The edge
427
* @return Whether the given edge is one of this node's outgoing edges
428
*/
429
bool hasOutgoing(const NBEdge* const e) const;
430
431
/// @brief returns the opposite incoming edge of certain edge
432
NBEdge* getOppositeIncoming(NBEdge* e) const;
433
434
/// @brief invalidate incoming connections
435
void invalidateIncomingConnections(bool reallowSetting = false);
436
437
/// @brief invalidate outgoing connections
438
void invalidateOutgoingConnections(bool reallowSetting = false);
439
440
/// @brief remove duble edges
441
void removeDoubleEdges();
442
443
/// @brief get connection to certain node
444
NBEdge* getConnectionTo(NBNode* n) const;
445
446
/// @brief add shorted link FOES
447
void addSortedLinkFoes(const NBConnection& mayDrive, const NBConnection& mustStop);
448
449
/// @brief get possibly splitted incoming edge
450
NBEdge* getPossiblySplittedIncoming(const std::string& edgeid);
451
452
/// @brief get possibly splitted outgoing edge
453
NBEdge* getPossiblySplittedOutgoing(const std::string& edgeid);
454
455
/// @brief Removes edge from this node and optionally removes connections as well
456
void removeEdge(NBEdge* edge, bool removeFromConnections = true);
457
458
/**@brief Computes whether the given connection is a left mover across the junction
459
*
460
* It is assumed, that it is a left-mover if the clockwise angle is lower
461
* than the counter-clockwise angle.
462
*
463
* @param[in] from The incoming edge (the begin of the connection)
464
* @param[in] from The outgoing edge (the end of the connection)
465
* @return Whether the described connection is a left-mover
466
*/
467
bool isLeftMover(const NBEdge* const from, const NBEdge* const to) const;
468
469
/**@brief Returns the information whether the described flow must let any other flow pass
470
* @param[in] from The connection's start edge
471
* @param[in] to The connection's end edge
472
* @param[in] fromLane The lane the connection start at
473
* @param[in] toLane The lane the connection ends at
474
* @param[in] includePedCrossings Whether braking due to a pedestrian crossing counts
475
* @return Whether the described connection must brake (has higher priorised foes)
476
*/
477
bool mustBrake(const NBEdge* const from, const NBEdge* const to, int fromLane, int toLane, bool includePedCrossings) const;
478
479
/**@brief Returns the information whether the described flow must brake for the given crossing
480
* @param[in] from The connection's start edge
481
* @param[in] to The connection's end edge
482
* @param[in] crossing The pedestrian crossing to check
483
* @return Whether the described connection must brake (has higher priorised foes)
484
*/
485
bool mustBrakeForCrossing(const NBEdge* const from, const NBEdge* const to, const Crossing& crossing) const;
486
487
/// @brief whether a connection to the given edge must brake for a crossing when leaving the intersection
488
bool brakeForCrossingOnExit(const NBEdge* to, LinkDirection dir, bool indirect) const;
489
490
/// @brief return whether the given laneToLane connection is a right turn which must yield to a bicycle crossings
491
static bool rightTurnConflict(const NBEdge* from, const NBEdge* to, int fromLane,
492
const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorFromLane);
493
494
/// @brief whether one of multple connections from the same edge targeting the same lane must yield
495
bool mergeConflictYields(const NBEdge* from, int fromLane, int fromLaneFoe, NBEdge* to, int toLane) const;
496
497
/// @brief whether multiple connections from the same edge target the same lane
498
bool mergeConflict(const NBEdge* from, const NBEdge::Connection& con,
499
const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
500
501
/// @brief whether the foe connections is oncoming on the same lane
502
bool bidiConflict(const NBEdge* from, const NBEdge::Connection& con,
503
const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
504
505
bool zipperConflict(const NBEdge* incoming, const NBEdge* outgoing, int fromLane, int toLane) const;
506
507
/// @brief return whether the given laneToLane connection originate from the same edge and are in conflict due to turning across each other
508
bool turnFoes(const NBEdge* from, const NBEdge* to, int fromLane,
509
const NBEdge* from2, const NBEdge* to2, int fromLane2,
510
bool lefthand = false) const;
511
512
/**@brief Returns the information whether "prohibited" flow must let "prohibitor" flow pass
513
* @param[in] possProhibitedFrom The maybe prohibited connection's begin
514
* @param[in] possProhibitedTo The maybe prohibited connection's end
515
* @param[in] possProhibitorFrom The maybe prohibiting connection's begin
516
* @param[in] possProhibitorTo The maybe prohibiting connection's end
517
* @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
518
* @return Whether the second flow prohibits the first one
519
*/
520
bool forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
521
const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
522
bool regardNonSignalisedLowerPriority) const;
523
524
/**@brief Returns the information whether the given flows cross
525
* @param[in] from1 The starting edge of the first stream
526
* @param[in] to1 The ending edge of the first stream
527
* @param[in] from2 The starting edge of the second stream
528
* @param[in] to2 The ending edge of the second stream
529
* @return Whether both stream are foes (cross)
530
*/
531
bool foes(const NBEdge* const from1, const NBEdge* const to1,
532
const NBEdge* const from2, const NBEdge* const to2) const;
533
534
/**@brief Returns the representation of the described stream's direction
535
* @param[in] incoming The edge the stream starts at
536
* @param[in] outgoing The edge the stream ends at
537
* @param[in] leftHand Whether a lefthand network is being built. Should only be set at writing time
538
* @return The direction of the stream
539
*/
540
LinkDirection getDirection(const NBEdge* const incoming, const NBEdge* const outgoing, bool leftHand = false) const;
541
542
/// @brief get link state
543
LinkState getLinkState(const NBEdge* incoming, const NBEdge* outgoing,
544
int fromLane, int toLane, bool mayDefinitelyPass, const std::string& tlID) const;
545
546
/**@brief Compute the junction shape for this node
547
* @param[in] mismatchThreshold The threshold for warning about shapes which are away from myPosition
548
*/
549
void computeNodeShape(double mismatchThreshold);
550
551
/// @brief update geometry of node and surrounding edges
552
void updateSurroundingGeometry();
553
554
/// @brief retrieve the junction shape
555
const PositionVector& getShape() const;
556
557
/// @brief set the junction shape
558
void setCustomShape(const PositionVector& shape);
559
560
/// @brief reset node shape
561
void resetShape() {
562
myPoly.clear();
563
}
564
565
/// @brief set the turning radius
566
void setRadius(double radius) {
567
myRadius = radius;
568
}
569
570
/// @brief set the keepClear flag
571
void setKeepClear(bool keepClear) {
572
myKeepClear = keepClear;
573
}
574
575
/// @brief set method for computing right-of-way
576
void setRightOfWay(RightOfWay rightOfWay) {
577
myRightOfWay = rightOfWay;
578
}
579
580
/// @brief set method for computing right-of-way
581
void setFringeType(FringeType fringeType) {
582
myFringeType = fringeType;
583
}
584
585
/// @brief set intersection name
586
void setName(const std::string& name) {
587
myName = name;
588
}
589
590
/// @brief return whether the shape was set by the user
591
bool hasCustomShape() const {
592
return myHaveCustomPoly;
593
}
594
595
/// @brief check if node is removable
596
bool checkIsRemovable() const;
597
598
/// @brief check if node is removable and return reason if not
599
bool checkIsRemovableReporting(std::string& reason) const;
600
601
/// @brief get edges to join
602
std::vector<std::pair<NBEdge*, NBEdge*> > getEdgesToJoin() const;
603
604
/// @chech if node is near district
605
bool isNearDistrict() const;
606
607
/// @brief check if node is a district
608
bool isDistrict() const;
609
610
/// @brief whether an internal junction should be built at from and respect other
611
bool needsCont(const NBEdge* fromE, const NBEdge* otherFromE,
612
const NBEdge::Connection& c, const NBEdge::Connection& otherC, bool checkOnlyTLS = false) const;
613
614
/// @brief whether the connection must yield if the foe remains on the intersection after its phase ends
615
bool tlsStrandedConflict(const NBEdge* from, const NBEdge::Connection& c,
616
const NBEdge* foeFrom, const NBEdge::Connection& foe) const;
617
618
619
/**@brief Compute the shape for an internal lane
620
* @param[in] fromE The starting edge
621
* @param[in] con The connection for this internal lane
622
* @param[in] numPoints The number of geometry points for the internal lane
623
* @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
624
* @return The shape of the internal lane
625
*/
626
PositionVector computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& con, int numPoints, NBNode* recordError = 0, int shapeFlag = 0) const;
627
628
/**@brief Compute a smooth curve between the given geometries
629
* @param[in] begShape The geometry at the start
630
* @param[in] endShape The geometry at the end
631
* @param[in] numPoints The number of geometry points for the internal lane
632
* @param[in] isTurnaround Whether this shall be the shape for a turnaround
633
* @param[in] extrapolateBeg Extrapolation distance at the beginning
634
* @param[in] extrapolateEnd Extrapolation distance at the end
635
* @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
636
* @return The shape of the internal lane
637
*/
638
PositionVector computeSmoothShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints,
639
bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
640
NBNode* recordError = 0, int shapeFlag = 0) const;
641
/// @brief get bezier control points
642
static PositionVector bezierControlPoints(const PositionVector& begShape, const PositionVector& endShape,
643
bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
644
bool& ok, NBNode* recordError = 0, double straightThresh = DEG2RAD(5),
645
int shapeFlag = 0);
646
647
/// @brief compute shape of indirect left turn
648
PositionVector indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const;
649
650
/// @brief compute the displacement error during s-curve computation
651
double getDisplacementError() const {
652
return myDisplacementError;
653
}
654
655
/// @brief Replaces occurrences of the first edge within the list of incoming by the second Connections are remapped, too
656
void replaceIncoming(NBEdge* which, NBEdge* by, int laneOff);
657
658
/// @brief Replaces occurrences of every edge from the given list within the list of incoming by the second Connections are remapped, too
659
void replaceIncoming(const EdgeVector& which, NBEdge* by);
660
661
/// @brief Replaces occurrences of the first edge within the list of outgoing by the second Connections are remapped, too
662
void replaceOutgoing(NBEdge* which, NBEdge* by, int laneOff);
663
664
/// @brief Replaces occurrences of every edge from the given list within the list of outgoing by the second Connections are remapped, too
665
void replaceOutgoing(const EdgeVector& which, NBEdge* by);
666
667
/// @brief guess pedestrian crossings and return how many were guessed
668
int guessCrossings();
669
670
/* @brief check whether a crossing should be build for the candiate edges and build 0 to n crossings
671
* @param[in] candidates The candidate vector of edges to be crossed
672
* @param[in] checkOnly Whether only checking (of user supplied) crossings shall be performed
673
* @return The number of crossings built
674
* */
675
int checkCrossing(EdgeVector candidates, bool checkOnly = false);
676
677
/// @brief return true if there already exist a crossing with the same edges as the input
678
bool checkCrossingDuplicated(EdgeVector edges);
679
680
/// @brief build internal lanes, pedestrian crossings and walking areas
681
double buildInnerEdges();
682
683
/**@brief build pedestrian crossings
684
* @return The next index for creating internal lanes
685
**/
686
int buildCrossings();
687
688
/**@brief build pedestrian walking areas and set connections from/to walkingAreas
689
* @param[in] cornerDetail The detail level when generating the inner curve
690
*/
691
void buildWalkingAreas(int cornerDetail, double joinMinDist);
692
693
/// @brief build crossing outlines after walkingareas are finished
694
void buildCrossingOutlines();
695
696
/// @brief build crossings, and walkingareas. Also removes invalid loaded crossings if wished
697
void buildCrossingsAndWalkingAreas();
698
699
/// @brief return all edges that lie clockwise between the given edges
700
EdgeVector edgesBetween(const NBEdge* e1, const NBEdge* e2) const;
701
702
/// @brief return true if the given edges are connected by a crossing
703
bool crossingBetween(const NBEdge* e1, const NBEdge* e2) const;
704
705
/// @brief return true if the given pedestrian paths are connected at another junction within dist
706
bool alreadyConnectedPaths(const NBEdge* e1, const NBEdge* e2, double dist) const;
707
708
/// @brief return true if the given sidewalks are separated by a fringe road
709
bool crossesFringe(const NBEdge* e1, const NBEdge* e2) const;
710
711
/// @brief get prohibitions (BLocked connections)
712
const NBConnectionProhibits& getProhibitions() {
713
return myBlockedConnections;
714
}
715
716
/// @brief whether this is structurally similar to a geometry node
717
bool geometryLike() const;
718
static bool geometryLike(const EdgeVector& incoming, const EdgeVector& outgoing);
719
720
/// @brief update the type of this node as a roundabout
721
void setRoundabout();
722
723
/// @brief return whether this node is part of a roundabout
724
bool isRoundabout() const;
725
726
/// @brief add a pedestrian crossing to this node
727
NBNode::Crossing* addCrossing(EdgeVector edges, double width, bool priority, int tlIndex = -1, int tlIndex2 = -1,
728
const PositionVector& customShape = PositionVector::EMPTY, bool fromSumoNet = false, const Parameterised* params = nullptr);
729
730
/// @brief add custom shape for walkingArea
731
void addWalkingAreaShape(EdgeVector edges, const PositionVector& shape, double width);
732
733
/// @brief remove a pedestrian crossing from this node (identified by its edges)
734
void removeCrossing(const EdgeVector& edges);
735
736
/// @brief discard all current (and optionally future) crossings
737
void discardAllCrossings(bool rejectAll);
738
739
/// @brief discard previously built walkingareas (required for repeated computation by netedit)
740
void discardWalkingareas();
741
742
/// @brief get num of crossings from sumo net
743
int numCrossingsFromSumoNet() const {
744
return myCrossingsLoadedFromSumoNet;
745
}
746
747
/// @brief return this junctions pedestrian crossings
748
std::vector<Crossing*> getCrossings() const;
749
inline const std::vector<std::unique_ptr<Crossing> >& getCrossingsIncludingInvalid() const {
750
return myCrossings;
751
}
752
753
/// @brief return this junctions pedestrian walking areas
754
inline const std::vector<WalkingArea>& getWalkingAreas() const {
755
return myWalkingAreas;
756
}
757
758
const std::vector<WalkingAreaCustomShape>& getWalkingAreaCustomShapes() const {
759
return myWalkingAreaCustomShapes;
760
}
761
762
/// @brief return the crossing with the given id
763
Crossing* getCrossing(const std::string& id) const;
764
765
/// @brief return the crossing with the given Edges
766
Crossing* getCrossing(const EdgeVector& edges, bool hardFail = true) const;
767
768
/// @brief return the walkingArea with the given ID
769
WalkingArea& getWalkingArea(const std::string& id);
770
771
/* @brief set tl indices of this nodes crossing starting at the given index
772
* @return Whether a custom index was used
773
*/
774
bool setCrossingTLIndices(const std::string& tlID, int startIndex, bool ignoreCustom = false);
775
776
/// @brief return the number of lane-to-lane connections at this junction (excluding crossings)
777
int numNormalConnections() const;
778
779
/// @brief fix overlap
780
void avoidOverlap();
781
782
/// @brief whether the given index must yield to the foeIndex while turing right on a red light
783
bool extraConflict(int index, int foeIndex) const;
784
785
/// @brief sort all edge containers for this node
786
void sortEdges(bool useNodeShape);
787
788
/// @brief return the index of the given connection
789
int getConnectionIndex(const NBEdge* from, const NBEdge::Connection& con) const;
790
791
/**
792
* @class nodes_by_id_sorter
793
* @brief Used for sorting the cells by the begin time they describe
794
*/
795
class nodes_by_id_sorter {
796
public:
797
/// @brief Constructor
798
explicit nodes_by_id_sorter() { }
799
800
/// @brief Comparing operator
801
int operator()(NBNode* n1, NBNode* n2) const {
802
return n1->getID() < n2->getID();
803
}
804
};
805
806
/** @class edge_by_direction_sorter
807
* @brief Sorts outgoing before incoming edges
808
*/
809
class edge_by_direction_sorter {
810
public:
811
/// @brief constructor
812
explicit edge_by_direction_sorter(NBNode* n) : myNode(n) {}
813
814
/// @brief operator of selection
815
int operator()(NBEdge* e1, NBEdge* e2) const {
816
UNUSED_PARAMETER(e2);
817
return e1->getFromNode() == myNode;
818
}
819
820
private:
821
/// @brief The node to compute the relative angle of
822
NBNode* myNode;
823
824
};
825
826
/// @brief return whether the given type is a traffic light
827
static bool isTrafficLight(SumoXMLNodeType type);
828
829
inline bool isTrafficLight() const {
830
return isTrafficLight(myType);
831
}
832
833
/// @brief check if node is a simple continuation
834
bool isSimpleContinuation(bool checkLaneNumbers = true, bool checkWidth = false) const;
835
836
/// @brief mark whether a priority road turns at this node
837
void markBentPriority(bool isBent) {
838
myIsBentPriority = isBent;
839
}
840
841
/// @brief return whether a priority road turns at this node
842
bool isBentPriority() const {
843
return myIsBentPriority;
844
}
845
846
/// @brief return whether a priority road turns at this node
847
bool typeWasGuessed() const {
848
return myTypeWasGuessed;
849
}
850
851
/// @brief detects whether a given junction splits or merges lanes while keeping constant road width
852
bool isConstantWidthTransition() const;
853
854
/// @brief return list of unique endpoint coordinates of all edges at this node
855
std::vector<std::pair<Position, std::string> > getEndPoints() const;
856
857
/// @brief ensure connectivity for all vClasses
858
void recheckVClassConnections(NBEdge* currentOutgoing);
859
860
/// @brief initialize signalized rail classes
861
static void initRailSignalClasses(const NBNodeCont& nc);
862
863
private:
864
/// @brief sets the priorites in case of a priority junction
865
void setPriorityJunctionPriorities();
866
867
/// @brief returns a list of edges which are connected to the given outgoing edge
868
void getEdgesThatApproach(NBEdge* currentOutgoing, EdgeVector& approaching);
869
870
/// @brief replace incoming connections prohibitions
871
void replaceInConnectionProhibitions(NBEdge* which, NBEdge* by, int whichLaneOff, int byLaneOff);
872
873
/// @brief remap removed
874
void remapRemoved(NBTrafficLightLogicCont& tc, NBEdge* removed, const EdgeVector& incoming, const EdgeVector& outgoing);
875
876
/// @brief return whether there is a non-sidewalk lane after the given index;
877
bool forbidsPedestriansAfter(std::vector<std::pair<NBEdge*, bool> > normalizedLanes, int startIndex);
878
879
/// @brief returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
880
EdgeVector getEdgesSortedByAngleAtNodeCenter() const;
881
882
/// @brief check if is long enough
883
static bool isLongEnough(NBEdge* out, double minLength);
884
885
/// @brief remove all traffic light definitions that are part of a joined tls
886
void removeJoinedTrafficLights();
887
888
/// @brief displace lane shapes to account for change in lane width at this node
889
void displaceShapeAtWidthChange(const NBEdge* from, const NBEdge::Connection& con, PositionVector& fromShape, PositionVector& toShape) const;
890
891
/// @brief returns whether sub is a subset of super
892
static bool includes(const std::set<const NBEdge*, ComparatorIdLess>& super,
893
const std::set<const NBEdge*, ComparatorIdLess>& sub);
894
895
NBEdge* getNextCompatibleOutgoing(const NBEdge* incoming, SVCPermissions vehPerm, EdgeVector::const_iterator start, bool clockwise) const;
896
897
/// @brief get the reduction in driving lanes at this junction
898
void getReduction(const NBEdge* in, const NBEdge* out, int& inOffset, int& inEnd, int& outOffset, int& outEnd, int& reduction) const;
899
900
/// @brief helper function to add connections for unsatisfied modes
901
SVCPermissions findToLaneForPermissions(NBEdge* currentOutgoing, int fromLane, NBEdge* incoming, SVCPermissions unsatisfied);
902
903
/// @brief check whether this edge has extra lanes on the right side
904
int addedLanesRight(NBEdge* out, int addedLanes) const;
905
906
/// @brief check whether the candidate edge is more likely to be the straight continuation
907
bool isStraighter(const NBEdge* const incoming, const double angle, const SVCPermissions vehPerm, const int modeLanes, const NBEdge* const candidate) const;
908
909
/// @brief return edges that permit passengers (either incoming or outgoing)
910
EdgeVector getPassengerEdges(bool incoming) const;
911
912
/// @brief detect explict rail turns with potential geometry problem
913
static bool isExplicitRailNoBidi(const NBEdge* incoming, const NBEdge* outgoing);
914
915
/// @brief geometry helper that cuts the first shape where bordered by the other two
916
PositionVector cutAtShapes(const PositionVector& cut, const PositionVector& border1, const PositionVector& border2, const PositionVector& def);
917
918
/// @brief compute offset for centering path-across-street crossings
919
void patchOffset_pathAcrossStreet(double& offset);
920
921
/// @brief whether the given rail connections at this node may run in unsignalized (right-of-way) mode
922
bool unsignalizedOperation() const;
923
924
/// @brief ensure connectivity for all special vClass
925
void recheckSpecialConnections(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial);
926
927
/// @brief helper function for recheckSpecialConnections
928
bool avoidConfict(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial, LinkDirection dir, int i);
929
930
private:
931
/// @brief The position the node lies at
932
Position myPosition;
933
934
/// @brief Vector of incoming edges
935
EdgeVector myIncomingEdges;
936
937
/// @brief Vector of outgoing edges
938
EdgeVector myOutgoingEdges;
939
940
/// @brief Vector of incoming and outgoing edges
941
EdgeVector myAllEdges;
942
943
/// @brief Vector of crossings
944
std::vector<std::unique_ptr<Crossing> > myCrossings;
945
946
/// @brief Vector of walking areas
947
std::vector<WalkingArea> myWalkingAreas;
948
949
/// @brief Vector of custom walking areas shapes
950
std::vector<WalkingAreaCustomShape> myWalkingAreaCustomShapes;
951
952
/// @brief The type of the junction
953
SumoXMLNodeType myType;
954
955
/// @brief The container for connection block dependencies
956
NBConnectionProhibits myBlockedConnections;
957
958
/// @brief The district the node is the centre of
959
NBDistrict* myDistrict;
960
961
/// @brief the (outer) shape of the junction
962
PositionVector myPoly;
963
964
/// @brief whether this nodes shape was set by the user
965
bool myHaveCustomPoly;
966
967
/// @brief Node requests
968
NBRequest* myRequest;
969
970
/// @brief traffic lights of node
971
std::set<NBTrafficLightDefinition*> myTrafficLights;
972
973
/// @brief the turning radius (for all corners) at this node in m.
974
double myRadius;
975
976
/// @brief whether the junction area must be kept clear
977
bool myKeepClear;
978
979
/// @brief how to compute right of way for this node
980
RightOfWay myRightOfWay;
981
982
/// @brief fringe type of this node
983
FringeType myFringeType;
984
985
/// @brief The intersection name (or whatever arbitrary string you wish to attach)
986
std::string myName;
987
988
/// @brief whether to discard all pedestrian crossings
989
bool myDiscardAllCrossings;
990
991
/// @brief number of crossings loaded from a sumo net
992
int myCrossingsLoadedFromSumoNet;
993
994
/// @brief geometry error after computation of internal lane shapes
995
double myDisplacementError;
996
997
/* @brief whether this junction is a bent priority junction (main direction turns)
998
* @note see NBEdgePriorityComputer
999
*/
1000
bool myIsBentPriority;
1001
1002
/// @brief whether the node type was guessed rather than loaded
1003
bool myTypeWasGuessed;
1004
1005
/// @brief all vehicle classes for which rail signals exist
1006
static SVCPermissions myHaveRailSignalClasses;
1007
1008
/// @brief all rail classes for which operation without rail signals is permitted
1009
static SVCPermissions myPermitUnsignalizedClasses;
1010
1011
private:
1012
/// @brief invalidated copy constructor
1013
NBNode(const NBNode& s);
1014
1015
/// @brief invalidated assignment operator
1016
NBNode& operator=(const NBNode& s);
1017
};
1018
1019