Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netbuild/NBNode.h
193884 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2026 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 roundabout type
310
inline RoundaboutType getRoundaboutType() const {
311
return myRoundaboutType;
312
}
313
314
/// @brief Returns intersection name
315
inline const std::string& getName() const {
316
return myName;
317
}
318
/// @}
319
320
/// @name Methods for dealing with assigned traffic lights
321
/// @{
322
/**@brief Adds a traffic light to the list of traffic lights that control this node
323
* @param[in] tld The traffic light that controls this node
324
*/
325
void addTrafficLight(NBTrafficLightDefinition* tlDef);
326
327
/// @brief Removes the given traffic light from this node
328
void removeTrafficLight(NBTrafficLightDefinition* tlDef);
329
330
/// @brief Removes all references to traffic lights that control this tls
331
void removeTrafficLights(bool setAsPriority = false);
332
333
/**@brief Returns whether this node is controlled by any tls
334
* @return Whether a traffic light was assigned to this node
335
*/
336
bool isTLControlled() const {
337
return myTrafficLights.size() != 0;
338
}
339
340
341
/// @brief whether this node was marked as having a signal in the (OSM) input
342
bool hadSignal() const;
343
344
/// @brief Returns the traffic lights that were assigned to this node (The set of tls that control this node)
345
const std::set<NBTrafficLightDefinition*>& getControllingTLS() const {
346
return myTrafficLights;
347
}
348
349
/// @brief causes the traffic light to be computed anew
350
void invalidateTLS(NBTrafficLightLogicCont& tlCont, bool addedConnections, bool removedConnections);
351
352
/// @brief patches loaded signal plans by modifying lane indices above threshold by the given offset
353
void shiftTLConnectionLaneIndex(NBEdge* edge, int offset, int threshold = -1);
354
/// @}
355
356
357
/// @name Prunning the input
358
/// @{
359
360
/**@brief Removes edges which are both incoming and outgoing into this node
361
*
362
* If given, the connections to other edges participating in this node are updated
363
*
364
* @param[in, opt. changed] dc The districts container to update
365
* @param[in, opt. changed] ec The edge container to remove the edges from
366
* @param[in, opt. changed] tc The traffic lights container to update
367
* @return The number of removed edges
368
*/
369
int removeSelfLoops(NBDistrictCont& dc, NBEdgeCont& ec, NBTrafficLightLogicCont& tc);
370
/// @}
371
372
373
/// @name Applying offset
374
/// @{
375
/**@brief Applies an offset to the node
376
* @param[in] xoff The x-offset to apply
377
* @param[in] yoff The y-offset to apply
378
*/
379
void reshiftPosition(double xoff, double yoff);
380
381
/// @brief ensure consistency between input and output geometries
382
void roundGeometry();
383
384
/// @brief mirror coordinates along the x-axis
385
void mirrorX();
386
/// @}
387
388
/// @brief adds an incoming edge
389
void addIncomingEdge(NBEdge* edge);
390
391
/// @brief adds an outgoing edge
392
void addOutgoingEdge(NBEdge* edge);
393
394
/// @brief computes the connections of lanes to edges
395
void computeLanes2Lanes();
396
397
/// @brief computes the node's type, logic and traffic light
398
void computeLogic(const NBEdgeCont& ec);
399
400
/// @brief compute right-of-way logic for all lane-to-lane connections
401
void computeLogic2(bool checkLaneFoes);
402
403
/// @brief compute keepClear status for all connections
404
void computeKeepClear();
405
406
/// @brief writes the XML-representation of the logic as a bitset-logic XML representation
407
bool writeLogic(OutputDevice& into) const;
408
409
/// @brief get the 'foes' string (conflict bit set) of the right-of-way logic
410
const std::string getFoes(int linkIndex) const;
411
412
/// @brief get the 'response' string (right-of-way bit set) of the right-of-way logic
413
const std::string getResponse(int linkIndex) const;
414
415
/// @brief whether there are conflicting streams of traffic at this node
416
bool hasConflict() const;
417
418
/// @brief whether the given edge has a conflicting stream of traffic at this node
419
bool hasConflict(const NBEdge* e) const;
420
421
/// @brief Returns something like the most unused direction Should only be used to add source or sink nodes
422
Position getEmptyDir() const;
423
424
/**@brief Returns whether the given edge ends at this node
425
* @param[in] e The edge
426
* @return Whether the given edge is one of this node's incoming edges
427
*/
428
bool hasIncoming(const NBEdge* const e) const;
429
430
/**@brief Returns whether the given edge starts at this node
431
* @param[in] e The edge
432
* @return Whether the given edge is one of this node's outgoing edges
433
*/
434
bool hasOutgoing(const NBEdge* const e) const;
435
436
/// @brief returns the opposite incoming edge of certain edge
437
NBEdge* getOppositeIncoming(NBEdge* e) const;
438
439
/// @brief invalidate incoming connections
440
void invalidateIncomingConnections(bool reallowSetting = false);
441
442
/// @brief invalidate outgoing connections
443
void invalidateOutgoingConnections(bool reallowSetting = false);
444
445
/// @brief remove duble edges
446
void removeDoubleEdges();
447
448
/// @brief get connection to certain node
449
NBEdge* getConnectionTo(NBNode* n) const;
450
451
/// @brief add shorted link FOES
452
void addSortedLinkFoes(const NBConnection& mayDrive, const NBConnection& mustStop);
453
454
/// @brief get possibly splitted incoming edge
455
NBEdge* getPossiblySplittedIncoming(const std::string& edgeid);
456
457
/// @brief get possibly splitted outgoing edge
458
NBEdge* getPossiblySplittedOutgoing(const std::string& edgeid);
459
460
/// @brief Removes edge from this node and optionally removes connections as well
461
void removeEdge(NBEdge* edge, bool removeFromConnections = true);
462
463
/**@brief Computes whether the given connection is a left mover across the junction
464
*
465
* It is assumed, that it is a left-mover if the clockwise angle is lower
466
* than the counter-clockwise angle.
467
*
468
* @param[in] from The incoming edge (the begin of the connection)
469
* @param[in] from The outgoing edge (the end of the connection)
470
* @return Whether the described connection is a left-mover
471
*/
472
bool isLeftMover(const NBEdge* const from, const NBEdge* const to) const;
473
474
/**@brief Returns the information whether the described flow must let any other flow pass
475
* @param[in] from The connection's start edge
476
* @param[in] to The connection's end edge
477
* @param[in] fromLane The lane the connection start at
478
* @param[in] toLane The lane the connection ends at
479
* @param[in] includePedCrossings Whether braking due to a pedestrian crossing counts
480
* @return Whether the described connection must brake (has higher priorised foes)
481
*/
482
bool mustBrake(const NBEdge* const from, const NBEdge* const to, int fromLane, int toLane, bool includePedCrossings) const;
483
484
/**@brief Returns the information whether the described flow must brake for the given crossing
485
* @param[in] from The connection's start edge
486
* @param[in] to The connection's end edge
487
* @param[in] crossing The pedestrian crossing to check
488
* @return Whether the described connection must brake (has higher priorised foes)
489
*/
490
bool mustBrakeForCrossing(const NBEdge* const from, const NBEdge* const to, const Crossing& crossing) const;
491
492
/// @brief whether a connection to the given edge must brake for a crossing when leaving the intersection
493
bool brakeForCrossingOnExit(const NBEdge* to, LinkDirection dir, bool indirect) const;
494
495
/// @brief return whether the given laneToLane connection is a right turn which must yield to a bicycle crossings
496
static bool rightTurnConflict(const NBEdge* from, const NBEdge* to, int fromLane,
497
const NBEdge* prohibitorFrom, const NBEdge* prohibitorTo, int prohibitorFromLane);
498
499
/// @brief whether one of multple connections from the same edge targeting the same lane must yield
500
bool mergeConflictYields(const NBEdge* from, int fromLane, int fromLaneFoe, NBEdge* to, int toLane) const;
501
502
/// @brief whether multiple connections from the same edge target the same lane
503
bool mergeConflict(const NBEdge* from, const NBEdge::Connection& con,
504
const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
505
506
/// @brief whether the foe connections is oncoming on the same lane
507
bool bidiConflict(const NBEdge* from, const NBEdge::Connection& con,
508
const NBEdge* prohibitorFrom, const NBEdge::Connection& prohibitorCon, bool foes) const;
509
510
bool zipperConflict(const NBEdge* incoming, const NBEdge* outgoing, int fromLane, int toLane) const;
511
512
/// @brief return whether the given laneToLane connection originate from the same edge and are in conflict due to turning across each other
513
bool turnFoes(const NBEdge* from, const NBEdge* to, int fromLane,
514
const NBEdge* from2, const NBEdge* to2, int fromLane2,
515
bool lefthand = false) const;
516
517
/**@brief Returns the information whether "prohibited" flow must let "prohibitor" flow pass
518
* @param[in] possProhibitedFrom The maybe prohibited connection's begin
519
* @param[in] possProhibitedTo The maybe prohibited connection's end
520
* @param[in] possProhibitorFrom The maybe prohibiting connection's begin
521
* @param[in] possProhibitorTo The maybe prohibiting connection's end
522
* @param[in] regardNonSignalisedLowerPriority Whether the right of way rules without traffic lights shall be regarded
523
* @return Whether the second flow prohibits the first one
524
*/
525
bool forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
526
const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
527
bool regardNonSignalisedLowerPriority) const;
528
529
/**@brief Returns the information whether the given flows cross
530
* @param[in] from1 The starting edge of the first stream
531
* @param[in] to1 The ending edge of the first stream
532
* @param[in] from2 The starting edge of the second stream
533
* @param[in] to2 The ending edge of the second stream
534
* @return Whether both stream are foes (cross)
535
*/
536
bool foes(const NBEdge* const from1, const NBEdge* const to1,
537
const NBEdge* const from2, const NBEdge* const to2) const;
538
539
/**@brief Returns the representation of the described stream's direction
540
* @param[in] incoming The edge the stream starts at
541
* @param[in] outgoing The edge the stream ends at
542
* @param[in] leftHand Whether a lefthand network is being built. Should only be set at writing time
543
* @return The direction of the stream
544
*/
545
LinkDirection getDirection(const NBEdge* const incoming, const NBEdge* const outgoing, bool leftHand = false) const;
546
547
/// @brief get link state
548
LinkState getLinkState(const NBEdge* incoming, const NBEdge* outgoing,
549
int fromLane, int toLane, bool mayDefinitelyPass, const std::string& tlID) const;
550
551
/**@brief Compute the junction shape for this node
552
* @param[in] mismatchThreshold The threshold for warning about shapes which are away from myPosition
553
*/
554
void computeNodeShape(double mismatchThreshold);
555
556
/// @brief update geometry of node and surrounding edges
557
void updateSurroundingGeometry();
558
559
/// @brief retrieve the junction shape
560
const PositionVector& getShape() const;
561
562
/// @brief set the junction shape
563
void setCustomShape(const PositionVector& shape);
564
565
/// @brief reset node shape
566
void resetShape() {
567
myPoly.clear();
568
}
569
570
/// @brief set the turning radius
571
void setRadius(double radius) {
572
myRadius = radius;
573
}
574
575
/// @brief set the keepClear flag
576
void setKeepClear(bool keepClear) {
577
myKeepClear = keepClear;
578
}
579
580
/// @brief set method for computing right-of-way
581
void setRightOfWay(RightOfWay rightOfWay) {
582
myRightOfWay = rightOfWay;
583
}
584
585
/// @brief set fringe type
586
void setFringeType(FringeType fringeType) {
587
myFringeType = fringeType;
588
}
589
590
/// @brief set roundabout type
591
void setRoundaboutType(RoundaboutType roundaboutType) {
592
myRoundaboutType = roundaboutType;
593
}
594
595
/// @brief set intersection name
596
void setName(const std::string& name) {
597
myName = name;
598
}
599
600
/// @brief return whether the shape was set by the user
601
bool hasCustomShape() const {
602
return myHaveCustomPoly;
603
}
604
605
/// @brief check if node is removable
606
bool checkIsRemovable() const;
607
608
/// @brief check if node is removable and return reason if not
609
bool checkIsRemovableReporting(std::string& reason) const;
610
611
/// @brief get edges to join
612
std::vector<std::pair<NBEdge*, NBEdge*> > getEdgesToJoin() const;
613
614
/// @chech if node is near district
615
bool isNearDistrict() const;
616
617
/// @brief check if node is a district
618
bool isDistrict() const;
619
620
/// @brief whether an internal junction should be built at from and respect other
621
bool needsCont(const NBEdge* fromE, const NBEdge* otherFromE,
622
const NBEdge::Connection& c, const NBEdge::Connection& otherC, bool checkOnlyTLS = false) const;
623
624
/// @brief whether the connection must yield if the foe remains on the intersection after its phase ends
625
bool tlsStrandedConflict(const NBEdge* from, const NBEdge::Connection& c,
626
const NBEdge* foeFrom, const NBEdge::Connection& foe) const;
627
628
629
/**@brief Compute the shape for an internal lane
630
* @param[in] fromE The starting edge
631
* @param[in] con The connection for this internal lane
632
* @param[in] numPoints The number of geometry points for the internal lane
633
* @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
634
* @return The shape of the internal lane
635
*/
636
PositionVector computeInternalLaneShape(const NBEdge* fromE, const NBEdge::Connection& con, int numPoints, NBNode* recordError = 0, int shapeFlag = 0) const;
637
638
/**@brief Compute a smooth curve between the given geometries
639
* @param[in] begShape The geometry at the start
640
* @param[in] endShape The geometry at the end
641
* @param[in] numPoints The number of geometry points for the internal lane
642
* @param[in] isTurnaround Whether this shall be the shape for a turnaround
643
* @param[in] extrapolateBeg Extrapolation distance at the beginning
644
* @param[in] extrapolateEnd Extrapolation distance at the end
645
* @param[in] recordError The node itself if the displacement error during shape computation shall be recorded
646
* @return The shape of the internal lane
647
*/
648
PositionVector computeSmoothShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints,
649
bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
650
NBNode* recordError = 0, int shapeFlag = 0) const;
651
/// @brief get bezier control points
652
static PositionVector bezierControlPoints(const PositionVector& begShape, const PositionVector& endShape,
653
bool isTurnaround, double extrapolateBeg, double extrapolateEnd,
654
bool& ok, NBNode* recordError = 0, double straightThresh = DEG2RAD(5),
655
int shapeFlag = 0);
656
657
/// @brief compute shape of indirect left turn
658
PositionVector indirectLeftShape(const PositionVector& begShape, const PositionVector& endShape, int numPoints) const;
659
660
/// @brief compute the displacement error during s-curve computation
661
double getDisplacementError() const {
662
return myDisplacementError;
663
}
664
665
/// @brief Replaces occurrences of the first edge within the list of incoming by the second Connections are remapped, too
666
void replaceIncoming(NBEdge* which, NBEdge* by, int laneOff);
667
668
/// @brief Replaces occurrences of every edge from the given list within the list of incoming by the second Connections are remapped, too
669
void replaceIncoming(const EdgeVector& which, NBEdge* by);
670
671
/// @brief Replaces occurrences of the first edge within the list of outgoing by the second Connections are remapped, too
672
void replaceOutgoing(NBEdge* which, NBEdge* by, int laneOff);
673
674
/// @brief Replaces occurrences of every edge from the given list within the list of outgoing by the second Connections are remapped, too
675
void replaceOutgoing(const EdgeVector& which, NBEdge* by);
676
677
/// @brief guess pedestrian crossings and return how many were guessed
678
int guessCrossings();
679
680
/* @brief check whether a crossing should be build for the candiate edges and build 0 to n crossings
681
* @param[in] candidates The candidate vector of edges to be crossed
682
* @param[in] checkOnly Whether only checking (of user supplied) crossings shall be performed
683
* @return The number of crossings built
684
* */
685
int checkCrossing(EdgeVector candidates, bool checkOnly = false);
686
687
/// @brief return true if there already exist a crossing with the same edges as the input
688
bool checkCrossingDuplicated(EdgeVector edges);
689
690
/// @brief build internal lanes, pedestrian crossings and walking areas
691
double buildInnerEdges();
692
693
/**@brief build pedestrian crossings
694
* @return The next index for creating internal lanes
695
**/
696
int buildCrossings();
697
698
/**@brief build pedestrian walking areas and set connections from/to walkingAreas
699
* @param[in] cornerDetail The detail level when generating the inner curve
700
*/
701
void buildWalkingAreas(int cornerDetail, double joinMinDist);
702
703
/// @brief build crossing outlines after walkingareas are finished
704
void buildCrossingOutlines();
705
706
/// @brief build crossings, and walkingareas. Also removes invalid loaded crossings if wished
707
void buildCrossingsAndWalkingAreas();
708
709
/// @brief return all edges that lie clockwise between the given edges
710
EdgeVector edgesBetween(const NBEdge* e1, const NBEdge* e2) const;
711
712
/// @brief return true if the given edges are connected by a crossing
713
bool crossingBetween(const NBEdge* e1, const NBEdge* e2) const;
714
715
/// @brief return true if the given pedestrian paths are connected at another junction within dist
716
bool alreadyConnectedPaths(const NBEdge* e1, const NBEdge* e2, double dist) const;
717
718
/// @brief return true if the given sidewalks are separated by a fringe road
719
bool crossesFringe(const NBEdge* e1, const NBEdge* e2) const;
720
721
/// @brief get prohibitions (BLocked connections)
722
const NBConnectionProhibits& getProhibitions() {
723
return myBlockedConnections;
724
}
725
726
/// @brief whether this is structurally similar to a geometry node
727
bool geometryLike() const;
728
static bool geometryLike(const EdgeVector& incoming, const EdgeVector& outgoing);
729
730
/// @brief update the type of this node as a roundabout
731
void setRoundabout();
732
733
/// @brief return whether this node is part of a roundabout
734
bool isRoundabout() const;
735
736
/// @brief add a pedestrian crossing to this node
737
NBNode::Crossing* addCrossing(EdgeVector edges, double width, bool priority, int tlIndex = -1, int tlIndex2 = -1,
738
const PositionVector& customShape = PositionVector::EMPTY, bool fromSumoNet = false, const Parameterised* params = nullptr);
739
740
/// @brief add custom shape for walkingArea
741
void addWalkingAreaShape(EdgeVector edges, const PositionVector& shape, double width);
742
743
/// @brief remove a pedestrian crossing from this node (identified by its edges)
744
void removeCrossing(const EdgeVector& edges);
745
746
/// @brief discard all current (and optionally future) crossings
747
void discardAllCrossings(bool rejectAll);
748
749
/// @brief discard previously built walkingareas (required for repeated computation by netedit)
750
void discardWalkingareas();
751
752
/// @brief get num of crossings from sumo net
753
int numCrossingsFromSumoNet() const {
754
return myCrossingsLoadedFromSumoNet;
755
}
756
757
/// @brief return this junctions pedestrian crossings
758
std::vector<Crossing*> getCrossings() const;
759
inline const std::vector<std::unique_ptr<Crossing> >& getCrossingsIncludingInvalid() const {
760
return myCrossings;
761
}
762
763
/// @brief return this junctions pedestrian walking areas
764
inline const std::vector<WalkingArea>& getWalkingAreas() const {
765
return myWalkingAreas;
766
}
767
768
const std::vector<WalkingAreaCustomShape>& getWalkingAreaCustomShapes() const {
769
return myWalkingAreaCustomShapes;
770
}
771
772
/// @brief return the crossing with the given id
773
Crossing* getCrossing(const std::string& id) const;
774
775
/// @brief return the crossing with the given Edges
776
Crossing* getCrossing(const EdgeVector& edges, bool hardFail = true) const;
777
778
/// @brief return the walkingArea with the given ID
779
WalkingArea& getWalkingArea(const std::string& id);
780
781
/* @brief set tl indices of this nodes crossing starting at the given index
782
* @return Whether a custom index was used
783
*/
784
bool setCrossingTLIndices(const std::string& tlID, int startIndex, bool ignoreCustom = false);
785
786
/// @brief return the number of lane-to-lane connections at this junction (excluding crossings)
787
int numNormalConnections() const;
788
789
/// @brief fix overlap
790
void avoidOverlap();
791
792
/// @brief whether the given index must yield to the foeIndex while turing right on a red light
793
bool extraConflict(int index, int foeIndex) const;
794
795
/// @brief sort all edge containers for this node
796
void sortEdges(bool useNodeShape);
797
798
/// @brief return the index of the given connection
799
int getConnectionIndex(const NBEdge* from, const NBEdge::Connection& con) const;
800
801
/**
802
* @class nodes_by_id_sorter
803
* @brief Used for sorting the cells by the begin time they describe
804
*/
805
class nodes_by_id_sorter {
806
public:
807
/// @brief Constructor
808
explicit nodes_by_id_sorter() { }
809
810
/// @brief Comparing operator
811
int operator()(NBNode* n1, NBNode* n2) const {
812
return n1->getID() < n2->getID();
813
}
814
};
815
816
/** @class edge_by_direction_sorter
817
* @brief Sorts outgoing before incoming edges
818
*/
819
class edge_by_direction_sorter {
820
public:
821
/// @brief constructor
822
explicit edge_by_direction_sorter(NBNode* n) : myNode(n) {}
823
824
/// @brief operator of selection
825
int operator()(NBEdge* e1, NBEdge* e2) const {
826
UNUSED_PARAMETER(e2);
827
return e1->getFromNode() == myNode;
828
}
829
830
private:
831
/// @brief The node to compute the relative angle of
832
NBNode* myNode;
833
834
};
835
836
/// @brief return whether the given type is a traffic light
837
static bool isTrafficLight(SumoXMLNodeType type);
838
839
inline bool isTrafficLight() const {
840
return isTrafficLight(myType);
841
}
842
843
/// @brief check if node is a simple continuation
844
bool isSimpleContinuation(bool checkLaneNumbers = true, bool checkWidth = false) const;
845
846
/// @brief mark whether a priority road turns at this node
847
void markBentPriority(bool isBent) {
848
myIsBentPriority = isBent;
849
}
850
851
/// @brief return whether a priority road turns at this node
852
bool isBentPriority() const {
853
return myIsBentPriority;
854
}
855
856
/// @brief return whether a priority road turns at this node
857
bool typeWasGuessed() const {
858
return myTypeWasGuessed;
859
}
860
861
/// @brief detects whether a given junction splits or merges lanes while keeping constant road width
862
bool isConstantWidthTransition() const;
863
864
/// @brief return list of unique endpoint coordinates of all edges at this node
865
std::vector<std::pair<Position, std::string> > getEndPoints() const;
866
867
/// @brief ensure connectivity for all vClasses
868
void recheckVClassConnections(NBEdge* currentOutgoing);
869
870
/// @brief initialize signalized rail classes
871
static void initRailSignalClasses(const NBNodeCont& nc);
872
873
private:
874
/// @brief sets the priorites in case of a priority junction
875
void setPriorityJunctionPriorities();
876
877
/// @brief returns a list of edges which are connected to the given outgoing edge
878
void getEdgesThatApproach(NBEdge* currentOutgoing, EdgeVector& approaching);
879
880
/// @brief replace incoming connections prohibitions
881
void replaceInConnectionProhibitions(NBEdge* which, NBEdge* by, int whichLaneOff, int byLaneOff);
882
883
/// @brief remap removed
884
void remapRemoved(NBTrafficLightLogicCont& tc, NBEdge* removed, const EdgeVector& incoming, const EdgeVector& outgoing);
885
886
/// @brief return whether there is a non-sidewalk lane after the given index;
887
bool forbidsPedestriansAfter(std::vector<std::pair<NBEdge*, bool> > normalizedLanes, int startIndex);
888
889
/// @brief returns the list of all edges sorted clockwise by getAngleAtNodeToCenter
890
EdgeVector getEdgesSortedByAngleAtNodeCenter() const;
891
892
/// @brief check if is long enough
893
static bool isLongEnough(NBEdge* out, double minLength);
894
895
/// @brief remove all traffic light definitions that are part of a joined tls
896
void removeJoinedTrafficLights();
897
898
/// @brief displace lane shapes to account for change in lane width at this node
899
void displaceShapeAtWidthChange(const NBEdge* from, const NBEdge::Connection& con, PositionVector& fromShape, PositionVector& toShape) const;
900
901
/// @brief returns whether sub is a subset of super
902
static bool includes(const std::set<const NBEdge*, ComparatorIdLess>& super,
903
const std::set<const NBEdge*, ComparatorIdLess>& sub);
904
905
NBEdge* getNextCompatibleOutgoing(const NBEdge* incoming, SVCPermissions vehPerm, EdgeVector::const_iterator start, bool clockwise) const;
906
907
/// @brief get the reduction in driving lanes at this junction
908
void getReduction(const NBEdge* in, const NBEdge* out, int& inOffset, int& inEnd, int& outOffset, int& outEnd, int& reduction) const;
909
910
/// @brief helper function to add connections for unsatisfied modes
911
SVCPermissions findToLaneForPermissions(NBEdge* currentOutgoing, int fromLane, NBEdge* incoming, SVCPermissions unsatisfied);
912
913
/// @brief check whether this edge has extra lanes on the right side
914
int addedLanesRight(NBEdge* out, int addedLanes) const;
915
916
/// @brief check whether the candidate edge is more likely to be the straight continuation
917
bool isStraighter(const NBEdge* const incoming, const double angle, const SVCPermissions vehPerm, const int modeLanes, const NBEdge* const candidate) const;
918
919
/// @brief return edges that permit passengers (either incoming or outgoing)
920
EdgeVector getPassengerEdges(bool incoming) const;
921
922
/// @brief detect explict rail turns with potential geometry problem
923
static bool isExplicitRailNoBidi(const NBEdge* incoming, const NBEdge* outgoing);
924
925
/// @brief geometry helper that cuts the first shape where bordered by the other two
926
PositionVector cutAtShapes(const PositionVector& cut, const PositionVector& border1, const PositionVector& border2, const PositionVector& def);
927
928
/// @brief compute offset for centering path-across-street crossings
929
void patchOffset_pathAcrossStreet(double& offset);
930
931
/// @brief whether the given rail connections at this node may run in unsignalized (right-of-way) mode
932
bool unsignalizedOperation() const;
933
934
/// @brief ensure connectivity for all special vClass
935
void recheckSpecialConnections(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial);
936
937
/// @brief helper function for recheckSpecialConnections
938
bool avoidConfict(NBEdge* incoming, NBEdge* currentOutgoing, SVCPermissions svcSpecial, LinkDirection dir, int i);
939
940
private:
941
/// @brief The position the node lies at
942
Position myPosition;
943
944
/// @brief Vector of incoming edges
945
EdgeVector myIncomingEdges;
946
947
/// @brief Vector of outgoing edges
948
EdgeVector myOutgoingEdges;
949
950
/// @brief Vector of incoming and outgoing edges
951
EdgeVector myAllEdges;
952
953
/// @brief Vector of crossings
954
std::vector<std::unique_ptr<Crossing> > myCrossings;
955
956
/// @brief Vector of walking areas
957
std::vector<WalkingArea> myWalkingAreas;
958
959
/// @brief Vector of custom walking areas shapes
960
std::vector<WalkingAreaCustomShape> myWalkingAreaCustomShapes;
961
962
/// @brief The type of the junction
963
SumoXMLNodeType myType;
964
965
/// @brief The container for connection block dependencies
966
NBConnectionProhibits myBlockedConnections;
967
968
/// @brief The district the node is the centre of
969
NBDistrict* myDistrict;
970
971
/// @brief the (outer) shape of the junction
972
PositionVector myPoly;
973
974
/// @brief whether this nodes shape was set by the user
975
bool myHaveCustomPoly;
976
977
/// @brief Node requests
978
NBRequest* myRequest;
979
980
/// @brief traffic lights of node
981
std::set<NBTrafficLightDefinition*> myTrafficLights;
982
983
/// @brief the turning radius (for all corners) at this node in m.
984
double myRadius;
985
986
/// @brief whether the junction area must be kept clear
987
bool myKeepClear;
988
989
/// @brief how to compute right of way for this node
990
RightOfWay myRightOfWay;
991
992
/// @brief fringe type of this node
993
FringeType myFringeType;
994
995
/// @brief roundabout type of this node
996
RoundaboutType myRoundaboutType;
997
998
/// @brief The intersection name (or whatever arbitrary string you wish to attach)
999
std::string myName;
1000
1001
/// @brief whether to discard all pedestrian crossings
1002
bool myDiscardAllCrossings;
1003
1004
/// @brief number of crossings loaded from a sumo net
1005
int myCrossingsLoadedFromSumoNet;
1006
1007
/// @brief geometry error after computation of internal lane shapes
1008
double myDisplacementError;
1009
1010
/* @brief whether this junction is a bent priority junction (main direction turns)
1011
* @note see NBEdgePriorityComputer
1012
*/
1013
bool myIsBentPriority;
1014
1015
/// @brief whether the node type was guessed rather than loaded
1016
bool myTypeWasGuessed;
1017
1018
/// @brief all vehicle classes for which rail signals exist
1019
static SVCPermissions myHaveRailSignalClasses;
1020
1021
/// @brief all rail classes for which operation without rail signals is permitted
1022
static SVCPermissions myPermitUnsignalizedClasses;
1023
1024
private:
1025
/// @brief invalidated copy constructor
1026
NBNode(const NBNode& s);
1027
1028
/// @brief invalidated assignment operator
1029
NBNode& operator=(const NBNode& s);
1030
};
1031
1032