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 NBEdge.h 11 /// @author Daniel Krajzewicz 12 /// @author Jakob Erdmann 13 /// @author Michael Behrisch 14 /// @date Tue, 20 Nov 2001 15 /// @version $Id$ 16 /// 17 // The representation of a single edge during network building 18 /****************************************************************************/ 19 #ifndef NBEdge_h 20 #define NBEdge_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 #include <config.h> 27 28 #include <map> 29 #include <vector> 30 #include <string> 31 #include <set> 32 #include <cassert> 33 #include <utils/common/Named.h> 34 #include <utils/common/Parameterised.h> 35 #include <utils/common/UtilExceptions.h> 36 #include <utils/common/VectorHelper.h> 37 #include <utils/geom/Bresenham.h> 38 #include <utils/geom/PositionVector.h> 39 #include <utils/common/SUMOVehicleClass.h> 40 #include <utils/xml/SUMOXMLDefinitions.h> 41 #include "NBCont.h" 42 #include "NBHelpers.h" 43 #include "NBSign.h" 44 45 46 // =========================================================================== 47 // class declarations 48 // =========================================================================== 49 class NBNode; 50 class NBConnection; 51 class NBNodeCont; 52 class NBEdgeCont; 53 class OutputDevice; 54 class GNELane; 55 class NBVehicle; 56 57 58 // =========================================================================== 59 // class definitions 60 // =========================================================================== 61 /** 62 * @class NBEdge 63 * @brief The representation of a single edge during network building 64 */ 65 class NBEdge : public Named, public Parameterised { 66 friend class NBEdgeCont; 67 68 /** used for visualization (NETEDIT) */ 69 friend class GNELane; 70 friend class GNEEdge; 71 friend class GNEJunction; 72 73 public: 74 75 /** @enum EdgeBuildingStep 76 * @brief Current state of the edge within the building process 77 * 78 * As the network is build in a cascaded way, considering loaded 79 * information, a counter holding the current step is needed. This is done 80 * by using this enumeration. 81 */ 82 enum EdgeBuildingStep { 83 /// @brief The edge has been loaded and connections shall not be added 84 INIT_REJECT_CONNECTIONS, 85 /// @brief The edge has been loaded, nothing is computed yet 86 INIT, 87 /// @brief The relationships between edges are computed/loaded 88 EDGE2EDGES, 89 /// @brief Lanes to edges - relationships are computed/loaded 90 LANES2EDGES, 91 /// @brief Lanes to lanes - relationships are computed; should be recheked 92 LANES2LANES_RECHECK, 93 /// @brief Lanes to lanes - relationships are computed; no recheck is necessary/wished 94 LANES2LANES_DONE, 95 /// @brief Lanes to lanes - relationships are loaded; no recheck is necessary/wished 96 LANES2LANES_USER 97 }; 98 99 100 /** @enum Lane2LaneInfoType 101 * @brief Modes of setting connections between lanes 102 */ 103 enum Lane2LaneInfoType { 104 /// @brief The connection was computed 105 L2L_COMPUTED, 106 /// @brief The connection was given by the user 107 L2L_USER, 108 /// @brief The connection was computed and validated 109 L2L_VALIDATED 110 }; 111 112 113 /** @struct Lane 114 * @brief An (internal) definition of a single lane of an edge 115 */ 116 struct Lane : public Parameterised { 117 /// @brief constructor 118 Lane(NBEdge* e, const std::string& _origID); 119 120 /// @brief The lane's shape 121 PositionVector shape; 122 123 /// @brief The speed allowed on this lane 124 double speed; 125 126 /// @brief List of vehicle types that are allowed on this lane 127 SVCPermissions permissions; 128 129 /// @brief List of vehicle types that are preferred on this lane 130 SVCPermissions preferred; 131 132 /// @brief This lane's offset to the intersection begin 133 double endOffset; 134 135 /// @brief stopOffsets.second - The stop offset for vehicles stopping at the lane's end. 136 /// Applies if vClass is in in stopOffset.first bitset 137 std::map<int, double> stopOffsets; 138 139 /// @brief This lane's width 140 double width; 141 142 /// @brief An opposite lane ID, if given 143 std::string oppositeID; 144 145 /// @brief Whether this lane is an acceleration lane 146 bool accelRamp; 147 148 /// @brief Whether connection information for this lane is already completed 149 // @note (see NIImporter_DlrNavteq::ConnectedLanesHandler) 150 bool connectionsDone; 151 152 /// @brief A custom shape for this lane set by the user 153 PositionVector customShape; 154 }; 155 156 157 /** @struct Connection 158 * @brief A structure which describes a connection between edges or lanes 159 */ 160 struct Connection : public Parameterised { 161 /** @brief Constructor 162 * @param[in] fromLane_ The lane the connections starts at 163 * @param[in] toEdge_ The edge the connections yields in 164 * @param[in] toLane_ The lane the connections yields in 165 */ 166 Connection(int fromLane_, NBEdge* toEdge_, int toLane_); 167 168 /// @brief constructor with more parameters 169 Connection(int fromLane_, NBEdge* toEdge_, int toLane_, bool mayDefinitelyPass_, 170 bool keepClear_ = true, 171 double contPos_ = UNSPECIFIED_CONTPOS, 172 double visibility_ = UNSPECIFIED_VISIBILITY_DISTANCE, 173 double speed_ = UNSPECIFIED_SPEED, 174 bool haveVia_ = false, 175 bool uncontrolled_ = false, 176 const PositionVector& customShape_ = PositionVector::EMPTY); 177 178 /// @brief destructor ~ConnectionConnection179 ~Connection() { } 180 181 /// @brief The lane the connections starts at 182 int fromLane; 183 184 /// @brief The edge the connections yields in 185 NBEdge* toEdge; 186 187 /// @brief The lane the connections yields in 188 int toLane; 189 190 /// @brief The id of the traffic light that controls this connection 191 std::string tlID; 192 193 /// @brief The index of this connection within the controlling traffic light 194 int tlLinkIndex; 195 196 /// @brief Information about being definitely free to drive (on-ramps) 197 bool mayDefinitelyPass; 198 199 /// @brief whether the junction must be kept clear when using this connection 200 bool keepClear; 201 202 /// @brief custom position for internal junction on this connection 203 double contPos; 204 205 /// @brief custom foe visiblity for connection 206 double visibility; 207 208 /// @brief custom speed for connection 209 double speed; 210 211 /// @brief custom shape for connection 212 PositionVector customShape; 213 214 /// @brief id of Connection 215 std::string id; 216 217 /// @brief shape of Connection 218 PositionVector shape; 219 220 /// @brief maximum velocity 221 double vmax; 222 223 /// @brief check if Connection have a Via 224 bool haveVia; 225 226 /// @brief if Connection have a via, ID of it 227 std::string viaID; 228 229 /// @brief shape of via 230 PositionVector viaShape; 231 232 /// @brief FOE Internal links 233 std::vector<int> foeInternalLinks; 234 235 /// @brief FOE Incomings lanes 236 std::vector<std::string> foeIncomingLanes; 237 238 /// @brief The lane index of this internal lane within the internal edge 239 int internalLaneIndex; 240 241 /// @brief check if Connection is uncontrolled 242 bool uncontrolled; 243 244 /// @brief get ID of internal lane 245 std::string getInternalLaneID() const; 246 247 /// @brief get string describing this connection 248 std::string getDescription(const NBEdge* parent) const; 249 250 /// @brief computed length (average of all internal lane shape lengths that share an internal edge) 251 double length; 252 }; 253 254 /// @brief Dummy edge to use when a reference must be supplied in the no-arguments constructor (FOX technicality) 255 static NBEdge DummyEdge; 256 257 /// @brief unspecified lane width 258 static const double UNSPECIFIED_WIDTH; 259 260 /// @brief unspecified lane offset 261 static const double UNSPECIFIED_OFFSET; 262 263 /// @brief unspecified lane speed 264 static const double UNSPECIFIED_SPEED; 265 266 /// @brief unspecified internal junction position 267 static const double UNSPECIFIED_CONTPOS; 268 269 /// @brief unspecified foe visibility for connections 270 static const double UNSPECIFIED_VISIBILITY_DISTANCE; 271 272 /// @brief no length override given 273 static const double UNSPECIFIED_LOADED_LENGTH; 274 275 /// @brief unspecified signal offset 276 static const double UNSPECIFIED_SIGNAL_OFFSET; 277 278 /// @brief the distance at which to take the default angle 279 static const double ANGLE_LOOKAHEAD; 280 281 /// @brief internal lane computation not yet done 282 static const int UNSPECIFIED_INTERNAL_LANE_INDEX; 283 284 /// @brief TLS-controlled despite its node controlled not specified. 285 static const bool UNSPECIFIED_CONNECTION_UNCONTROLLED; 286 287 /// @brief junction priority values set by setJunctionPriority 288 enum JunctionPriority { 289 MINOR_ROAD = 0, 290 PRIORITY_ROAD = 1, 291 ROUNDABOUT = 1000 292 }; 293 294 public: 295 /** @brief Constructor 296 * 297 * Use this if no edge geometry is given. 298 * 299 * @param[in] id The id of the edge 300 * @param[in] from The node the edge starts at 301 * @param[in] to The node the edge ends at 302 * @param[in] type The type of the edge (my be =="") 303 * @param[in] speed The maximum velocity allowed on this edge 304 * @param[in] nolanes The number of lanes this edge has 305 * @param[in] priority This edge's priority 306 * @param[in] width This edge's lane width 307 * @param[in] endOffset Additional offset to the destination node 308 * @param[in] streetName The street name (need not be unique) 309 * @param[in] spread How the lateral offset of the lanes shall be computed 310 * @see init 311 * @see LaneSpreadFunction 312 */ 313 NBEdge(const std::string& id, 314 NBNode* from, NBNode* to, std::string type, 315 double speed, int nolanes, int priority, 316 double width, double endOffset, 317 const std::string& streetName = "", 318 LaneSpreadFunction spread = LANESPREAD_RIGHT); 319 320 321 /** @brief Constructor 322 * 323 * Use this if the edge's geometry is given. 324 * 325 * @param[in] id The id of the edge 326 * @param[in] from The node the edge starts at 327 * @param[in] to The node the edge ends at 328 * @param[in] type The type of the edge (may be =="") 329 * @param[in] speed The maximum velocity allowed on this edge 330 * @param[in] nolanes The number of lanes this edge has 331 * @param[in] priority This edge's priority 332 * @param[in] width This edge's lane width 333 * @param[in] endOffset Additional offset to the destination node 334 * @param[in] geom The edge's geomatry 335 * @param[in] streetName The street name (need not be unique) 336 * @param[in] origID The original ID in the source network (need not be unique) 337 * @param[in] spread How the lateral offset of the lanes shall be computed 338 * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2 339 * @see init 340 * @see LaneSpreadFunction 341 */ 342 NBEdge(const std::string& id, 343 NBNode* from, NBNode* to, std::string type, 344 double speed, int nolanes, int priority, 345 double width, double endOffset, 346 PositionVector geom, 347 const std::string& streetName = "", 348 const std::string& origID = "", 349 LaneSpreadFunction spread = LANESPREAD_RIGHT, 350 bool tryIgnoreNodePositions = false); 351 352 /** @brief Constructor 353 * 354 * Use this to copy attribuets from another edge 355 * 356 * @param[in] id The id of the edge 357 * @param[in] from The node the edge starts at 358 * @param[in] to The node the edge ends at 359 * @param[in] tpl The template edge to copy attributes from 360 * @param[in] geom The geometry to use (may be empty) 361 * @param[in] numLanes The number of lanes of the new edge (copy from tpl by default) 362 */ 363 NBEdge(const std::string& id, 364 NBNode* from, NBNode* to, 365 const NBEdge* tpl, 366 const PositionVector& geom = PositionVector(), 367 int numLanes = -1); 368 369 370 /// @brief Destructor 371 ~NBEdge(); 372 373 374 /** @brief Resets initial values 375 * 376 * @param[in] from The node the edge starts at 377 * @param[in] to The node the edge ends at 378 * @param[in] type The type of the edge (may be =="") 379 * @param[in] speed The maximum velocity allowed on this edge 380 * @param[in] nolanes The number of lanes this edge has 381 * @param[in] priority This edge's priority 382 * @param[in] geom The edge's geomatry 383 * @param[in] width This edge's lane width 384 * @param[in] endOffset Additional offset to the destination node 385 * @param[in] streetName The street name (need not be unique) 386 * @param[in] spread How the lateral offset of the lanes shall be computed 387 * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2 388 */ 389 void reinit(NBNode* from, NBNode* to, const std::string& type, 390 double speed, int nolanes, int priority, 391 PositionVector geom, double width, double endOffset, 392 const std::string& streetName, 393 LaneSpreadFunction spread = LANESPREAD_RIGHT, 394 bool tryIgnoreNodePositions = false); 395 396 /** @brief Resets nodes but keeps all other values the same (used when joining) 397 * @param[in] from The node the edge starts at 398 * @param[in] to The node the edge ends at 399 */ 400 void reinitNodes(NBNode* from, NBNode* to); 401 402 /// @name Applying offset 403 /// @{ 404 /** @brief Applies an offset to the edge 405 * @param[in] xoff The x-offset to apply 406 * @param[in] yoff The y-offset to apply 407 */ 408 void reshiftPosition(double xoff, double yoff); 409 410 /// @brief mirror coordinates along the x-axis 411 void mirrorX(); 412 /// @} 413 414 /// @name Atomar getter methods 415 //@{ 416 417 /** @brief Returns the number of lanes 418 * @returns This edge's number of lanes 419 */ getNumLanes()420 int getNumLanes() const { 421 return (int)myLanes.size(); 422 } 423 424 /** @brief Returns the priority of the edge 425 * @return This edge's priority 426 */ getPriority()427 int getPriority() const { 428 return myPriority; 429 } 430 431 /** @brief Returns the origin node of the edge 432 * @return The node this edge starts at 433 */ getFromNode()434 NBNode* getFromNode() const { 435 return myFrom; 436 } 437 438 /** @brief Returns the destination node of the edge 439 * @return The node this edge ends at 440 */ getToNode()441 NBNode* getToNode() const { 442 return myTo; 443 } 444 445 /** @brief Returns the angle at the start of the edge 446 * (relative to the node shape center) 447 * The angle is computed in computeAngle() 448 * @return This edge's start angle 449 */ getStartAngle()450 inline double getStartAngle() const { 451 return myStartAngle; 452 } 453 454 /** @brief Returns the angle at the end of the edge 455 * (relative to the node shape center) 456 * The angle is computed in computeAngle() 457 * @return This edge's end angle 458 */ getEndAngle()459 inline double getEndAngle() const { 460 return myEndAngle; 461 } 462 463 /** @brief Returns the angle at the start of the edge 464 * @note only using edge shape 465 * @return This edge's start angle 466 */ 467 double getShapeStartAngle() const; 468 469 470 /** @brief Returns the angle at the end of the edge 471 * @note only using edge shape 472 * @note The angle is computed in computeAngle() 473 * @return This edge's end angle 474 */ 475 double getShapeEndAngle() const; 476 477 /** @brief Returns the angle at the start of the edge 478 * @note The angle is computed in computeAngle() 479 * @return This edge's angle 480 */ getTotalAngle()481 inline double getTotalAngle() const { 482 return myTotalAngle; 483 } 484 485 /** @brief Returns the computed length of the edge 486 * @return The edge's computed length 487 */ getLength()488 double getLength() const { 489 return myLength; 490 } 491 492 493 /** @brief Returns the length was set explicitly or the computed length if it wasn't set 494 * @todo consolidate use of myLength and myLoaded length 495 * @return The edge's specified length 496 */ getLoadedLength()497 double getLoadedLength() const { 498 return myLoadedLength > 0 ? myLoadedLength : myLength; 499 } 500 501 /// @brief get length that will be assigned to the lanes in the final network 502 double getFinalLength() const; 503 504 /** @brief Returns whether a length was set explicitly 505 * @return Wether the edge's length was specified 506 */ hasLoadedLength()507 bool hasLoadedLength() const { 508 return myLoadedLength > 0; 509 } 510 511 /** @brief Returns the speed allowed on this edge 512 * @return The maximum speed allowed on this edge 513 */ getSpeed()514 double getSpeed() const { 515 return mySpeed; 516 } 517 518 /** @brief The building step of this edge 519 * @return The current building step for this edge 520 * @todo Recheck usage! 521 * @see EdgeBuildingStep 522 */ getStep()523 EdgeBuildingStep getStep() const { 524 return myStep; 525 } 526 527 /** @brief Returns the default width of lanes of this edge 528 * @return The width of lanes of this edge 529 */ getLaneWidth()530 double getLaneWidth() const { 531 return myLaneWidth; 532 } 533 534 /** @brief Returns the width of the lane of this edge 535 * @return The width of the lane of this edge 536 */ 537 double getLaneWidth(int lane) const; 538 539 /// @brief Returns the combined width of all lanes of this edge 540 double getTotalWidth() const; 541 542 /// @brief Returns the street name of this edge getStreetName()543 const std::string& getStreetName() const { 544 return myStreetName; 545 } 546 547 /// @brief sets the street name of this edge setStreetName(const std::string & name)548 void setStreetName(const std::string& name) { 549 myStreetName = name; 550 } 551 552 /** @brief Returns the offset to the destination node 553 * @return The offset to the destination node 554 */ getEndOffset()555 double getEndOffset() const { 556 return myEndOffset; 557 } 558 559 /** @brief Returns the stopOffset to the end of the edge 560 * @return The offset to the end of the edge 561 */ getStopOffsets()562 const std::map<int, double>& getStopOffsets() const { 563 return myStopOffsets; 564 } 565 566 /** @brief Returns the offset to the destination node a the specified lane 567 * @return The offset to the destination node 568 */ 569 double getEndOffset(int lane) const; 570 571 /** @brief Returns the stop offset to the specified lane's end 572 * @return The stop offset to the specified lane's end 573 */ 574 const std::map<int, double>& getStopOffsets(int lane) const; 575 576 /// @brief Returns the offset of a traffic signal from the end of this edge getSignalOffset()577 double getSignalOffset() const { 578 return mySignalOffset; 579 } 580 581 /// @brief Returns the node that (possibly) represents a traffic signal controlling at the end of this edge getSignalNode()582 NBNode* getSignalNode() const { 583 return mySignalNode; 584 } 585 586 /// @brief sets the offset of a traffic signal from the end of this edge setSignalOffset(double offset,NBNode * signalNode)587 void setSignalOffset(double offset, NBNode* signalNode) { 588 mySignalOffset = offset; 589 mySignalNode = signalNode; 590 } 591 592 /** @brief Returns the lane definitions 593 * @return The stored lane definitions 594 */ getLanes()595 const std::vector<NBEdge::Lane>& getLanes() const { 596 return myLanes; 597 } 598 //@} 599 600 /** @brief return the first lane with permissions other than SVC_PEDESTRIAN and 0 601 * @param[in] direction The direction in which the lanes shall be checked 602 * @param[in] exclusive Whether lanes that allow pedestrians along with other classes shall be counted as non-pedestrian 603 */ 604 int getFirstNonPedestrianLaneIndex(int direction, bool exclusive = false) const; 605 606 /// @brief return index of the first lane that allows the given permissions 607 int getSpecialLane(SVCPermissions permissions) const; 608 609 /** @brief return the first lane that permits at least 1 vClass or the last lane if search direction of there is no such lane 610 * @param[in] direction The direction in which the lanes shall be checked 611 */ 612 int getFirstAllowedLaneIndex(int direction) const; 613 614 /// @brif get first non-pedestrian lane 615 NBEdge::Lane getFirstNonPedestrianLane(int direction) const; 616 617 /// @brief return all permission variants within the specified lane range [iStart, iEnd[ 618 std::set<SVCPermissions> getPermissionVariants(int iStart, int iEnd) const; 619 620 /// @brief return the angle for computing pedestrian crossings at the given node 621 double getCrossingAngle(NBNode* node); 622 623 /// @brief get the lane id for the canonical sidewalk lane 624 std::string getSidewalkID(); 625 626 /// @name Edge geometry access and computation 627 //@{ 628 /** @brief Returns the geometry of the edge 629 * @return The edge's geometry 630 */ getGeometry()631 const PositionVector& getGeometry() const { 632 return myGeom; 633 } 634 635 /// @brief Returns the geometry of the edge without the endpoints 636 const PositionVector getInnerGeometry() const; 637 638 /// @brief Returns whether the geometry consists only of the node positions 639 bool hasDefaultGeometry() const; 640 641 /** @brief Returns whether the geometry is terminated by the node positions 642 * This default may be violated by initializing with 643 * tryIgnoreNodePositions=true' or with setGeometry() 644 * non-default endpoints are useful to control the generated node shape 645 */ 646 bool hasDefaultGeometryEndpoints() const; 647 648 /** @brief Returns whether the geometry is terminated by the node positions 649 * This default may be violated by initializing with 650 * tryIgnoreNodePositions=true' or with setGeometry() 651 * non-default endpoints are useful to control the generated node shape 652 */ 653 bool hasDefaultGeometryEndpointAtNode(const NBNode* node) const; 654 655 /** @brief (Re)sets the edge's geometry 656 * 657 * Replaces the edge's prior geometry by the given. Then, computes 658 * the geometries of all lanes using computeLaneShapes. 659 * Definitely not the best way to have it accessable from outside... 660 * @param[in] g The edge's new geometry 661 * @param[in] inner whether g should be interpreted as inner points 662 * @todo Recheck usage, disallow access 663 * @see computeLaneShapes 664 */ 665 void setGeometry(const PositionVector& g, bool inner = false); 666 667 /** @brief Adds a further geometry point 668 * 669 * Some importer do not know an edge's geometry when it is initialised. 670 * This method allows to insert further geometry points after the edge 671 * has been built. 672 * 673 * @param[in] index The position at which the point shall be added 674 * @param[in] p The point to add 675 */ 676 void addGeometryPoint(int index, const Position& p); 677 678 /// @brief linearly extend the geometry at the given node 679 void extendGeometryAtNode(const NBNode* node, double maxExtent); 680 681 /// @brief linearly extend the geometry at the given node 682 void shortenGeometryAtNode(const NBNode* node, double reduction); 683 684 /// @brief shift geometry at the given node to avoid overlap 685 void shiftPositionAtNode(NBNode* node, NBEdge* opposite); 686 687 /** @brief Recomputeds the lane shapes to terminate at the node shape 688 * For every lane the intersection with the fromNode and toNode is 689 * calculated and the lane shorted accordingly. The edge length is then set 690 * to the average of all lane lenghts (which may differ). This average length is used as the lane 691 * length when writing the network. 692 * @note All lanes of an edge in a sumo net must have the same nominal length 693 * but may differ in actual geomtric length. 694 * @note Depends on previous call to NBNodeCont::computeNodeShapes 695 */ 696 void computeEdgeShape(double smoothElevationThreshold = -1); 697 698 /** @brief Returns the shape of the nth lane 699 * @return The shape of the lane given by its index (counter from right) 700 */ 701 const PositionVector& getLaneShape(int i) const; 702 703 /** @brief (Re)sets how the lanes lateral offset shall be computed 704 * @param[in] spread The type of lateral offset to apply 705 * @see LaneSpreadFunction 706 */ 707 void setLaneSpreadFunction(LaneSpreadFunction spread); 708 709 /** @brief Returns how this edge's lanes' lateral offset is computed 710 * @return The type of lateral offset that is applied on this edge 711 * @see LaneSpreadFunction 712 */ getLaneSpreadFunction()713 LaneSpreadFunction getLaneSpreadFunction() const { 714 return myLaneSpreadFunction; 715 } 716 717 /** @brief Splits this edge at geometry points 718 * @param[in] ec The edge cont to add new edges to 719 * @param[in] nc The node cont to add new nodes to 720 * @return Whether the geometry was changed 721 */ 722 bool splitGeometry(NBEdgeCont& ec, NBNodeCont& nc); 723 724 /** @brief Removes points with a distance lesser than the given 725 * @param[in] minDist The minimum distance between two position to keep the second 726 */ 727 void reduceGeometry(const double minDist); 728 729 /** @brief Check the angles of successive geometry segments 730 * @param[in] maxAngle The maximum angle allowed 731 * @param[in] minRadius The minimum turning radius allowed at the start and end 732 * @param[in] fix Whether to prune geometry points to avoid sharp turns at start and end 733 */ 734 void checkGeometry(const double maxAngle, const double minRadius, bool fix); 735 //@} 736 737 /// @name Setting and getting connections 738 /// @{ 739 /** @brief Adds a connection to another edge 740 * 741 * If the given edge does not start at the node this edge ends on, false is returned. 742 * 743 * All other cases return true. Though, a connection may not been added if this edge 744 * is in step "INIT_REJECT_CONNECTIONS". Also, this method assures that a connection 745 * to an edge is set only once, no multiple connections to next edge are stored. 746 * 747 * After a first connection to an edge was set, the process step is set to "EDGE2EDGES". 748 * @note Passing 0 implicitly removes all existing connections 749 * 750 * @param[in] dest The connection's destination edge 751 * @return Whether the connection was valid 752 */ 753 bool addEdge2EdgeConnection(NBEdge* dest); 754 755 /** @brief Adds a connection between the specified this edge's lane and an approached one 756 * 757 * If the given edge does not start at the node this edge ends on, false is returned. 758 * 759 * All other cases return true. Though, a connection may not been added if this edge 760 * is in step "INIT_REJECT_CONNECTIONS". Before the lane-to-lane connection is set, 761 * a connection between edges is established using "addEdge2EdgeConnection". Then, 762 * "setConnection" is called for inserting the lane-to-lane connection. 763 * 764 * @param[in] fromLane The connection's starting lane (of this edge) 765 * @param[in] dest The connection's destination edge 766 * @param[in] toLane The connection's destination lane 767 * @param[in] type The connections's type 768 * @param[in] mayUseSameDestination Whether this connection may be set though connecting an already connected lane 769 * @param[in] mayDefinitelyPass Whether this connection is definitely undistrubed (special case for on-ramps) 770 * @return Whether the connection was added / exists 771 * @see addEdge2EdgeConnection 772 * @see setConnection 773 * @todo Check difference between "setConnection" and "addLane2LaneConnection" 774 */ 775 bool addLane2LaneConnection(int fromLane, NBEdge* dest, 776 int toLane, Lane2LaneInfoType type, 777 bool mayUseSameDestination = false, 778 bool mayDefinitelyPass = false, 779 bool keepClear = true, 780 double contPos = UNSPECIFIED_CONTPOS, 781 double visibility = UNSPECIFIED_VISIBILITY_DISTANCE, 782 double speed = UNSPECIFIED_SPEED, 783 const PositionVector& customShape = PositionVector::EMPTY, 784 const bool uncontrolled = UNSPECIFIED_CONNECTION_UNCONTROLLED); 785 786 /** @brief Builds no connections starting at the given lanes 787 * 788 * If "invalidatePrevious" is true, a call to "invalidateConnections(true)" is done. 789 * This method loops through the given connections to set, calling "addLane2LaneConnection" 790 * for each. 791 * 792 * @param[in] fromLane The first of the connections' starting lanes (of this edge) 793 * @param[in] dest The connections' destination edge 794 * @param[in] toLane The first of the connections' destination lanes 795 * @param[in] no The number of connections to set 796 * @param[in] type The connections' type 797 * @param[in] invalidatePrevious Whether previously set connection shall be deleted 798 * @param[in] mayDefinitelyPass Whether these connections are definitely undistrubed (special case for on-ramps) 799 * @return Whether the connections were added / existed 800 * @see addLane2LaneConnection 801 * @see invalidateConnections 802 */ 803 bool addLane2LaneConnections(int fromLane, 804 NBEdge* dest, int toLane, int no, 805 Lane2LaneInfoType type, bool invalidatePrevious = false, 806 bool mayDefinitelyPass = false); 807 808 /** @brief Adds a connection to a certain lane of a certain edge 809 * 810 * @param[in] lane The connection's starting lane (of this edge) 811 * @param[in] destEdge The connection's destination edge 812 * @param[in] destLane The connection's destination lane 813 * @param[in] type The connections's type 814 * @param[in] mayUseSameDestination Whether this connection may be set though connecting an already connected lane 815 * @param[in] mayDefinitelyPass Whether this connection is definitely undistrubed (special case for on-ramps) 816 * @todo Check difference between "setConnection" and "addLane2LaneConnection" 817 */ 818 bool setConnection(int lane, NBEdge* destEdge, 819 int destLane, 820 Lane2LaneInfoType type, 821 bool mayUseSameDestination = false, 822 bool mayDefinitelyPass = false, 823 bool keepClear = true, 824 double contPos = UNSPECIFIED_CONTPOS, 825 double visibility = UNSPECIFIED_VISIBILITY_DISTANCE, 826 double speed = UNSPECIFIED_SPEED, 827 const PositionVector& customShape = PositionVector::EMPTY, 828 const bool uncontrolled = UNSPECIFIED_CONNECTION_UNCONTROLLED); 829 830 /** @brief Returns connections from a given lane 831 * 832 * This method goes through "myConnections" and copies those which are 833 * starting at the given lane. 834 * @param[in] lane The lane which connections shall be returned 835 * @param[in] to The target Edge (ignore nullptr) 836 * @param[in] toLane The target lane (ignore if > 0) 837 * @return The connections from the given lane 838 * @see NBEdge::Connection 839 */ 840 std::vector<Connection> getConnectionsFromLane(int lane, NBEdge* to = nullptr, int toLane = -1) const; 841 842 /** @brief Returns the specified connection 843 * This method goes through "myConnections" and returns the specified one 844 * @see NBEdge::Connection 845 */ 846 Connection getConnection(int fromLane, const NBEdge* to, int toLane) const; 847 848 /** @brief Returns reference to the specified connection 849 * This method goes through "myConnections" and returns the specified one 850 * @see NBEdge::Connection 851 */ 852 Connection& getConnectionRef(int fromLane, const NBEdge* to, int toLane); 853 854 /** @brief Retrieves info about a connection to a certain lane of a certain edge 855 * 856 * Turnaround edge is ignored! 857 * @param[in] destEdge The connection's destination edge 858 * @param[in] destLane The connection's destination lane 859 * @param[in] fromLane If a value >= 0 is given, only return true if a connection from the given lane exists 860 * @return whether a connection to the specified lane exists 861 */ 862 bool hasConnectionTo(NBEdge* destEdge, int destLane, int fromLane = -1) const; 863 864 /** @brief Returns the information whethe a connection to the given edge has been added (or computed) 865 * 866 * Turnaround edge is not ignored! 867 * @param[in] e The destination edge 868 * @return Whether a connection to the specified edge exists 869 */ 870 bool isConnectedTo(const NBEdge* e) const; 871 872 /** @brief Returns the connections 873 * @return This edge's connections to following edges 874 */ getConnections()875 const std::vector<Connection>& getConnections() const { 876 return myConnections; 877 } 878 879 /** @brief Returns the connections 880 * @return This edge's connections to following edges 881 */ getConnections()882 std::vector<Connection>& getConnections() { 883 return myConnections; 884 } 885 886 /** @brief Returns the list of outgoing edges without the turnaround sorted in clockwise direction 887 * @return Connected edges, sorted clockwise 888 */ 889 const EdgeVector* getConnectedSorted(); 890 891 /** @brief Returns the list of outgoing edges unsorted 892 * @return Connected edges 893 */ 894 EdgeVector getConnectedEdges() const; 895 896 /** @brief Returns the list of incoming edges unsorted 897 * @return Connected predecessor edges 898 */ 899 EdgeVector getIncomingEdges() const; 900 901 /** @brief Returns the list of lanes that may be used to reach the given edge 902 * @return Lanes approaching the given edge 903 */ 904 std::vector<int> getConnectionLanes(NBEdge* currentOutgoing, bool withBikes = true) const; 905 906 /// @brief sorts the outgoing connections by their angle relative to their junction 907 void sortOutgoingConnectionsByAngle(); 908 909 /// @brief sorts the outgoing connections by their from-lane-index and their to-lane-index 910 void sortOutgoingConnectionsByIndex(); 911 912 /** @brief Remaps the connection in a way that allows the removal of it 913 * 914 * This edge (which is a self loop edge, in fact) connections are spread over the valid incoming edges 915 * @todo recheck! 916 */ 917 void remapConnections(const EdgeVector& incoming); 918 919 /** @brief Removes the specified connection(s) 920 * @param[in] toEdge The destination edge 921 * @param[in] fromLane The lane from which connections shall be removed; -1 means remove all 922 * @param[in] toLane The lane to which connections shall be removed; -1 means remove all 923 * @param[in] tryLater If the connection does not exist, try again during recheckLanes() 924 * @param[in] adaptToLaneRemoval we are in the process of removing a complete lane, adapt all connections accordingly 925 */ 926 void removeFromConnections(NBEdge* toEdge, int fromLane = -1, int toLane = -1, bool tryLater = false, const bool adaptToLaneRemoval = false, const bool keepPossibleTurns = false); 927 928 /// @brief remove an existent connection of edge 929 bool removeFromConnections(NBEdge::Connection connectionToRemove); 930 931 /// @brief invalidate current connections of edge 932 void invalidateConnections(bool reallowSetting = false); 933 934 /// @brief replace in current connections of edge 935 void replaceInConnections(NBEdge* which, NBEdge* by, int laneOff); 936 937 /// @brief replace in current connections of edge 938 void replaceInConnections(NBEdge* which, const std::vector<NBEdge::Connection>& origConns); 939 940 /// @brief copy connections from antoher edge 941 void copyConnectionsFrom(NBEdge* src); 942 943 /// @brief modifify the toLane for all connections to the given edge 944 void shiftToLanesToEdge(NBEdge* to, int laneOff); 945 /// @} 946 947 /** @brief Returns whether the given edge is the opposite direction to this edge 948 * @param[in] edge The edge which may be the turnaround direction 949 * @return Whether the given edge is this edge's turnaround direction 950 * (regardless of whether a connection exists) 951 */ 952 bool isTurningDirectionAt(const NBEdge* const edge) const; 953 954 /** @brief Sets the turing destination at the given edge 955 * @param[in] e The turn destination 956 * @param[in] onlyPossible If true, only sets myPossibleTurnDestination 957 */ 958 void setTurningDestination(NBEdge* e, bool onlyPossible = false); 959 960 /// @name Setting/getting special types 961 /// @{ 962 /// @brief Marks this edge as a macroscopic connector setAsMacroscopicConnector()963 void setAsMacroscopicConnector() { 964 myAmMacroscopicConnector = true; 965 } 966 967 /** @brief Returns whether this edge was marked as a macroscopic connector 968 * @return Whether this edge was marked as a macroscopic connector 969 */ isMacroscopicConnector()970 bool isMacroscopicConnector() const { 971 return myAmMacroscopicConnector; 972 } 973 974 /// @brief Marks this edge being within an intersection setInternal()975 void setInternal() { 976 myAmInnerEdge = true; 977 } 978 979 /** @brief Returns whether this edge was marked as being within an intersection 980 * @return Whether this edge was marked as being within an intersection 981 */ isInternal()982 bool isInternal() const { 983 return myAmInnerEdge; 984 } 985 /// @} 986 987 /** @brief Sets the junction priority of the edge 988 * @param[in] node The node for which the edge's priority is given 989 * @param[in] prio The edge's new priority at this node 990 * @todo Maybe the edge priority whould be stored in the node 991 */ 992 void setJunctionPriority(const NBNode* const node, int prio); 993 994 /** @brief Returns the junction priority (normalised for the node currently build) 995 * 996 * If the given node is neither the edge's start nor the edge's ending node, the behaviour 997 * is undefined. 998 * 999 * @param[in] node The node for which the edge's priority shall be returned 1000 * @return The edge's priority at the given node 1001 * @todo Maybe the edge priority whould be stored in the node 1002 */ 1003 int getJunctionPriority(const NBNode* const node) const; 1004 1005 /// @brief set loaded lenght 1006 void setLoadedLength(double val); 1007 1008 /// @brief dimiss vehicle class information 1009 void dismissVehicleClassInformation(); 1010 1011 /// @brief get ID of type getTypeID()1012 const std::string& getTypeID() const { 1013 return myType; 1014 } 1015 1016 /// @brief whether at least one lane has values differing from the edges values 1017 bool needsLaneSpecificOutput() const; 1018 1019 /// @brief whether at least one lane has restrictions 1020 bool hasPermissions() const; 1021 1022 /// @brief whether lanes differ in allowed vehicle classes 1023 bool hasLaneSpecificPermissions() const; 1024 1025 /// @brief whether lanes differ in speed 1026 bool hasLaneSpecificSpeed() const; 1027 1028 /// @brief whether lanes differ in width 1029 bool hasLaneSpecificWidth() const; 1030 1031 /// @brief whether lanes differ in offset 1032 bool hasLaneSpecificEndOffset() const; 1033 1034 /// @brief whether lanes differ in stopOffsets 1035 bool hasLaneSpecificStopOffsets() const; 1036 1037 /// @brief whether one of the lanes is an acceleration lane 1038 bool hasAccelLane() const; 1039 1040 /// @brief whether one of the lanes has a custom shape 1041 bool hasCustomLaneShape() const; 1042 1043 /// @brief whether one of the lanes has parameters set 1044 bool hasLaneParams() const; 1045 1046 /// @brief computes the edge (step1: computation of approached edges) 1047 bool computeEdge2Edges(bool noLeftMovers); 1048 1049 /// @brief computes the edge, step2: computation of which lanes approach the edges) 1050 bool computeLanes2Edges(); 1051 1052 /// @brief recheck whether all lanes within the edge are all right and optimises the connections once again 1053 bool recheckLanes(); 1054 1055 /** @brief Add a connection to the previously computed turnaround, if wished 1056 * 1057 * If a turning direction exists (myTurnDestination!=0) and either the 1058 * edge is not controlled by a tls or noTLSControlled is false, a connection 1059 * to the edge stored in myTurnDestination is added (from the leftmost lane 1060 * of this edge to the leftmost lane of myTurnDestination). 1061 * @param[in] noTLSControlled Whether the turnaround shall not be connected if this edge is controlled by a tls 1062 */ 1063 void appendTurnaround(bool noTLSControlled, bool onlyDeadends, bool noGeometryLike, bool checkPermissions); 1064 1065 /** @brief Returns the node at the given edges length (using an epsilon) 1066 @note When no node is existing at the given position, 0 is returned 1067 The epsilon is a static member of NBEdge, should be setable via program options */ 1068 NBNode* tryGetNodeAtPosition(double pos, double tolerance = 5.0) const; 1069 1070 /// @brief get max lane offset 1071 double getMaxLaneOffset(); 1072 1073 /// @brief Check if lanes were assigned 1074 bool lanesWereAssigned() const; 1075 1076 /// @brief return true if certain connection must be controlled by TLS 1077 bool mayBeTLSControlled(int fromLane, NBEdge* toEdge, int toLane) const; 1078 1079 /// @brief Returns if the link could be set as to be controlled 1080 bool setControllingTLInformation(const NBConnection& c, const std::string& tlID); 1081 1082 /// @brief clears tlID for all connections 1083 void clearControllingTLInformation(); 1084 1085 /// @brief add crossing points as incoming with given outgoing 1086 void addCrossingPointsAsIncomingWithGivenOutgoing(NBEdge* o, PositionVector& into); 1087 1088 /// @brief get the outer boundary of this edge when going clock-wise around the given node 1089 PositionVector getCWBoundaryLine(const NBNode& n) const; 1090 1091 /// @brief get the outer boundary of this edge when going counter-clock-wise around the given node 1092 PositionVector getCCWBoundaryLine(const NBNode& n) const; 1093 1094 /// @brief Check if Node is expandable 1095 bool expandableBy(NBEdge* possContinuation, std::string& reason) const; 1096 1097 /// @brief append another edge 1098 void append(NBEdge* continuation); 1099 1100 /// @brief Check if edge has signalised connections 1101 bool hasSignalisedConnectionTo(const NBEdge* const e) const; 1102 1103 /// @brief move outgoing connection 1104 void moveOutgoingConnectionsFrom(NBEdge* e, int laneOff); 1105 1106 /* @brief return the turn destination if it exists 1107 * @param[in] possibleDestination Wether myPossibleTurnDestination should be returned if no turnaround connection 1108 * exists 1109 */ 1110 NBEdge* getTurnDestination(bool possibleDestination = false) const; 1111 1112 /// @brief get lane ID 1113 std::string getLaneID(int lane) const; 1114 1115 /// @brief get lane speed 1116 double getLaneSpeed(int lane) const; 1117 1118 /// @brief Check if edge is near enought to be joined to another edge 1119 bool isNearEnough2BeJoined2(NBEdge* e, double threshold) const; 1120 1121 /** @brief Returns the angle of the edge's geometry at the given node 1122 * 1123 * The angle is signed, regards direction, and starts at 12 o'clock 1124 * (north->south), proceeds positive clockwise. 1125 * @param[in] node The node for which the edge's angle shall be returned 1126 * @return This edge's angle at the given node 1127 */ 1128 double getAngleAtNode(const NBNode* const node) const; 1129 1130 /** @brief Returns the angle of from the node shape center to where the edge meets 1131 * the node shape 1132 * 1133 * The angle is signed, disregards direction, and starts at 12 o'clock 1134 * (north->south), proceeds positive clockwise. 1135 * @param[in] node The node for which the edge's angle shall be returned 1136 * @return This edge's angle at the given node shape 1137 */ 1138 double getAngleAtNodeToCenter(const NBNode* const node) const; 1139 1140 /// @brief increment lane 1141 void incLaneNo(int by); 1142 1143 /// @brief decrement lane 1144 void decLaneNo(int by); 1145 1146 /// @brief delete lane 1147 void deleteLane(int index, bool recompute, bool shiftIndices); 1148 1149 /// @brief add lane 1150 void addLane(int index, bool recomputeShape, bool recomputeConnections, bool shiftIndices); 1151 1152 /// @brief mark edge as in lane to state lane 1153 void markAsInLane2LaneState(); 1154 1155 /// @brief add a pedestrian sidewalk of the given width and shift existing connctions 1156 void addSidewalk(double width); 1157 1158 /// @brief restore an previously added sidewalk 1159 void restoreSidewalk(std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections); 1160 1161 /// add a bicycle lane of the given width and shift existing connctions 1162 void addBikeLane(double width); 1163 1164 /// @brief restore an previously added BikeLane 1165 void restoreBikelane(std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections); 1166 1167 /// @brief set allowed/disallowed classes for the given lane or for all lanes if -1 is given 1168 void setPermissions(SVCPermissions permissions, int lane = -1); 1169 1170 /// @brief set preferred Vehicle Class 1171 void setPreferredVehicleClass(SVCPermissions permissions, int lane = -1); 1172 1173 /// @brief set allowed class for the given lane or for all lanes if -1 is given 1174 void allowVehicleClass(int lane, SUMOVehicleClass vclass); 1175 1176 /// @brief set disallowed class for the given lane or for all lanes if -1 is given 1177 void disallowVehicleClass(int lane, SUMOVehicleClass vclass); 1178 1179 /// @brief prefer certain vehicle class 1180 void preferVehicleClass(int lane, SUMOVehicleClass vclass); 1181 1182 /// @brief set lane specific width (negative lane implies set for all lanes) 1183 void setLaneWidth(int lane, double width); 1184 1185 /// @brief set lane specific end-offset (negative lane implies set for all lanes) 1186 void setEndOffset(int lane, double offset); 1187 1188 /// @brief set lane specific speed (negative lane implies set for all lanes) 1189 void setSpeed(int lane, double speed); 1190 1191 /// @brief set lane and vehicle class specific stopOffset (negative lane implies set for all lanes) 1192 /// @return Whether given stop offset was applied. 1193 bool setStopOffsets(int lane, std::map<int, double> offsets, bool overwrite = false); 1194 1195 /// @brief marks one lane as acceleration lane 1196 void setAcceleration(int lane, bool accelRamp); 1197 1198 /// @brief sets a custom lane shape 1199 void setLaneShape(int lane, const PositionVector& shape); 1200 1201 /// @brief get the union of allowed classes over all lanes or for a specific lane 1202 SVCPermissions getPermissions(int lane = -1) const; 1203 1204 /// @brief set origID for all lanes 1205 void setOrigID(const std::string origID); 1206 1207 /// @brief disable connections for TLS 1208 void disableConnection4TLS(int fromLane, NBEdge* toEdge, int toLane); 1209 1210 // @brief returns a reference to the internal structure for the convenience of NETEDIT getLaneStruct(int lane)1211 Lane& getLaneStruct(int lane) { 1212 assert(lane >= 0); 1213 assert(lane < (int)myLanes.size()); 1214 return myLanes[lane]; 1215 } 1216 1217 // @brief returns a reference to the internal structure for the convenience of NETEDIT getLaneStruct(int lane)1218 const Lane& getLaneStruct(int lane) const { 1219 assert(lane >= 0); 1220 assert(lane < (int)myLanes.size()); 1221 return myLanes[lane]; 1222 } 1223 1224 /// @brief declares connections as fully loaded. This is needed to avoid recomputing connections if an edge has no connections intentionally. 1225 void declareConnectionsAsLoaded(EdgeBuildingStep step = LANES2LANES_USER) { 1226 myStep = step; 1227 } 1228 1229 /* @brief fill connection attributes shape, viaShape, ... 1230 * 1231 * @param[in,out] edgeIndex The number of connections already handled 1232 * @param[in,out] splitIndex The number of via edges already built 1233 * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2 1234 */ 1235 void buildInnerEdges(const NBNode& n, int noInternalNoSplits, int& linkIndex, int& splitIndex); 1236 1237 /// @brief get Signs getSigns()1238 inline const std::vector<NBSign>& getSigns() const { 1239 return mySigns; 1240 } 1241 1242 /// @brief add Sign addSign(NBSign sign)1243 inline void addSign(NBSign sign) { 1244 mySigns.push_back(sign); 1245 } 1246 1247 /// @brief cut shape at the intersection shapes 1248 PositionVector cutAtIntersection(const PositionVector& old) const; 1249 1250 /// @brief Set Node border 1251 void setNodeBorder(const NBNode* node, const Position& p, const Position& p2, bool rectangularCut); 1252 const PositionVector& getNodeBorder(const NBNode* node); 1253 void resetNodeBorder(const NBNode* node); 1254 1255 /// @brief whether this edge is part of a bidirectional railway 1256 bool isBidiRail(bool ignoreSpread = false) const; 1257 1258 /// @brief whether this edge is a railway edge that does not continue 1259 bool isRailDeadEnd() const; 1260 1261 /// @brief debugging helper to print all connections 1262 void debugPrintConnections(bool outgoing = true, bool incoming = false) const; 1263 1264 /// @brief compute the first intersection point between the given lane geometries considering their rspective widths 1265 static double firstIntersection(const PositionVector& v1, const PositionVector& v2, double width2); 1266 1267 /** returns a modified version of laneShape which starts at the outside of startNode. laneShape may be shorted or extended 1268 * @note see [wiki:Developer/Network_Building_Process] 1269 */ 1270 static PositionVector startShapeAt(const PositionVector& laneShape, const NBNode* startNode, PositionVector nodeShape); 1271 1272 /// @name functions for router usage 1273 //@{ 1274 getTravelTimeStatic(const NBEdge * const edge,const NBVehicle * const,double)1275 static inline double getTravelTimeStatic(const NBEdge* const edge, const NBVehicle* const /*veh*/, double /*time*/) { 1276 return edge->getLength() / edge->getSpeed(); 1277 } 1278 1279 static int getLaneIndexFromLaneID(const std::string laneID); 1280 1281 /// @brief sets the index of the edge in the list of all network edges setNumericalID(int index)1282 void setNumericalID(int index) { 1283 myIndex = index; 1284 } 1285 1286 /** @brief Returns the index (numeric id) of the edge 1287 * @note This is only used in the context of routing 1288 * @return This edge's numerical id 1289 */ getNumericalID()1290 int getNumericalID() const { 1291 return myIndex; 1292 } 1293 1294 /** @brief Returns the following edges for the given vClass 1295 */ 1296 const EdgeVector& getSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const; 1297 1298 1299 /** @brief Returns the following edges for the given vClass 1300 */ 1301 const NBConstEdgePairVector& getViaSuccessors(SUMOVehicleClass vClass = SVC_IGNORING) const; 1302 1303 //@} 1304 1305 private: 1306 /** @class ToEdgeConnectionsAdder 1307 * @brief A class that being a bresenham-callback assigns the incoming lanes to the edges 1308 */ 1309 class ToEdgeConnectionsAdder : public Bresenham::BresenhamCallBack { 1310 private: 1311 /// @brief map of edges to this edge's lanes that reach them 1312 std::map<NBEdge*, std::vector<int> > myConnections; 1313 1314 /// @brief the transition from the virtual lane to the edge it belongs to 1315 const EdgeVector& myTransitions; 1316 1317 public: 1318 /// @brief constructor ToEdgeConnectionsAdder(const EdgeVector & transitions)1319 ToEdgeConnectionsAdder(const EdgeVector& transitions) 1320 : myTransitions(transitions) { } 1321 1322 /// @brief destructor ~ToEdgeConnectionsAdder()1323 ~ToEdgeConnectionsAdder() { } 1324 1325 /// @brief executes a bresenham - step 1326 void execute(const int lane, const int virtEdge); 1327 1328 /// @brief get built connections getBuiltConnections()1329 const std::map<NBEdge*, std::vector<int> >& getBuiltConnections() const { 1330 return myConnections; 1331 } 1332 1333 private: 1334 /// @brief Invalidated copy constructor. 1335 ToEdgeConnectionsAdder(const ToEdgeConnectionsAdder&); 1336 1337 /// @brief Invalidated assignment operator. 1338 ToEdgeConnectionsAdder& operator=(const ToEdgeConnectionsAdder&); 1339 }; 1340 1341 1342 /** 1343 * @class MainDirections 1344 * @brief Holds (- relative to the edge it is build from -!!!) the list of 1345 * main directions a vehicle that drives on this street may take on 1346 * the junction the edge ends in 1347 * The back direction is not regarded 1348 */ 1349 class MainDirections { 1350 public: 1351 /// @brief enum of possible directions 1352 enum Direction { DIR_RIGHTMOST, DIR_LEFTMOST, DIR_FORWARD }; 1353 1354 public: 1355 /// @brief constructor 1356 MainDirections(const EdgeVector& outgoing, NBEdge* parent, NBNode* to, const std::vector<int>& availableLanes); 1357 1358 /// @brief destructor 1359 ~MainDirections(); 1360 1361 /// @brief returns the index of the straightmost among the given outgoing edges getStraightest()1362 int getStraightest() const { 1363 return myStraightest; 1364 } 1365 1366 /// @brief returns the information whether no following street has a higher priority 1367 bool empty() const; 1368 1369 /// @brief returns the information whether the street in the given direction has a higher priority 1370 bool includes(Direction d) const; 1371 1372 private: 1373 /// @brief the index of the straightmost among the given outgoing edges 1374 int myStraightest; 1375 1376 /// @brief list of the main direction within the following junction relative to the edge 1377 std::vector<Direction> myDirs; 1378 1379 /// @brief Invalidated copy constructor. 1380 MainDirections(const MainDirections&); 1381 1382 /// @brief Invalidated assignment operator. 1383 MainDirections& operator=(const MainDirections&); 1384 }; 1385 1386 /// @brief Computes the shape for the given lane 1387 PositionVector computeLaneShape(int lane, double offset) const; 1388 1389 /// @brief compute lane shapes 1390 void computeLaneShapes(); 1391 1392 private: 1393 /** @brief Initialization routines common to all constructors 1394 * 1395 * Checks whether the number of lanes>0, whether the junction's from- 1396 * and to-nodes are given (!=0) and whether they are distict. Throws 1397 * a ProcessError if any of these checks fails. 1398 * 1399 * Adds the nodes positions to geometry if it shall not be ignored or 1400 * if the geometry is empty. 1401 * 1402 * Computes the angle and length, and adds this edge to its node as 1403 * outgoing/incoming. Builds lane informations. 1404 * 1405 * @param[in] noLanes The number of lanes this edge has 1406 * @param[in] tryIgnoreNodePositions Does not add node geometries if geom.size()>=2 1407 * @param[in] origID The original ID this edge had 1408 */ 1409 void init(int noLanes, bool tryIgnoreNodePositions, const std::string& origID); 1410 1411 /// @brief divides the lanes on the outgoing edges 1412 void divideOnEdges(const EdgeVector* outgoing); 1413 1414 /// @brief divide selected lanes on edges 1415 void divideSelectedLanesOnEdges(const EdgeVector* outgoing, const std::vector<int>& availableLanes); 1416 1417 /// @brief add some straight connections 1418 void addStraightConnections(const EdgeVector* outgoing, const std::vector<int>& availableLanes, const std::vector<int>& priorities); 1419 1420 /// @brief recomputes the edge priorities and manipulates them for a distribution of lanes on edges which is more like in real-life 1421 const std::vector<int> prepareEdgePriorities(const EdgeVector* outgoing, const std::vector<int>& availableLanes); 1422 1423 /// @name Setting and getting connections 1424 /// @{ 1425 /** @briefmoves a connection one place to the left; 1426 * @note Attention! no checking for field validity 1427 */ 1428 void moveConnectionToLeft(int lane); 1429 1430 /** @briefmoves a connection one place to the right; 1431 * @noteAttention! no checking for field validity 1432 */ 1433 void moveConnectionToRight(int lane); 1434 1435 /// @brief whether the connection can originate on newFromLane 1436 bool canMoveConnection(const Connection& con, int newFromLane) const; 1437 /// @} 1438 1439 /// @brief computes the angle of this edge and stores it in myAngle 1440 void computeAngle(); 1441 1442 /// @brief determine conflict between opposite left turns 1443 bool bothLeftIntersect(const NBNode& n, const PositionVector& shape, LinkDirection dir, NBEdge* otherFrom, const NBEdge::Connection& otherCon, int numPoints, double width2, int shapeFlag = 0) const; 1444 1445 /// @brief add a lane of the given width, restricted to the given class and shift existing connections 1446 void addRestrictedLane(double width, SUMOVehicleClass vclass); 1447 1448 /// @brief restore a restricted lane 1449 void restoreRestrictedLane(SUMOVehicleClass vclass, std::vector<NBEdge::Lane> oldLanes, PositionVector oldGeometry, std::vector<NBEdge::Connection> oldConnections); 1450 1451 /// @brief assign length to all lanes of an internal edge 1452 void assignInternalLaneLength(std::vector<Connection>::iterator i, int numLanes, double lengthSum); 1453 1454 private: 1455 /** @brief The building step 1456 * @see EdgeBuildingStep 1457 */ 1458 EdgeBuildingStep myStep; 1459 1460 /// @brief The type of the edge 1461 std::string myType; 1462 1463 /// @brief The source and the destination node 1464 NBNode* myFrom, *myTo; 1465 1466 /// @brief The length of the edge 1467 double myLength; 1468 1469 /// @brief The angles of the edge 1470 /// @{ 1471 double myStartAngle; 1472 double myEndAngle; 1473 double myTotalAngle; 1474 /// @} 1475 1476 /// @brief The priority of the edge 1477 int myPriority; 1478 1479 /// @brief The maximal speed 1480 double mySpeed; 1481 1482 /** @brief List of connections to following edges 1483 * @see Connection 1484 */ 1485 std::vector<Connection> myConnections; 1486 1487 /// @brief List of connections marked for delayed removal 1488 std::vector<Connection> myConnectionsToDelete; 1489 1490 /// @brief The turn destination edge (if a connection exists) 1491 NBEdge* myTurnDestination; 1492 1493 /// @brief The edge that would be the turn destination if there was one 1494 NBEdge* myPossibleTurnDestination; 1495 1496 /// @brief The priority normalised for the node the edge is outgoing of 1497 int myFromJunctionPriority; 1498 1499 /// @brief The priority normalised for the node the edge is incoming in 1500 int myToJunctionPriority; 1501 1502 /// @brief The geometry for the edge 1503 PositionVector myGeom; 1504 1505 /// @brief The information about how to spread the lanes 1506 LaneSpreadFunction myLaneSpreadFunction; 1507 1508 /// @brief This edges's offset to the intersection begin (will be applied to all lanes) 1509 double myEndOffset; 1510 1511 /// @brief A vClass specific stop offset - assumed of length 0 (unspecified) or 1. 1512 /// For the latter case the int is a bit set specifying the vClasses, 1513 /// the offset applies to (see SUMOVehicleClass.h), and the double is the 1514 /// stopping offset in meters from the lane end 1515 std::map<int, double> myStopOffsets; 1516 1517 /// @brief This width of this edge's lanes 1518 double myLaneWidth; 1519 1520 /** @brief Lane information 1521 * @see Lane 1522 */ 1523 std::vector<Lane> myLanes; 1524 1525 /// @brief An optional length to use (-1 if not valid) 1526 double myLoadedLength; 1527 1528 /// @brief Information whether this is a junction-inner edge 1529 bool myAmInnerEdge; 1530 1531 /// @brief Information whether this edge is a (macroscopic) connector 1532 bool myAmMacroscopicConnector; 1533 1534 /// @brief The street name (or whatever arbitrary string you wish to attach) 1535 std::string myStreetName; 1536 1537 /// @brief the street signs along this edge 1538 std::vector<NBSign> mySigns; 1539 1540 /// @brief the offset of a traffic light signal from the end of this edge (-1 for None) 1541 double mySignalOffset; 1542 NBNode* mySignalNode; 1543 1544 /// @brief intersection borders (because the node shape might be invalid) 1545 /// @{ 1546 PositionVector myFromBorder; 1547 PositionVector myToBorder; 1548 /// @} 1549 1550 1551 /// @brief the index of the edge in the list of all edges. Set by NBEdgeCont and requires re-set whenever the list of edges changes 1552 int myIndex; 1553 1554 // @brief a static list of successor edges. Set by NBEdgeCont and requires reset when the network changes 1555 mutable EdgeVector mySuccessors; 1556 1557 // @brief a static list of successor edges. Set by NBEdgeCont and requires reset when the network changes 1558 mutable NBConstEdgePairVector myViaSuccessors; 1559 1560 public: 1561 1562 /// @class connections_toedge_finder 1563 class connections_toedge_finder { 1564 public: 1565 /// @brief constructor 1566 connections_toedge_finder(const NBEdge* const edge2find, bool hasFromLane = false) : myHasFromLane(hasFromLane)1567 myHasFromLane(hasFromLane), 1568 myEdge2Find(edge2find) { } 1569 1570 /// @brief operator () operator()1571 bool operator()(const Connection& c) const { 1572 return c.toEdge == myEdge2Find && (!myHasFromLane || c.fromLane != -1); 1573 } 1574 1575 private: 1576 /// @brief check if has from lane 1577 const bool myHasFromLane; 1578 1579 /// @brief edge to find 1580 const NBEdge* const myEdge2Find; 1581 1582 private: 1583 /// @brief invalidated assignment operator 1584 connections_toedge_finder& operator=(const connections_toedge_finder& s); 1585 }; 1586 1587 /// @class connections_toedgelane_finder 1588 class connections_toedgelane_finder { 1589 public: 1590 /// @brief constructor connections_toedgelane_finder(NBEdge * const edge2find,int lane2find,int fromLane2find)1591 connections_toedgelane_finder(NBEdge* const edge2find, int lane2find, int fromLane2find) : 1592 myEdge2Find(edge2find), 1593 myLane2Find(lane2find), 1594 myFromLane2Find(fromLane2find) { } 1595 1596 /// @brief operator () operator()1597 bool operator()(const Connection& c) const { 1598 return c.toEdge == myEdge2Find && c.toLane == myLane2Find && (myFromLane2Find < 0 || c.fromLane == myFromLane2Find); 1599 } 1600 1601 private: 1602 /// @brief edge to find 1603 NBEdge* const myEdge2Find; 1604 1605 /// @brief lane to find 1606 int myLane2Find; 1607 1608 /// @brief from lane to find 1609 int myFromLane2Find; 1610 1611 private: 1612 /// @brief invalidated assignment operator 1613 connections_toedgelane_finder& operator=(const connections_toedgelane_finder& s); 1614 1615 }; 1616 1617 /// @class connections_finder 1618 class connections_finder { 1619 public: 1620 /// @brief constructor 1621 connections_finder(int fromLane, NBEdge* const edge2find, int lane2find, bool invertEdge2find = false) : myFromLane(fromLane)1622 myFromLane(fromLane), myEdge2Find(edge2find), myLane2Find(lane2find), myInvertEdge2find(invertEdge2find) { } 1623 1624 /// @brief operator () operator()1625 bool operator()(const Connection& c) const { 1626 return ((c.fromLane == myFromLane || myFromLane == -1) 1627 && ((!myInvertEdge2find && c.toEdge == myEdge2Find) || (myInvertEdge2find && c.toEdge != myEdge2Find)) 1628 && (c.toLane == myLane2Find || myLane2Find == -1)); 1629 } 1630 1631 private: 1632 /// @brief index of from lane 1633 int myFromLane; 1634 1635 /// @brief edge to find 1636 NBEdge* const myEdge2Find; 1637 1638 /// @brief lane to find 1639 int myLane2Find; 1640 1641 /// @brief invert edge to find 1642 bool myInvertEdge2find; 1643 1644 private: 1645 /// @brief invalidated assignment operator 1646 connections_finder& operator=(const connections_finder& s); 1647 1648 }; 1649 1650 /// @class connections_conflict_finder 1651 class connections_conflict_finder { 1652 public: 1653 /// @brief constructor connections_conflict_finder(int fromLane,NBEdge * const edge2find,bool checkRight)1654 connections_conflict_finder(int fromLane, NBEdge* const edge2find, bool checkRight) : 1655 myFromLane(fromLane), myEdge2Find(edge2find), myCheckRight(checkRight) { } 1656 1657 /// @brief operator () operator()1658 bool operator()(const Connection& c) const { 1659 return (((myCheckRight && c.fromLane < myFromLane) || (!myCheckRight && c.fromLane > myFromLane)) 1660 && c.fromLane >= 0 // already assigned 1661 && c.toEdge == myEdge2Find); 1662 } 1663 1664 private: 1665 /// @brief index of from lane 1666 int myFromLane; 1667 1668 /// @brief edge to find 1669 NBEdge* const myEdge2Find; 1670 1671 /// @brief check if is right 1672 bool myCheckRight; 1673 1674 private: 1675 /// @brief invalidated assignment operator 1676 connections_conflict_finder& operator=(const connections_conflict_finder& s); 1677 1678 }; 1679 1680 /// @class connections_fromlane_finder 1681 class connections_fromlane_finder { 1682 public: 1683 /// @briefconstructor connections_fromlane_finder(int lane2find)1684 connections_fromlane_finder(int lane2find) : myLane2Find(lane2find) { } 1685 1686 /// @brief operator () operator()1687 bool operator()(const Connection& c) const { 1688 return c.fromLane == myLane2Find; 1689 } 1690 1691 private: 1692 /// @brief index of lane to find 1693 int myLane2Find; 1694 1695 private: 1696 /// @brief invalidated assignment operator 1697 connections_fromlane_finder& operator=(const connections_fromlane_finder& s); 1698 1699 }; 1700 1701 /// @brief connections_sorter sort by fromLane, toEdge and toLane 1702 static bool connections_sorter(const Connection& c1, const Connection& c2); 1703 1704 /** 1705 * @class connections_relative_edgelane_sorter 1706 * @brief Class to sort edges by their angle 1707 */ 1708 class connections_relative_edgelane_sorter { 1709 public: 1710 /// @brief constructor connections_relative_edgelane_sorter(NBEdge * e)1711 explicit connections_relative_edgelane_sorter(NBEdge* e) : myEdge(e) {} 1712 1713 public: 1714 /// @brief comparing operation 1715 int operator()(const Connection& c1, const Connection& c2) const; 1716 1717 private: 1718 /// @brief the edge to compute the relative angle of 1719 NBEdge* myEdge; 1720 }; 1721 1722 private: 1723 /// @brief invalidated copy constructor 1724 NBEdge(const NBEdge& s); 1725 1726 /// @brief invalidated assignment operator 1727 NBEdge& operator=(const NBEdge& s); 1728 1729 /// @brief constructor for dummy edge 1730 NBEdge(); 1731 1732 }; 1733 1734 1735 #endif 1736 1737 /****************************************************************************/ 1738 1739