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

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

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

Lanes from a sumo network

Lane(edge, speed, length, width, allow, disallow, acceleration)
118    def __init__(self, edge, speed, length, width, allow, disallow, acceleration):
119        self._edge = edge
120        self._speed = speed
121        self._length = length
122        self._width = width
123        self._shape = None
124        self._shape3D = None
125        self._shapeWithJunctions = None
126        self._shapeWithJunctions3D = None
127        self._outgoing = []
128        self._params = {}
129        self._allowed = get_allowed(allow, disallow)
130        self._neigh = None
131        self._selected = False
132        self._acceleration = acceleration
133        self._lengthGeometryFactor = 1
134        edge.addLane(self)
def getSpeed(self):
136    def getSpeed(self):
137        return self._speed
def getLength(self):
139    def getLength(self):
140        return self._length
def getWidth(self):
142    def getWidth(self):
143        return self._width
def setShape(self, shape):
145    def setShape(self, shape):
146        """Set the shape of the lane
147
148        shape must be a list containing x,y,z coords as numbers
149        to represent the shape of the lane
150        """
151        for pp in shape:
152            if len(pp) != 3:
153                raise ValueError('shape point must consist of x,y,z')
154
155        self._shape3D = shape
156        self._shape = [(x, y) for x, y, z in shape]
157        shapeLength = sumolib.geomhelper.polyLength(self.getShape())
158        if shapeLength > 0:
159            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):
161    def getShape(self, includeJunctions=False):
162        """Returns the shape of the lane in 2d.
163
164        This function returns the shape of the lane, as defined in the net.xml
165        file. The returned shape is a list containing numerical
166        2-tuples representing the x,y coordinates of the shape points.
167
168        For includeJunctions=True the returned list will contain
169        additionally the coords (x,y) of the fromNode of the
170        corresponding edge as first element and the coords (x,y)
171        of the toNode as last element.
172
173        For internal lanes, includeJunctions is ignored and the unaltered
174        shape of the lane is returned.
175        """
176
177        if includeJunctions and not self._edge.isSpecial():
178            if self._shapeWithJunctions is None:
179                self._shapeWithJunctions = addJunctionPos(self._shape,
180                                                          self._edge.getFromNode().getCoord(),
181                                                          self._edge.getToNode().getCoord())
182            return self._shapeWithJunctions
183        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):
185    def getShape3D(self, includeJunctions=False):
186        """Returns the shape of the lane in 3d.
187
188        This function returns the shape of the lane, as defined in the net.xml
189        file. The returned shape is a list containing numerical
190        3-tuples representing the x,y,z coordinates of the shape points
191        where z defaults to zero.
192
193        For includeJunction=True the returned list will contain
194        additionally the coords (x,y,z) of the fromNode of the
195        corresponding edge as first element and the coords (x,y,z)
196        of the toNode as last element.
197
198        For internal lanes, includeJunctions is ignored and the unaltered
199        shape of the lane is returned.
200        """
201
202        if includeJunctions and not self._edge.isSpecial():
203            if self._shapeWithJunctions3D is None:
204                self._shapeWithJunctions3D = addJunctionPos(self._shape3D,
205                                                            self._edge.getFromNode(
206                                                            ).getCoord3D(),
207                                                            self._edge.getToNode().getCoord3D())
208            return self._shapeWithJunctions3D
209        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):
211    def getBoundingBox(self, includeJunctions=True):
212        s = self.getShape(includeJunctions)
213        xmin = s[0][0]
214        xmax = s[0][0]
215        ymin = s[0][1]
216        ymax = s[0][1]
217        for p in s[1:]:
218            xmin = min(xmin, p[0])
219            xmax = max(xmax, p[0])
220            ymin = min(ymin, p[1])
221            ymax = max(ymax, p[1])
222        return (xmin, ymin, xmax, ymax)
def getClosestLanePosAndDist(self, point, perpendicular=False):
224    def getClosestLanePosAndDist(self, point, perpendicular=False):
225        shapePos, dist = sumolib.geomhelper.polygonOffsetAndDistanceToPoint(point, self.getShape(), perpendicular)
226        return shapePos * self._lengthGeometryFactor, dist
def getIndex(self):
228    def getIndex(self):
229        return self._edge._lanes.index(self)
def getID(self):
231    def getID(self):
232        return "%s_%s" % (self._edge._id, self.getIndex())
def getEdge(self):
234    def getEdge(self):
235        return self._edge
def addOutgoing(self, conn):
237    def addOutgoing(self, conn):
238        self._outgoing.append(conn)
def getOutgoing(self):
240    def getOutgoing(self):
241        """
242        Returns all outgoing connections from this lane.
243        """
244        return self._outgoing

Returns all outgoing connections from this lane.

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

Returns all outgoing edges from this lane.

def getOutgoingLanes(self):
256    def getOutgoingLanes(self):
257        """
258        Returns all outgoing lanes from this lane.
259        """
260        return [conn.getToLane() for conn in self.getOutgoing()]

Returns all outgoing lanes from this lane.

def getIncoming(self, onlyDirect=False):
262    def getIncoming(self, onlyDirect=False):
263        """
264        Returns all incoming lanes for this lane, i.e. lanes, which have a connection to this lane.
265        If onlyDirect is True, then only incoming internal lanes are returned for a normal lane if they exist
266        """
267        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
268        lanes = [c.getFromLane() for c in candidates if self == c.getToLane()]
269        if onlyDirect:
270            hasInternal = False
271            for _lane in lanes:
272                if _lane.getID()[0] == ":":
273                    hasInternal = True
274                    break
275            if hasInternal:
276                return [_lane for _lane in lanes if _lane.getID()[0] == ":" and
277                        _lane.getOutgoing()[0].getViaLaneID() == ""]
278        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):
280    def getIncomingConnections(self, onlyDirect=False):
281        """
282        Returns all incoming connections for this lane
283        If onlyDirect is True, then only connections from internal lanes are returned for a normal lane if they exist
284        """
285        candidates = reduce(lambda x, y: x + y, [cons for e, cons in self._edge.getIncoming().items()], [])
286        cons = [c for c in candidates if self == c.getToLane()]
287        if onlyDirect:
288            hasInternal = False
289            for c in cons:
290                if c.getFromLane().getID()[0] == ":":
291                    hasInternal = True
292                    break
293            if hasInternal:
294                return [c for c in cons if c.getFromLane()[0] == ":" and
295                        c.getFromLane().getOutgoing()[0].getViaLaneID() == ""]
296        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):
298    def getConnection(self, toLane):
299        """Returns the connection to the given target lane or None"""
300        for conn in self._outgoing:
301            if conn.getToLane() == toLane or conn.getViaLaneID() == toLane.getID():
302                return conn
303        return None

Returns the connection to the given target lane or None

def getPermissions(self):
305    def getPermissions(self):
306        """return the allowed vehicle classes"""
307        return self._allowed

return the allowed vehicle classes

def setPermissions(self, allowed):
309    def setPermissions(self, allowed):
310        """set the allowed vehicle classes"""
311        self._allowed = allowed

set the allowed vehicle classes

def allows(self, vClass):
313    def allows(self, vClass):
314        """true if this lane allows the given vehicle class"""
315        if vClass is None or vClass == "ignoring":
316            return True
317        return vClass in self._allowed

true if this lane allows the given vehicle class

def setNeigh(self, neigh):
319    def setNeigh(self, neigh):
320        self._neigh = neigh
def getNeigh(self):
322    def getNeigh(self):
323        return self._neigh
def setParam(self, key, value):
325    def setParam(self, key, value):
326        self._params[key] = value
def getParam(self, key, default=None):
328    def getParam(self, key, default=None):
329        return self._params.get(key, default)
def getParams(self):
331    def getParams(self):
332        return self._params
def isAccelerationLane(self):
334    def isAccelerationLane(self):
335        return self._acceleration
def isNormal(self):
337    def isNormal(self):
338        return self.getID()[0] != ":"
def interpretOffset(self, lanePos):
340    def interpretOffset(self, lanePos):
341        if lanePos >= 0:
342            return lanePos
343        else:
344            return lanePos + self.getLength()