sumolib.net.lane

  1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
  2# Copyright (C) 2011-2026 German Aerospace Center (DLR) and others.
  3# This program and the accompanying materials are made available under the
  4# terms of the Eclipse Public License 2.0 which is available at
  5# https://www.eclipse.org/legal/epl-2.0/
  6# This Source Code may also be made available under the following Secondary
  7# Licenses when the conditions for such availability set forth in the Eclipse
  8# Public License 2.0 are satisfied: GNU General Public License, version 2
  9# or later which is available at
 10# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
 11# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
 12
 13# @file    lane.py
 14# @author  Daniel Krajzewicz
 15# @author  Laura Bieker
 16# @author  Karol Stosiek
 17# @author  Michael Behrisch
 18# @author  Jakob Erdmann
 19# @date    2011-11-28
 20
 21
 22import sumolib.geomhelper
 23from functools import reduce
 24
 25# taken from sumo/src/utils/common/SUMOVehicleClass.cpp
 26SUMO_VEHICLE_CLASSES = set([
 27    "public_emergency",  # deprecated
 28    "public_authority",  # deprecated
 29    "public_army",       # deprecated
 30    "public_transport",  # deprecated
 31    "transport",         # deprecated
 32    "lightrail",         # deprecated
 33    "cityrail",          # deprecated
 34    "rail_slow",         # deprecated
 35    "rail_fast",         # deprecated
 36
 37    "private",
 38    "emergency",
 39    "authority",
 40    "army",
 41    "vip",
 42    "passenger",
 43    "hov",
 44    "taxi",
 45    "bus",
 46    "coach",
 47    "delivery",
 48    "truck",
 49    "trailer",
 50    "tram",
 51    "rail_urban",
 52    "rail",
 53    "rail_electric",
 54    "motorcycle",
 55    "moped",
 56    "bicycle",
 57    "pedestrian",
 58    "evehicle",
 59    "ship",
 60    "container",
 61    "cable_car",
 62    "subway",
 63    "aircraft",
 64    "wheelchair",
 65    "scooter",
 66    "drone",
 67    "custom1",
 68    "custom2"])
 69
 70SUMO_VEHICLE_CLASSES_DEPRECATED = set([
 71    "public_emergency",
 72    "public_authority",
 73    "public_army",
 74    "public_transport",
 75    "transport",
 76    "lightrail",
 77    "cityrail",
 78    "rail_slow",
 79    "rail_fast"])
 80
 81
 82def is_vehicle_class(s):
 83    return s in SUMO_VEHICLE_CLASSES
 84
 85
 86def get_allowed(allow, disallow):
 87    """Normalize the given string attributes as a set of all allowed vClasses."""
 88    if allow is None and disallow is None:
 89        return SUMO_VEHICLE_CLASSES
 90    elif disallow is None:
 91        return set(allow.split())
 92    elif disallow == "all":
 93        return set()
 94    else:
 95        return SUMO_VEHICLE_CLASSES.difference(disallow.split())
 96
 97
 98def addJunctionPos(shape, fromPos, toPos):
 99    """Extends shape with the given positions in case they differ from the
100    existing endpoints. assumes that shape and positions have the same dimensionality"""
101    result = list(shape)
102    if fromPos != shape[0]:
103        result = [fromPos] + result
104    if toPos != shape[-1]:
105        result.append(toPos)
106    return result
107
108
109class Lane:
110
111    """ Lanes from a sumo network """
112
113    def __init__(self, edge, speed, length, width, allow, disallow, acceleration):
114        self._edge = edge
115        self._speed = speed
116        self._length = length
117        self._width = width
118        self._shape = None
119        self._shape3D = None
120        self._shapeWithJunctions = None
121        self._shapeWithJunctions3D = None
122        self._outgoing = []
123        self._params = {}
124        self._allowed = get_allowed(allow, disallow)
125        self._neigh = None
126        self._selected = False
127        self._acceleration = acceleration
128        self._lengthGeometryFactor = 1
129        edge.addLane(self)
130
131    def getSpeed(self):
132        return self._speed
133
134    def getLength(self):
135        return self._length
136
137    def getWidth(self):
138        return self._width
139
140    def setShape(self, shape):
141        """Set the shape of the lane
142
143        shape must be a list containing x,y,z coords as numbers
144        to represent the shape of the lane
145        """
146        for pp in shape:
147            if len(pp) != 3:
148                raise ValueError('shape point must consist of x,y,z')
149
150        self._shape3D = shape
151        self._shape = [(x, y) for x, y, z in shape]
152        shapeLength = sumolib.geomhelper.polyLength(self.getShape())
153        if shapeLength > 0:
154            self._lengthGeometryFactor = self.getLength() / shapeLength
155
156    def getShape(self, includeJunctions=False):
157        """Returns the shape of the lane in 2d.
158
159        This function returns the shape of the lane, as defined in the net.xml
160        file. The returned shape is a list containing numerical
161        2-tuples representing the x,y coordinates of the shape points.
162
163        For includeJunctions=True the returned list will contain
164        additionally the coords (x,y) of the fromNode of the
165        corresponding edge as first element and the coords (x,y)
166        of the toNode as last element.
167
168        For internal lanes, includeJunctions is ignored and the unaltered
169        shape of the lane is returned.
170        """
171
172        if includeJunctions and not self._edge.isSpecial():
173            if self._shapeWithJunctions is None:
174                self._shapeWithJunctions = addJunctionPos(self._shape,
175                                                          self._edge.getFromNode().getCoord(),
176                                                          self._edge.getToNode().getCoord())
177            return self._shapeWithJunctions
178        return self._shape
179
180    def getShape3D(self, includeJunctions=False):
181        """Returns the shape of the lane in 3d.
182
183        This function returns the shape of the lane, as defined in the net.xml
184        file. The returned shape is a list containing numerical
185        3-tuples representing the x,y,z coordinates of the shape points
186        where z defaults to zero.
187
188        For includeJunction=True the returned list will contain
189        additionally the coords (x,y,z) of the fromNode of the
190        corresponding edge as first element and the coords (x,y,z)
191        of the toNode as last element.
192
193        For internal lanes, includeJunctions is ignored and the unaltered
194        shape of the lane is returned.
195        """
196
197        if includeJunctions and not self._edge.isSpecial():
198            if self._shapeWithJunctions3D is None:
199                self._shapeWithJunctions3D = addJunctionPos(self._shape3D,
200                                                            self._edge.getFromNode(
201                                                            ).getCoord3D(),
202                                                            self._edge.getToNode().getCoord3D())
203            return self._shapeWithJunctions3D
204        return self._shape3D
205
206    def getBoundingBox(self, includeJunctions=True):
207        s = self.getShape(includeJunctions)
208        xmin = s[0][0]
209        xmax = s[0][0]
210        ymin = s[0][1]
211        ymax = s[0][1]
212        for p in s[1:]:
213            xmin = min(xmin, p[0])
214            xmax = max(xmax, p[0])
215            ymin = min(ymin, p[1])
216            ymax = max(ymax, p[1])
217        return (xmin, ymin, xmax, ymax)
218
219    def getClosestLanePosAndDist(self, point, perpendicular=False):
220        shapePos, dist = sumolib.geomhelper.polygonOffsetAndDistanceToPoint(point, self.getShape(), perpendicular)
221        return shapePos * self._lengthGeometryFactor, dist
222
223    def getIndex(self):
224        return self._edge._lanes.index(self)
225
226    def getID(self):
227        return "%s_%s" % (self._edge._id, self.getIndex())
228
229    def getEdge(self):
230        return self._edge
231
232    def addOutgoing(self, conn):
233        self._outgoing.append(conn)
234
235    def getOutgoing(self):
236        """
237        Returns all outgoing connections from this lane.
238        """
239        return self._outgoing
240
241    def getOutgoingEdges(self):
242        """
243        Returns all outgoing edges from this lane.
244        """
245        result = []
246        for conn in self.getOutgoing():
247            if conn.getTo() not in result:
248                result.append(conn.getTo())
249        return result
250
251    def getOutgoingLanes(self):
252        """
253        Returns all outgoing lanes from this lane.
254        """
255        return [conn.getToLane() for conn in self.getOutgoing()]
256
257    def getIncoming(self, onlyDirect=False):
258        """
259        Returns all incoming lanes for this lane, i.e. lanes, which have a connection to this lane.
260        If onlyDirect is True, then only incoming internal lanes are returned for a normal lane if they exist
261        """
262        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
263        lanes = [c.getFromLane() for c in candidates if self == c.getToLane()]
264        if onlyDirect:
265            hasInternal = False
266            for _lane in lanes:
267                if _lane.getID()[0] == ":":
268                    hasInternal = True
269                    break
270            if hasInternal:
271                return [_lane for _lane in lanes if _lane.getID()[0] == ":" and
272                        _lane.getOutgoing()[0].getViaLaneID() == ""]
273        return lanes
274
275    def getIncomingConnections(self, onlyDirect=False):
276        """
277        Returns all incoming connections for this lane
278        If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist
279        """
280        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
281        cons = [c for c in candidates if self == c.getToLane()]
282        if onlyDirect:
283            hasInternal = False
284            for c in cons:
285                if c.getFromLane().getID()[0] == ":":
286                    hasInternal = True
287                    break
288            if hasInternal:
289                return [c for c in cons if c.getFromLane()[0] == ":" and
290                        c.getFromLane().getOutgoing()[0].getViaLaneID() == ""]
291        return cons
292
293    def getConnection(self, toLane):
294        """Returns the connection to the given target lane or None"""
295        for conn in self._outgoing:
296            if conn.getToLane() == toLane or conn.getViaLaneID() == toLane.getID():
297                return conn
298        return None
299
300    def getPermissions(self):
301        """return the allowed vehicle classes"""
302        return self._allowed
303
304    def setPermissions(self, allowed):
305        """set the allowed vehicle classes"""
306        self._allowed = allowed
307
308    def allows(self, vClass):
309        """true if this lane allows the given vehicle class"""
310        if vClass is None or vClass == "ignoring":
311            return True
312        return vClass in self._allowed
313
314    def setNeigh(self, neigh):
315        self._neigh = neigh
316
317    def getNeigh(self):
318        return self._neigh
319
320    def setParam(self, key, value):
321        self._params[key] = value
322
323    def getParam(self, key, default=None):
324        return self._params.get(key, default)
325
326    def getParams(self):
327        return self._params
328
329    def isAccelerationLane(self):
330        return self._acceleration
331
332    def isNormal(self):
333        return self.getID()[0] != ":"
334
335    def interpretOffset(self, lanePos):
336        if lanePos >= 0:
337            return lanePos
338        else:
339            return lanePos + self.getLength()
SUMO_VEHICLE_CLASSES = {'bus', 'truck', 'container', 'public_army', 'private', 'emergency', 'scooter', 'pedestrian', 'tram', 'ship', 'public_authority', 'cable_car', 'trailer', 'cityrail', 'custom1', 'authority', 'bicycle', 'rail_urban', 'rail_slow', 'public_transport', 'moped', 'passenger', 'taxi', 'delivery', 'motorcycle', 'army', 'hov', 'rail_electric', 'wheelchair', 'transport', 'public_emergency', 'lightrail', 'rail', 'aircraft', 'vip', 'coach', 'subway', 'rail_fast', 'drone', 'custom2', 'evehicle'}
SUMO_VEHICLE_CLASSES_DEPRECATED = {'public_transport', 'lightrail', 'public_army', 'cityrail', 'rail_fast', 'transport', 'public_emergency', 'rail_slow', 'public_authority'}
def is_vehicle_class(s):
83def is_vehicle_class(s):
84    return s in SUMO_VEHICLE_CLASSES
def get_allowed(allow, disallow):
87def get_allowed(allow, disallow):
88    """Normalize the given string attributes as a set of all allowed vClasses."""
89    if allow is None and disallow is None:
90        return SUMO_VEHICLE_CLASSES
91    elif disallow is None:
92        return set(allow.split())
93    elif disallow == "all":
94        return set()
95    else:
96        return SUMO_VEHICLE_CLASSES.difference(disallow.split())

Normalize the given string attributes as a set of all allowed vClasses.

def addJunctionPos(shape, fromPos, toPos):
 99def addJunctionPos(shape, fromPos, toPos):
100    """Extends shape with the given positions in case they differ from the
101    existing endpoints. assumes that shape and positions have the same dimensionality"""
102    result = list(shape)
103    if fromPos != shape[0]:
104        result = [fromPos] + result
105    if toPos != shape[-1]:
106        result.append(toPos)
107    return result

Extends shape with the given positions in case they differ from the existing endpoints. assumes that shape and positions have the same dimensionality

class Lane:
110class Lane:
111
112    """ Lanes from a sumo network """
113
114    def __init__(self, edge, speed, length, width, allow, disallow, acceleration):
115        self._edge = edge
116        self._speed = speed
117        self._length = length
118        self._width = width
119        self._shape = None
120        self._shape3D = None
121        self._shapeWithJunctions = None
122        self._shapeWithJunctions3D = None
123        self._outgoing = []
124        self._params = {}
125        self._allowed = get_allowed(allow, disallow)
126        self._neigh = None
127        self._selected = False
128        self._acceleration = acceleration
129        self._lengthGeometryFactor = 1
130        edge.addLane(self)
131
132    def getSpeed(self):
133        return self._speed
134
135    def getLength(self):
136        return self._length
137
138    def getWidth(self):
139        return self._width
140
141    def setShape(self, shape):
142        """Set the shape of the lane
143
144        shape must be a list containing x,y,z coords as numbers
145        to represent the shape of the lane
146        """
147        for pp in shape:
148            if len(pp) != 3:
149                raise ValueError('shape point must consist of x,y,z')
150
151        self._shape3D = shape
152        self._shape = [(x, y) for x, y, z in shape]
153        shapeLength = sumolib.geomhelper.polyLength(self.getShape())
154        if shapeLength > 0:
155            self._lengthGeometryFactor = self.getLength() / shapeLength
156
157    def getShape(self, includeJunctions=False):
158        """Returns the shape of the lane in 2d.
159
160        This function returns the shape of the lane, as defined in the net.xml
161        file. The returned shape is a list containing numerical
162        2-tuples representing the x,y coordinates of the shape points.
163
164        For includeJunctions=True the returned list will contain
165        additionally the coords (x,y) of the fromNode of the
166        corresponding edge as first element and the coords (x,y)
167        of the toNode as last element.
168
169        For internal lanes, includeJunctions is ignored and the unaltered
170        shape of the lane is returned.
171        """
172
173        if includeJunctions and not self._edge.isSpecial():
174            if self._shapeWithJunctions is None:
175                self._shapeWithJunctions = addJunctionPos(self._shape,
176                                                          self._edge.getFromNode().getCoord(),
177                                                          self._edge.getToNode().getCoord())
178            return self._shapeWithJunctions
179        return self._shape
180
181    def getShape3D(self, includeJunctions=False):
182        """Returns the shape of the lane in 3d.
183
184        This function returns the shape of the lane, as defined in the net.xml
185        file. The returned shape is a list containing numerical
186        3-tuples representing the x,y,z coordinates of the shape points
187        where z defaults to zero.
188
189        For includeJunction=True the returned list will contain
190        additionally the coords (x,y,z) of the fromNode of the
191        corresponding edge as first element and the coords (x,y,z)
192        of the toNode as last element.
193
194        For internal lanes, includeJunctions is ignored and the unaltered
195        shape of the lane is returned.
196        """
197
198        if includeJunctions and not self._edge.isSpecial():
199            if self._shapeWithJunctions3D is None:
200                self._shapeWithJunctions3D = addJunctionPos(self._shape3D,
201                                                            self._edge.getFromNode(
202                                                            ).getCoord3D(),
203                                                            self._edge.getToNode().getCoord3D())
204            return self._shapeWithJunctions3D
205        return self._shape3D
206
207    def getBoundingBox(self, includeJunctions=True):
208        s = self.getShape(includeJunctions)
209        xmin = s[0][0]
210        xmax = s[0][0]
211        ymin = s[0][1]
212        ymax = s[0][1]
213        for p in s[1:]:
214            xmin = min(xmin, p[0])
215            xmax = max(xmax, p[0])
216            ymin = min(ymin, p[1])
217            ymax = max(ymax, p[1])
218        return (xmin, ymin, xmax, ymax)
219
220    def getClosestLanePosAndDist(self, point, perpendicular=False):
221        shapePos, dist = sumolib.geomhelper.polygonOffsetAndDistanceToPoint(point, self.getShape(), perpendicular)
222        return shapePos * self._lengthGeometryFactor, dist
223
224    def getIndex(self):
225        return self._edge._lanes.index(self)
226
227    def getID(self):
228        return "%s_%s" % (self._edge._id, self.getIndex())
229
230    def getEdge(self):
231        return self._edge
232
233    def addOutgoing(self, conn):
234        self._outgoing.append(conn)
235
236    def getOutgoing(self):
237        """
238        Returns all outgoing connections from this lane.
239        """
240        return self._outgoing
241
242    def getOutgoingEdges(self):
243        """
244        Returns all outgoing edges from this lane.
245        """
246        result = []
247        for conn in self.getOutgoing():
248            if conn.getTo() not in result:
249                result.append(conn.getTo())
250        return result
251
252    def getOutgoingLanes(self):
253        """
254        Returns all outgoing lanes from this lane.
255        """
256        return [conn.getToLane() for conn in self.getOutgoing()]
257
258    def getIncoming(self, onlyDirect=False):
259        """
260        Returns all incoming lanes for this lane, i.e. lanes, which have a connection to this lane.
261        If onlyDirect is True, then only incoming internal lanes are returned for a normal lane if they exist
262        """
263        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
264        lanes = [c.getFromLane() for c in candidates if self == c.getToLane()]
265        if onlyDirect:
266            hasInternal = False
267            for _lane in lanes:
268                if _lane.getID()[0] == ":":
269                    hasInternal = True
270                    break
271            if hasInternal:
272                return [_lane for _lane in lanes if _lane.getID()[0] == ":" and
273                        _lane.getOutgoing()[0].getViaLaneID() == ""]
274        return lanes
275
276    def getIncomingConnections(self, onlyDirect=False):
277        """
278        Returns all incoming connections for this lane
279        If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist
280        """
281        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
282        cons = [c for c in candidates if self == c.getToLane()]
283        if onlyDirect:
284            hasInternal = False
285            for c in cons:
286                if c.getFromLane().getID()[0] == ":":
287                    hasInternal = True
288                    break
289            if hasInternal:
290                return [c for c in cons if c.getFromLane()[0] == ":" and
291                        c.getFromLane().getOutgoing()[0].getViaLaneID() == ""]
292        return cons
293
294    def getConnection(self, toLane):
295        """Returns the connection to the given target lane or None"""
296        for conn in self._outgoing:
297            if conn.getToLane() == toLane or conn.getViaLaneID() == toLane.getID():
298                return conn
299        return None
300
301    def getPermissions(self):
302        """return the allowed vehicle classes"""
303        return self._allowed
304
305    def setPermissions(self, allowed):
306        """set the allowed vehicle classes"""
307        self._allowed = allowed
308
309    def allows(self, vClass):
310        """true if this lane allows the given vehicle class"""
311        if vClass is None or vClass == "ignoring":
312            return True
313        return vClass in self._allowed
314
315    def setNeigh(self, neigh):
316        self._neigh = neigh
317
318    def getNeigh(self):
319        return self._neigh
320
321    def setParam(self, key, value):
322        self._params[key] = value
323
324    def getParam(self, key, default=None):
325        return self._params.get(key, default)
326
327    def getParams(self):
328        return self._params
329
330    def isAccelerationLane(self):
331        return self._acceleration
332
333    def isNormal(self):
334        return self.getID()[0] != ":"
335
336    def interpretOffset(self, lanePos):
337        if lanePos >= 0:
338            return lanePos
339        else:
340            return lanePos + self.getLength()

Lanes from a sumo network

Lane(edge, speed, length, width, allow, disallow, acceleration)
114    def __init__(self, edge, speed, length, width, allow, disallow, acceleration):
115        self._edge = edge
116        self._speed = speed
117        self._length = length
118        self._width = width
119        self._shape = None
120        self._shape3D = None
121        self._shapeWithJunctions = None
122        self._shapeWithJunctions3D = None
123        self._outgoing = []
124        self._params = {}
125        self._allowed = get_allowed(allow, disallow)
126        self._neigh = None
127        self._selected = False
128        self._acceleration = acceleration
129        self._lengthGeometryFactor = 1
130        edge.addLane(self)
def getSpeed(self):
132    def getSpeed(self):
133        return self._speed
def getLength(self):
135    def getLength(self):
136        return self._length
def getWidth(self):
138    def getWidth(self):
139        return self._width
def setShape(self, shape):
141    def setShape(self, shape):
142        """Set the shape of the lane
143
144        shape must be a list containing x,y,z coords as numbers
145        to represent the shape of the lane
146        """
147        for pp in shape:
148            if len(pp) != 3:
149                raise ValueError('shape point must consist of x,y,z')
150
151        self._shape3D = shape
152        self._shape = [(x, y) for x, y, z in shape]
153        shapeLength = sumolib.geomhelper.polyLength(self.getShape())
154        if shapeLength > 0:
155            self._lengthGeometryFactor = self.getLength() / shapeLength

Set the shape of the lane

shape must be a list containing x,y,z coords as numbers to represent the shape of the lane

def getShape(self, includeJunctions=False):
157    def getShape(self, includeJunctions=False):
158        """Returns the shape of the lane in 2d.
159
160        This function returns the shape of the lane, as defined in the net.xml
161        file. The returned shape is a list containing numerical
162        2-tuples representing the x,y coordinates of the shape points.
163
164        For includeJunctions=True the returned list will contain
165        additionally the coords (x,y) of the fromNode of the
166        corresponding edge as first element and the coords (x,y)
167        of the toNode as last element.
168
169        For internal lanes, includeJunctions is ignored and the unaltered
170        shape of the lane is returned.
171        """
172
173        if includeJunctions and not self._edge.isSpecial():
174            if self._shapeWithJunctions is None:
175                self._shapeWithJunctions = addJunctionPos(self._shape,
176                                                          self._edge.getFromNode().getCoord(),
177                                                          self._edge.getToNode().getCoord())
178            return self._shapeWithJunctions
179        return self._shape

Returns the shape of the lane in 2d.

This function returns the shape of the lane, as defined in the net.xml file. The returned shape is a list containing numerical 2-tuples representing the x,y coordinates of the shape points.

For includeJunctions=True the returned list will contain additionally the coords (x,y) of the fromNode of the corresponding edge as first element and the coords (x,y) of the toNode as last element.

For internal lanes, includeJunctions is ignored and the unaltered shape of the lane is returned.

def getShape3D(self, includeJunctions=False):
181    def getShape3D(self, includeJunctions=False):
182        """Returns the shape of the lane in 3d.
183
184        This function returns the shape of the lane, as defined in the net.xml
185        file. The returned shape is a list containing numerical
186        3-tuples representing the x,y,z coordinates of the shape points
187        where z defaults to zero.
188
189        For includeJunction=True the returned list will contain
190        additionally the coords (x,y,z) of the fromNode of the
191        corresponding edge as first element and the coords (x,y,z)
192        of the toNode as last element.
193
194        For internal lanes, includeJunctions is ignored and the unaltered
195        shape of the lane is returned.
196        """
197
198        if includeJunctions and not self._edge.isSpecial():
199            if self._shapeWithJunctions3D is None:
200                self._shapeWithJunctions3D = addJunctionPos(self._shape3D,
201                                                            self._edge.getFromNode(
202                                                            ).getCoord3D(),
203                                                            self._edge.getToNode().getCoord3D())
204            return self._shapeWithJunctions3D
205        return self._shape3D

Returns the shape of the lane in 3d.

This function returns the shape of the lane, as defined in the net.xml file. The returned shape is a list containing numerical 3-tuples representing the x,y,z coordinates of the shape points where z defaults to zero.

For includeJunction=True the returned list will contain additionally the coords (x,y,z) of the fromNode of the corresponding edge as first element and the coords (x,y,z) of the toNode as last element.

For internal lanes, includeJunctions is ignored and the unaltered shape of the lane is returned.

def getBoundingBox(self, includeJunctions=True):
207    def getBoundingBox(self, includeJunctions=True):
208        s = self.getShape(includeJunctions)
209        xmin = s[0][0]
210        xmax = s[0][0]
211        ymin = s[0][1]
212        ymax = s[0][1]
213        for p in s[1:]:
214            xmin = min(xmin, p[0])
215            xmax = max(xmax, p[0])
216            ymin = min(ymin, p[1])
217            ymax = max(ymax, p[1])
218        return (xmin, ymin, xmax, ymax)
def getClosestLanePosAndDist(self, point, perpendicular=False):
220    def getClosestLanePosAndDist(self, point, perpendicular=False):
221        shapePos, dist = sumolib.geomhelper.polygonOffsetAndDistanceToPoint(point, self.getShape(), perpendicular)
222        return shapePos * self._lengthGeometryFactor, dist
def getIndex(self):
224    def getIndex(self):
225        return self._edge._lanes.index(self)
def getID(self):
227    def getID(self):
228        return "%s_%s" % (self._edge._id, self.getIndex())
def getEdge(self):
230    def getEdge(self):
231        return self._edge
def addOutgoing(self, conn):
233    def addOutgoing(self, conn):
234        self._outgoing.append(conn)
def getOutgoing(self):
236    def getOutgoing(self):
237        """
238        Returns all outgoing connections from this lane.
239        """
240        return self._outgoing

Returns all outgoing connections from this lane.

def getOutgoingEdges(self):
242    def getOutgoingEdges(self):
243        """
244        Returns all outgoing edges from this lane.
245        """
246        result = []
247        for conn in self.getOutgoing():
248            if conn.getTo() not in result:
249                result.append(conn.getTo())
250        return result

Returns all outgoing edges from this lane.

def getOutgoingLanes(self):
252    def getOutgoingLanes(self):
253        """
254        Returns all outgoing lanes from this lane.
255        """
256        return [conn.getToLane() for conn in self.getOutgoing()]

Returns all outgoing lanes from this lane.

def getIncoming(self, onlyDirect=False):
258    def getIncoming(self, onlyDirect=False):
259        """
260        Returns all incoming lanes for this lane, i.e. lanes, which have a connection to this lane.
261        If onlyDirect is True, then only incoming internal lanes are returned for a normal lane if they exist
262        """
263        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
264        lanes = [c.getFromLane() for c in candidates if self == c.getToLane()]
265        if onlyDirect:
266            hasInternal = False
267            for _lane in lanes:
268                if _lane.getID()[0] == ":":
269                    hasInternal = True
270                    break
271            if hasInternal:
272                return [_lane for _lane in lanes if _lane.getID()[0] == ":" and
273                        _lane.getOutgoing()[0].getViaLaneID() == ""]
274        return lanes

Returns all incoming lanes for this lane, i.e. lanes, which have a connection to this lane. If onlyDirect is True, then only incoming internal lanes are returned for a normal lane if they exist

def getIncomingConnections(self, onlyDirect=False):
276    def getIncomingConnections(self, onlyDirect=False):
277        """
278        Returns all incoming connections for this lane
279        If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist
280        """
281        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
282        cons = [c for c in candidates if self == c.getToLane()]
283        if onlyDirect:
284            hasInternal = False
285            for c in cons:
286                if c.getFromLane().getID()[0] == ":":
287                    hasInternal = True
288                    break
289            if hasInternal:
290                return [c for c in cons if c.getFromLane()[0] == ":" and
291                        c.getFromLane().getOutgoing()[0].getViaLaneID() == ""]
292        return cons

Returns all incoming connections for this lane If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist

def getConnection(self, toLane):
294    def getConnection(self, toLane):
295        """Returns the connection to the given target lane or None"""
296        for conn in self._outgoing:
297            if conn.getToLane() == toLane or conn.getViaLaneID() == toLane.getID():
298                return conn
299        return None

Returns the connection to the given target lane or None

def getPermissions(self):
301    def getPermissions(self):
302        """return the allowed vehicle classes"""
303        return self._allowed

return the allowed vehicle classes

def setPermissions(self, allowed):
305    def setPermissions(self, allowed):
306        """set the allowed vehicle classes"""
307        self._allowed = allowed

set the allowed vehicle classes

def allows(self, vClass):
309    def allows(self, vClass):
310        """true if this lane allows the given vehicle class"""
311        if vClass is None or vClass == "ignoring":
312            return True
313        return vClass in self._allowed

true if this lane allows the given vehicle class

def setNeigh(self, neigh):
315    def setNeigh(self, neigh):
316        self._neigh = neigh
def getNeigh(self):
318    def getNeigh(self):
319        return self._neigh
def setParam(self, key, value):
321    def setParam(self, key, value):
322        self._params[key] = value
def getParam(self, key, default=None):
324    def getParam(self, key, default=None):
325        return self._params.get(key, default)
def getParams(self):
327    def getParams(self):
328        return self._params
def isAccelerationLane(self):
330    def isAccelerationLane(self):
331        return self._acceleration
def isNormal(self):
333    def isNormal(self):
334        return self.getID()[0] != ":"
def interpretOffset(self, lanePos):
336    def interpretOffset(self, lanePos):
337        if lanePos >= 0:
338            return lanePos
339        else:
340            return lanePos + self.getLength()