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