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