sumolib.net.node
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 node.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 22class Node: 23 24 """ Nodes from a sumo network """ 25 26 def __init__(self, id, type, coord, incLanes, intLanes=None): 27 self._id = id 28 self._type = type 29 self._coord = coord 30 self._incoming = [] 31 self._outgoing = [] 32 self._foes = {} 33 self._prohibits = {} 34 self._incLanes = incLanes 35 self._intLanes = intLanes 36 self._shape3D = None 37 self._shape = None 38 self._fringe = None 39 self._params = {} 40 self._selected = False 41 42 def getID(self): 43 return self._id 44 45 def setShape(self, shape): 46 """Set the shape of the node. 47 48 Shape must be a list containing x,y,z coords as numbers 49 to represent the shape of the node. 50 """ 51 for pp in shape: 52 if len(pp) != 3: 53 raise ValueError('shape point must consist of x,y,z') 54 self._shape3D = shape 55 self._shape = [(x, y) for x, y, z in shape] 56 57 def getShape(self): 58 """Returns the shape of the node in 2d. 59 60 This function returns the shape of the node, as defined in the net.xml 61 file. The returned shape is a list containing numerical 62 2-tuples representing the x,y coordinates of the shape points. 63 64 If no shape is defined in the xml, an empty list will be returned. 65 """ 66 67 return self._shape 68 69 def getShape3D(self): 70 """Returns the shape of the node in 3d. 71 72 This function returns the shape of the node, as defined in the net.xml 73 file. The returned shape is a list containing numerical 74 3-tuples representing the x,y,z coordinates of the shape points. 75 76 If no shape is defined in the xml, an empty list will be returned. 77 """ 78 79 return self._shape3D 80 81 def addOutgoing(self, edge): 82 self._outgoing.append(edge) 83 84 def getOutgoing(self): 85 return self._outgoing 86 87 def addIncoming(self, edge): 88 self._incoming.append(edge) 89 90 def getIncoming(self): 91 return self._incoming 92 93 def getInternal(self): 94 """Returns the internal lanes starting at the border of the node. 95 96 This function returns the junction internal lanes as defined in the 97 "intLanes" attribute in net.xml. Note that this may not contain 98 all internal lanes because there may be internal junctions where 99 further internal lanes start. 100 101 The returned list contains string ids and no lane objects. 102 """ 103 return self._intLanes 104 105 def setFoes(self, index, foes, prohibits): 106 self._foes[index] = foes 107 self._prohibits[index] = prohibits 108 109 def areFoes(self, link1, link2): 110 return self._foes[link1][len(self._foes[link1]) - link2 - 1] == '1' 111 112 def hasFoes(self): 113 """whether there are any conflicting connections as this node""" 114 return any(['1' in foes for foes in self._foes.values()]) 115 116 def getLinkIndex(self, conn): 117 ret = 0 118 for lane_id in self._incLanes: 119 lastUnderscore = lane_id.rfind("_") 120 if lastUnderscore > 0: 121 edge_id = lane_id[:lastUnderscore] 122 index = lane_id[lastUnderscore+1:] 123 edge = [e for e in self._incoming if e.getID() == edge_id][0] 124 for candidate_conn in edge.getLane(int(index)).getOutgoing(): 125 fromFunction = candidate_conn.getFromLane().getEdge().getFunction() 126 toFunction = candidate_conn.getToLane().getEdge().getFunction() 127 if toFunction == "walkingarea" or (fromFunction == "walkingarea" and not toFunction == "crossing"): 128 continue 129 if candidate_conn == conn: 130 return ret 131 ret += 1 132 return -1 133 134 def forbids(self, possProhibitor, possProhibited): 135 possProhibitorIndex = self.getLinkIndex(possProhibitor) 136 possProhibitedIndex = self.getLinkIndex(possProhibited) 137 if possProhibitorIndex < 0 or possProhibitedIndex < 0: 138 return False 139 ps = self._prohibits[possProhibitedIndex] 140 return ps[-(possProhibitorIndex + 1)] == '1' 141 142 def getCoord(self): 143 return tuple(self._coord[:2]) 144 145 def getCoord3D(self): 146 return self._coord 147 148 def getType(self): 149 return self._type 150 151 def getFringe(self): 152 return self._fringe 153 154 def getConnections(self, source=None, target=None): 155 if source: 156 incoming = [source] 157 else: 158 incoming = list(self._incoming) 159 conns = [] 160 for e in incoming: 161 if hasattr(e, "getLanes"): 162 lanes = e.getLanes() 163 else: 164 # assuming source is a lane 165 lanes = [e] 166 for _lane in lanes: 167 all_outgoing = _lane.getOutgoing() 168 outgoing = [] 169 if target: 170 if hasattr(target, "getLanes"): 171 for o in all_outgoing: 172 if o.getTo() == target: 173 outgoing.append(o) 174 else: 175 # assuming target is a lane 176 for o in all_outgoing: 177 if o.getToLane() == target: 178 outgoing.append(o) 179 else: 180 outgoing = all_outgoing 181 conns.extend(outgoing) 182 return conns 183 184 def select(self, value=True): 185 self._selected = value 186 187 def isSelected(self): 188 return self._selected 189 190 def setParam(self, key, value): 191 self._params[key] = value 192 193 def getParam(self, key, default=None): 194 return self._params.get(key, default) 195 196 def getParams(self): 197 return self._params 198 199 def getNeighboringNodes(self, outgoingNodes=True, incomingNodes=True): 200 neighboring = [] 201 if incomingNodes: 202 edges = self._incoming 203 for e in edges: 204 if not (e.getFromNode() in neighboring) and not (e.getFromNode().getID() == self.getID()): 205 neighboring.append(e.getFromNode()) 206 if outgoingNodes: 207 edges = self._outgoing 208 for e in edges: 209 if not (e.getToNode() in neighboring) and not (e.getToNode().getID() == self.getID()): 210 neighboring.append(e.getToNode()) 211 return neighboring 212 213 def __repr__(self): 214 return '<junction id="%s"/>' % self._id 215 216 def getMaxTLLinkIndex(self): 217 idx = [] 218 if self.getType() == 'traffic_light': 219 for conn in self.getConnections(): 220 idx.append(conn.getTLLinkIndex()) 221 return (max(idx)) 222 else: 223 return None
23class Node: 24 25 """ Nodes from a sumo network """ 26 27 def __init__(self, id, type, coord, incLanes, intLanes=None): 28 self._id = id 29 self._type = type 30 self._coord = coord 31 self._incoming = [] 32 self._outgoing = [] 33 self._foes = {} 34 self._prohibits = {} 35 self._incLanes = incLanes 36 self._intLanes = intLanes 37 self._shape3D = None 38 self._shape = None 39 self._fringe = None 40 self._params = {} 41 self._selected = False 42 43 def getID(self): 44 return self._id 45 46 def setShape(self, shape): 47 """Set the shape of the node. 48 49 Shape must be a list containing x,y,z coords as numbers 50 to represent the shape of the node. 51 """ 52 for pp in shape: 53 if len(pp) != 3: 54 raise ValueError('shape point must consist of x,y,z') 55 self._shape3D = shape 56 self._shape = [(x, y) for x, y, z in shape] 57 58 def getShape(self): 59 """Returns the shape of the node in 2d. 60 61 This function returns the shape of the node, as defined in the net.xml 62 file. The returned shape is a list containing numerical 63 2-tuples representing the x,y coordinates of the shape points. 64 65 If no shape is defined in the xml, an empty list will be returned. 66 """ 67 68 return self._shape 69 70 def getShape3D(self): 71 """Returns the shape of the node in 3d. 72 73 This function returns the shape of the node, as defined in the net.xml 74 file. The returned shape is a list containing numerical 75 3-tuples representing the x,y,z coordinates of the shape points. 76 77 If no shape is defined in the xml, an empty list will be returned. 78 """ 79 80 return self._shape3D 81 82 def addOutgoing(self, edge): 83 self._outgoing.append(edge) 84 85 def getOutgoing(self): 86 return self._outgoing 87 88 def addIncoming(self, edge): 89 self._incoming.append(edge) 90 91 def getIncoming(self): 92 return self._incoming 93 94 def getInternal(self): 95 """Returns the internal lanes starting at the border of the node. 96 97 This function returns the junction internal lanes as defined in the 98 "intLanes" attribute in net.xml. Note that this may not contain 99 all internal lanes because there may be internal junctions where 100 further internal lanes start. 101 102 The returned list contains string ids and no lane objects. 103 """ 104 return self._intLanes 105 106 def setFoes(self, index, foes, prohibits): 107 self._foes[index] = foes 108 self._prohibits[index] = prohibits 109 110 def areFoes(self, link1, link2): 111 return self._foes[link1][len(self._foes[link1]) - link2 - 1] == '1' 112 113 def hasFoes(self): 114 """whether there are any conflicting connections as this node""" 115 return any(['1' in foes for foes in self._foes.values()]) 116 117 def getLinkIndex(self, conn): 118 ret = 0 119 for lane_id in self._incLanes: 120 lastUnderscore = lane_id.rfind("_") 121 if lastUnderscore > 0: 122 edge_id = lane_id[:lastUnderscore] 123 index = lane_id[lastUnderscore+1:] 124 edge = [e for e in self._incoming if e.getID() == edge_id][0] 125 for candidate_conn in edge.getLane(int(index)).getOutgoing(): 126 fromFunction = candidate_conn.getFromLane().getEdge().getFunction() 127 toFunction = candidate_conn.getToLane().getEdge().getFunction() 128 if toFunction == "walkingarea" or (fromFunction == "walkingarea" and not toFunction == "crossing"): 129 continue 130 if candidate_conn == conn: 131 return ret 132 ret += 1 133 return -1 134 135 def forbids(self, possProhibitor, possProhibited): 136 possProhibitorIndex = self.getLinkIndex(possProhibitor) 137 possProhibitedIndex = self.getLinkIndex(possProhibited) 138 if possProhibitorIndex < 0 or possProhibitedIndex < 0: 139 return False 140 ps = self._prohibits[possProhibitedIndex] 141 return ps[-(possProhibitorIndex + 1)] == '1' 142 143 def getCoord(self): 144 return tuple(self._coord[:2]) 145 146 def getCoord3D(self): 147 return self._coord 148 149 def getType(self): 150 return self._type 151 152 def getFringe(self): 153 return self._fringe 154 155 def getConnections(self, source=None, target=None): 156 if source: 157 incoming = [source] 158 else: 159 incoming = list(self._incoming) 160 conns = [] 161 for e in incoming: 162 if hasattr(e, "getLanes"): 163 lanes = e.getLanes() 164 else: 165 # assuming source is a lane 166 lanes = [e] 167 for _lane in lanes: 168 all_outgoing = _lane.getOutgoing() 169 outgoing = [] 170 if target: 171 if hasattr(target, "getLanes"): 172 for o in all_outgoing: 173 if o.getTo() == target: 174 outgoing.append(o) 175 else: 176 # assuming target is a lane 177 for o in all_outgoing: 178 if o.getToLane() == target: 179 outgoing.append(o) 180 else: 181 outgoing = all_outgoing 182 conns.extend(outgoing) 183 return conns 184 185 def select(self, value=True): 186 self._selected = value 187 188 def isSelected(self): 189 return self._selected 190 191 def setParam(self, key, value): 192 self._params[key] = value 193 194 def getParam(self, key, default=None): 195 return self._params.get(key, default) 196 197 def getParams(self): 198 return self._params 199 200 def getNeighboringNodes(self, outgoingNodes=True, incomingNodes=True): 201 neighboring = [] 202 if incomingNodes: 203 edges = self._incoming 204 for e in edges: 205 if not (e.getFromNode() in neighboring) and not (e.getFromNode().getID() == self.getID()): 206 neighboring.append(e.getFromNode()) 207 if outgoingNodes: 208 edges = self._outgoing 209 for e in edges: 210 if not (e.getToNode() in neighboring) and not (e.getToNode().getID() == self.getID()): 211 neighboring.append(e.getToNode()) 212 return neighboring 213 214 def __repr__(self): 215 return '<junction id="%s"/>' % self._id 216 217 def getMaxTLLinkIndex(self): 218 idx = [] 219 if self.getType() == 'traffic_light': 220 for conn in self.getConnections(): 221 idx.append(conn.getTLLinkIndex()) 222 return (max(idx)) 223 else: 224 return None
Nodes from a sumo network
27 def __init__(self, id, type, coord, incLanes, intLanes=None): 28 self._id = id 29 self._type = type 30 self._coord = coord 31 self._incoming = [] 32 self._outgoing = [] 33 self._foes = {} 34 self._prohibits = {} 35 self._incLanes = incLanes 36 self._intLanes = intLanes 37 self._shape3D = None 38 self._shape = None 39 self._fringe = None 40 self._params = {} 41 self._selected = False
46 def setShape(self, shape): 47 """Set the shape of the node. 48 49 Shape must be a list containing x,y,z coords as numbers 50 to represent the shape of the node. 51 """ 52 for pp in shape: 53 if len(pp) != 3: 54 raise ValueError('shape point must consist of x,y,z') 55 self._shape3D = shape 56 self._shape = [(x, y) for x, y, z in shape]
Set the shape of the node.
Shape must be a list containing x,y,z coords as numbers to represent the shape of the node.
58 def getShape(self): 59 """Returns the shape of the node in 2d. 60 61 This function returns the shape of the node, as defined in the net.xml 62 file. The returned shape is a list containing numerical 63 2-tuples representing the x,y coordinates of the shape points. 64 65 If no shape is defined in the xml, an empty list will be returned. 66 """ 67 68 return self._shape
Returns the shape of the node in 2d.
This function returns the shape of the node, 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.
If no shape is defined in the xml, an empty list will be returned.
70 def getShape3D(self): 71 """Returns the shape of the node in 3d. 72 73 This function returns the shape of the node, as defined in the net.xml 74 file. The returned shape is a list containing numerical 75 3-tuples representing the x,y,z coordinates of the shape points. 76 77 If no shape is defined in the xml, an empty list will be returned. 78 """ 79 80 return self._shape3D
Returns the shape of the node in 3d.
This function returns the shape of the node, 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.
If no shape is defined in the xml, an empty list will be returned.
94 def getInternal(self): 95 """Returns the internal lanes starting at the border of the node. 96 97 This function returns the junction internal lanes as defined in the 98 "intLanes" attribute in net.xml. Note that this may not contain 99 all internal lanes because there may be internal junctions where 100 further internal lanes start. 101 102 The returned list contains string ids and no lane objects. 103 """ 104 return self._intLanes
Returns the internal lanes starting at the border of the node.
This function returns the junction internal lanes as defined in the "intLanes" attribute in net.xml. Note that this may not contain all internal lanes because there may be internal junctions where further internal lanes start.
The returned list contains string ids and no lane objects.
113 def hasFoes(self): 114 """whether there are any conflicting connections as this node""" 115 return any(['1' in foes for foes in self._foes.values()])
whether there are any conflicting connections as this node
117 def getLinkIndex(self, conn): 118 ret = 0 119 for lane_id in self._incLanes: 120 lastUnderscore = lane_id.rfind("_") 121 if lastUnderscore > 0: 122 edge_id = lane_id[:lastUnderscore] 123 index = lane_id[lastUnderscore+1:] 124 edge = [e for e in self._incoming if e.getID() == edge_id][0] 125 for candidate_conn in edge.getLane(int(index)).getOutgoing(): 126 fromFunction = candidate_conn.getFromLane().getEdge().getFunction() 127 toFunction = candidate_conn.getToLane().getEdge().getFunction() 128 if toFunction == "walkingarea" or (fromFunction == "walkingarea" and not toFunction == "crossing"): 129 continue 130 if candidate_conn == conn: 131 return ret 132 ret += 1 133 return -1
135 def forbids(self, possProhibitor, possProhibited): 136 possProhibitorIndex = self.getLinkIndex(possProhibitor) 137 possProhibitedIndex = self.getLinkIndex(possProhibited) 138 if possProhibitorIndex < 0 or possProhibitedIndex < 0: 139 return False 140 ps = self._prohibits[possProhibitedIndex] 141 return ps[-(possProhibitorIndex + 1)] == '1'
155 def getConnections(self, source=None, target=None): 156 if source: 157 incoming = [source] 158 else: 159 incoming = list(self._incoming) 160 conns = [] 161 for e in incoming: 162 if hasattr(e, "getLanes"): 163 lanes = e.getLanes() 164 else: 165 # assuming source is a lane 166 lanes = [e] 167 for _lane in lanes: 168 all_outgoing = _lane.getOutgoing() 169 outgoing = [] 170 if target: 171 if hasattr(target, "getLanes"): 172 for o in all_outgoing: 173 if o.getTo() == target: 174 outgoing.append(o) 175 else: 176 # assuming target is a lane 177 for o in all_outgoing: 178 if o.getToLane() == target: 179 outgoing.append(o) 180 else: 181 outgoing = all_outgoing 182 conns.extend(outgoing) 183 return conns
200 def getNeighboringNodes(self, outgoingNodes=True, incomingNodes=True): 201 neighboring = [] 202 if incomingNodes: 203 edges = self._incoming 204 for e in edges: 205 if not (e.getFromNode() in neighboring) and not (e.getFromNode().getID() == self.getID()): 206 neighboring.append(e.getFromNode()) 207 if outgoingNodes: 208 edges = self._outgoing 209 for e in edges: 210 if not (e.getToNode() in neighboring) and not (e.getToNode().getID() == self.getID()): 211 neighboring.append(e.getToNode()) 212 return neighboring