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