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