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