sumolib.net.generator.network

  1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
  2# Copyright (C) 2013-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    network.py
 14# @author  Daniel Krajzewicz
 15# @date    2013-10-10
 16
 17from __future__ import absolute_import
 18from __future__ import print_function
 19import os
 20import sys
 21import subprocess
 22import tempfile
 23
 24if 'SUMO_HOME' in os.environ:
 25    tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
 26    sys.path.append(os.path.join(tools))
 27import sumolib  # noqa
 28
 29
 30class Node:
 31
 32    def __init__(self, nid, x, y, nodeType):
 33        self.nid = nid
 34        self.x = x
 35        self.y = y
 36        self.nodeType = nodeType
 37        self.crossings = []
 38
 39    def getNetworkCoordinates(self):
 40        t = self.nid.split("/")
 41        return [int(t[0]), int(t[1])]
 42
 43    def addCrossing(self, fromEdge, toEdge):
 44        self.crossings.append([fromEdge, toEdge])
 45
 46
 47class Lane:
 48
 49    def __init__(self, dirs=None, allowed=None, disallowed=None):
 50        self.dirs = dirs
 51        self.allowed = allowed
 52        self.disallowed = disallowed
 53        if self.dirs is None:
 54            self.dirs = []
 55
 56
 57class Split:
 58
 59    def __init__(self, distance, lanes):
 60        self.distance = distance
 61        self.lanes = lanes
 62
 63
 64class Edge:
 65
 66    def __init__(self, eid=None, fromNode=None, toNode=None, numLanes=None, maxSpeed=None, lanes=None, splits=None):
 67        self.eid = eid
 68        self.fromNode = fromNode
 69        self.toNode = toNode
 70        self.numLanes = numLanes
 71        self.maxSpeed = maxSpeed
 72        self.lanes = lanes
 73        if self.lanes is None:
 74            self.lanes = [Lane() for _ in range(numLanes)]
 75        self.splits = splits
 76        if self.splits is None:
 77            self.splits = []
 78        if numLanes is None:
 79            numLanes = len(self.lanes)
 80
 81    def addSplit(self, distance, lanesToRight=None, lanesToLeft=None):
 82        if len(self.splits) == 0:
 83            if lanesToRight is None:
 84                lanesToRight = 0
 85            if lanesToLeft is None:
 86                lanesToLeft = 0
 87            lanes = range(lanesToRight, self.numLanes + lanesToRight)
 88            self.splits.append(Split(0, lanes))
 89            lanes = range(0, self.numLanes + lanesToRight + lanesToLeft)
 90            self.splits.append(Split(distance, lanes))
 91            self.lanes = [Lane() for _ in range(lanesToRight)] + self.lanes
 92            self.lanes += [Lane() for _ in range(lanesToLeft)]
 93
 94    def getConnections(self, net):
 95        ret = []
 96
 97        seen = {}
 98        for i, l in enumerate(self.lanes):
 99            for d in l.dirs:
100                if d not in seen:
101                    seen[d] = 0
102                c = net.dir2connection(d, self, i, seen[d])
103                if c is not None:
104                    ret.append(c)
105                seen[d] = seen[d] + 1
106        return ret
107
108    def getDirection(self):
109        n1c = self.fromNode.getNetworkCoordinates()
110        n2c = self.toNode.getNetworkCoordinates()
111        return [n2c[0] - n1c[0], n2c[1] - n1c[1]]
112
113
114class Connection:
115
116    def __init__(self, fromEdge, fromLane, toEdge, toLane):
117        self.fromEdge = fromEdge
118        self.fromLane = fromLane
119        self.toEdge = toEdge
120        self.toLane = toLane
121
122
123class E1:
124
125    def __init__(self, id, laneID, pos, freq, outputFile):
126        self.id = id
127        self.laneID = laneID
128        self.pos = pos
129        self.freq = freq
130        self.outputFile = outputFile
131
132
133class Net:
134
135    def __init__(self, defaultNode, defaultEdge):
136        self._nodes = {}
137        self._edges = {}
138        self._defaultEdge = defaultEdge
139        if self._defaultEdge is None:
140            self._defaultEdge = Edge(None, None, None, 2, 13.89)
141        self._defaultNode = defaultNode
142        if self._defaultNode is None:
143            self._defaultNode = Node(None, None, None, "traffic_light")
144        self._e1 = {}
145        self.netName = None
146
147    def addNode(self, n):
148        self._nodes[n.nid] = n
149
150    def getNode(self, id):
151        if id in self._nodes:
152            return self._nodes[id]
153        return None
154
155    def addEdge(self, e):
156        self._edges[e.eid] = e
157
158    def addE1Detectors(self, id, laneID, pos, freq, outputFile):
159        e1 = E1(id, laneID, pos, freq, outputFile)
160        self._e1[e1.id] = e1
161        return e1
162
163    def getEdge(self, id):
164        if id in self._edges:
165            return self._edges[id]
166        return None
167
168    def getDefaultEdge(self, n1, n2):
169        return self._defaultEdge
170
171    def buildEdge(self, n1, n2):
172        defEdge = self.getDefaultEdge(n1, n2)
173        splits = []
174        for s in defEdge.splits:
175            splits.append(s)
176        lanes = list(defEdge.lanes)
177        numLanes = defEdge.numLanes
178        maxSpeed = defEdge.maxSpeed
179        e = Edge(n1.nid + "_to_" + n2.nid, n1, n2, numLanes=numLanes,
180                 maxSpeed=maxSpeed, lanes=lanes, splits=splits)
181        return e
182
183    def connectNodes(self, node1, node2, bidi, centralReservation):
184        n1 = self._nodes[node1]
185        n2 = self._nodes[node2]
186        self.addEdge(self.buildEdge(n1, n2))
187        if bidi:
188            self.addEdge(self.buildEdge(n2, n1))
189
190    def getDirectionFromNode(self, n, dir):
191        nc = n.getNetworkCoordinates()
192        eid = n.nid + "_to_" + str(nc[0] + dir[0]) + "/" + str(nc[1] + dir[1])
193        if eid in self._edges:
194            return self._edges[eid]
195        return None
196
197    def getMatchingOutgoing(self, edge, direction):
198        edir = edge.getDirection()
199        if direction == "s":
200            return self.getDirectionFromNode(edge.toNode, edir)
201        elif direction == "t":
202            return self.getDirectionFromNode(edge.toNode, [-1 * edir[0], -1 * edir[1]])
203        elif direction == "r":
204            # look, the following is because SUMO's coordinates don't match:
205            #  the y-direction starts at the bottom, while x on right
206            if edir[0] == 0:
207                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
208            else:
209                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
210        elif direction == "l":
211            # the same as above
212            if edir[0] != 0:
213                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
214            else:
215                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
216        else:
217            raise RuntimeError("Unrecognized direction '%s'" % direction)
218
219    def dir2connection(self, direction, edge, lane, seen):
220        toEdge = self.getMatchingOutgoing(edge, direction)
221        if toEdge is not None:
222            if toEdge.lanes[seen].allowed != edge.lanes[lane].allowed:
223                seen = seen + 1
224            return Connection(edge, lane, toEdge, seen)
225        return None
226
227    def build(self, netName="net.net.xml"):
228        connections = []
229        nodesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
230        print("<nodes>", file=nodesFile)
231        for nid in self._nodes:
232            n = self._nodes[nid]
233            print('    <node id="%s" x="%s" y="%s" type="%s"/>' % (
234                n.nid, n.x, n.y, n.nodeType), file=nodesFile)
235        print("</nodes>", file=nodesFile)
236        nodesFile.close()
237
238        edgesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
239        print("<edges>", file=edgesFile)
240        for eid in self._edges:
241            e = self._edges[eid]
242            print('    <edge id="%s" from="%s" to="%s" numLanes="%s" speed="%s">' % (
243                e.eid, e.fromNode.nid, e.toNode.nid, e.numLanes, e.maxSpeed), file=edgesFile)
244            for s in e.splits:
245                print('        <split pos="%s" lanes="%s"/>' %
246                      (-s.distance, " ".join(map(str, s.lanes))), file=edgesFile)
247
248            """
249        for i,l in enumerate(e.lanes):
250            if l.allowed==None and l.disallowed==None:
251                continue
252            ls =  '        <lane index="%s" ' % (i)
253            if l.allowed!=None:
254                ls = ls + 'allow="%s"' % l.allowed
255            if l.disallowed!=None:
256                ls = ls + 'disallow="%s"' % l.disallowed
257            print >> edgesFile, ls+'/>'
258        """
259
260            connections.extend(e.getConnections(self))
261            print('    </edge>', file=edgesFile)
262
263            hadConstraints = False
264            for i, l in enumerate(e.lanes):
265                if l.allowed is None and l.disallowed is None:
266                    continue
267                hadConstraints = True
268            if hadConstraints:
269                for s in e.splits:
270                    eid = e.eid
271                    if s.distance != 0:
272                        eid = eid + ".%s" % -s.distance
273                    print('    <edge id="%s">' % (eid), file=edgesFile)
274                    for i, l in enumerate(e.lanes):
275                        # if i not in s.lanes:
276                        #    continue
277                        if l.allowed is None and l.disallowed is None:
278                            continue
279                        ls = '        <lane index="%s" ' % (i)
280                        if l.allowed is not None:
281                            ls = ls + 'allow="%s"' % l.allowed
282                        if l.disallowed is not None:
283                            ls = ls + 'disallow="%s"' % l.disallowed
284                        print(ls + '/>', file=edgesFile)
285                    print('    </edge>', file=edgesFile)
286
287        print("</edges>", file=edgesFile)
288        edgesFile.close()
289
290        connectionsFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
291        print("<connections>", file=connectionsFile)
292        for c in connections:
293            eid = c.fromEdge.eid
294            if len(c.fromEdge.splits) > 1:
295                eid = eid + ".-" + str(c.fromEdge.splits[-1].distance)
296            print('    <connection from="%s" to="%s" fromLane="%s" toLane="%s"/>' % (
297                eid, c.toEdge.eid, c.fromLane, c.toLane), file=connectionsFile)
298        for n in self._nodes:
299            if len(self._nodes[n].crossings) == 0:
300                continue
301            for c in self._nodes[n].crossings:
302                print('    <crossing node="%s" edges="%s"/>' % (
303                    n, " ".join(c)), file=connectionsFile)
304        print("</connections>", file=connectionsFile)
305        connectionsFile.close()
306
307        netconvert = sumolib.checkBinary("netconvert")
308
309        subprocess.call([netconvert, "-v", "-n", nodesFile.name, "-e", edgesFile.name, "-x", connectionsFile.name,
310                         "-o", netName])
311        os.remove(nodesFile.name)
312        os.remove(edgesFile.name)
313        os.remove(connectionsFile.name)
314        self.netName = netName
315        return netName
316
317    def buildDetectors(self, filename):
318        e1File = filename
319        fdo = open(e1File, "w")
320        print("<additional>", file=fdo)
321        for e1id in self._e1:
322            e1 = self._e1[e1id]
323            print('    <e1Detector id="%s" lane="%s" pos="%s" freq="%s" file="%s"/>' % (
324                e1.id, e1.laneID, e1.pos, e1.freq, e1.outputFile), file=fdo)
325        print("</additional>", file=fdo)
326        fdo.close()
class Node:
31class Node:
32
33    def __init__(self, nid, x, y, nodeType):
34        self.nid = nid
35        self.x = x
36        self.y = y
37        self.nodeType = nodeType
38        self.crossings = []
39
40    def getNetworkCoordinates(self):
41        t = self.nid.split("/")
42        return [int(t[0]), int(t[1])]
43
44    def addCrossing(self, fromEdge, toEdge):
45        self.crossings.append([fromEdge, toEdge])
Node(nid, x, y, nodeType)
33    def __init__(self, nid, x, y, nodeType):
34        self.nid = nid
35        self.x = x
36        self.y = y
37        self.nodeType = nodeType
38        self.crossings = []
nid
x
y
nodeType
crossings
def getNetworkCoordinates(self):
40    def getNetworkCoordinates(self):
41        t = self.nid.split("/")
42        return [int(t[0]), int(t[1])]
def addCrossing(self, fromEdge, toEdge):
44    def addCrossing(self, fromEdge, toEdge):
45        self.crossings.append([fromEdge, toEdge])
class Lane:
48class Lane:
49
50    def __init__(self, dirs=None, allowed=None, disallowed=None):
51        self.dirs = dirs
52        self.allowed = allowed
53        self.disallowed = disallowed
54        if self.dirs is None:
55            self.dirs = []
Lane(dirs=None, allowed=None, disallowed=None)
50    def __init__(self, dirs=None, allowed=None, disallowed=None):
51        self.dirs = dirs
52        self.allowed = allowed
53        self.disallowed = disallowed
54        if self.dirs is None:
55            self.dirs = []
dirs
allowed
disallowed
class Split:
58class Split:
59
60    def __init__(self, distance, lanes):
61        self.distance = distance
62        self.lanes = lanes
Split(distance, lanes)
60    def __init__(self, distance, lanes):
61        self.distance = distance
62        self.lanes = lanes
distance
lanes
class Edge:
 65class Edge:
 66
 67    def __init__(self, eid=None, fromNode=None, toNode=None, numLanes=None, maxSpeed=None, lanes=None, splits=None):
 68        self.eid = eid
 69        self.fromNode = fromNode
 70        self.toNode = toNode
 71        self.numLanes = numLanes
 72        self.maxSpeed = maxSpeed
 73        self.lanes = lanes
 74        if self.lanes is None:
 75            self.lanes = [Lane() for _ in range(numLanes)]
 76        self.splits = splits
 77        if self.splits is None:
 78            self.splits = []
 79        if numLanes is None:
 80            numLanes = len(self.lanes)
 81
 82    def addSplit(self, distance, lanesToRight=None, lanesToLeft=None):
 83        if len(self.splits) == 0:
 84            if lanesToRight is None:
 85                lanesToRight = 0
 86            if lanesToLeft is None:
 87                lanesToLeft = 0
 88            lanes = range(lanesToRight, self.numLanes + lanesToRight)
 89            self.splits.append(Split(0, lanes))
 90            lanes = range(0, self.numLanes + lanesToRight + lanesToLeft)
 91            self.splits.append(Split(distance, lanes))
 92            self.lanes = [Lane() for _ in range(lanesToRight)] + self.lanes
 93            self.lanes += [Lane() for _ in range(lanesToLeft)]
 94
 95    def getConnections(self, net):
 96        ret = []
 97
 98        seen = {}
 99        for i, l in enumerate(self.lanes):
100            for d in l.dirs:
101                if d not in seen:
102                    seen[d] = 0
103                c = net.dir2connection(d, self, i, seen[d])
104                if c is not None:
105                    ret.append(c)
106                seen[d] = seen[d] + 1
107        return ret
108
109    def getDirection(self):
110        n1c = self.fromNode.getNetworkCoordinates()
111        n2c = self.toNode.getNetworkCoordinates()
112        return [n2c[0] - n1c[0], n2c[1] - n1c[1]]
Edge( eid=None, fromNode=None, toNode=None, numLanes=None, maxSpeed=None, lanes=None, splits=None)
67    def __init__(self, eid=None, fromNode=None, toNode=None, numLanes=None, maxSpeed=None, lanes=None, splits=None):
68        self.eid = eid
69        self.fromNode = fromNode
70        self.toNode = toNode
71        self.numLanes = numLanes
72        self.maxSpeed = maxSpeed
73        self.lanes = lanes
74        if self.lanes is None:
75            self.lanes = [Lane() for _ in range(numLanes)]
76        self.splits = splits
77        if self.splits is None:
78            self.splits = []
79        if numLanes is None:
80            numLanes = len(self.lanes)
eid
fromNode
toNode
numLanes
maxSpeed
lanes
splits
def addSplit(self, distance, lanesToRight=None, lanesToLeft=None):
82    def addSplit(self, distance, lanesToRight=None, lanesToLeft=None):
83        if len(self.splits) == 0:
84            if lanesToRight is None:
85                lanesToRight = 0
86            if lanesToLeft is None:
87                lanesToLeft = 0
88            lanes = range(lanesToRight, self.numLanes + lanesToRight)
89            self.splits.append(Split(0, lanes))
90            lanes = range(0, self.numLanes + lanesToRight + lanesToLeft)
91            self.splits.append(Split(distance, lanes))
92            self.lanes = [Lane() for _ in range(lanesToRight)] + self.lanes
93            self.lanes += [Lane() for _ in range(lanesToLeft)]
def getConnections(self, net):
 95    def getConnections(self, net):
 96        ret = []
 97
 98        seen = {}
 99        for i, l in enumerate(self.lanes):
100            for d in l.dirs:
101                if d not in seen:
102                    seen[d] = 0
103                c = net.dir2connection(d, self, i, seen[d])
104                if c is not None:
105                    ret.append(c)
106                seen[d] = seen[d] + 1
107        return ret
def getDirection(self):
109    def getDirection(self):
110        n1c = self.fromNode.getNetworkCoordinates()
111        n2c = self.toNode.getNetworkCoordinates()
112        return [n2c[0] - n1c[0], n2c[1] - n1c[1]]
class Connection:
115class Connection:
116
117    def __init__(self, fromEdge, fromLane, toEdge, toLane):
118        self.fromEdge = fromEdge
119        self.fromLane = fromLane
120        self.toEdge = toEdge
121        self.toLane = toLane
Connection(fromEdge, fromLane, toEdge, toLane)
117    def __init__(self, fromEdge, fromLane, toEdge, toLane):
118        self.fromEdge = fromEdge
119        self.fromLane = fromLane
120        self.toEdge = toEdge
121        self.toLane = toLane
fromEdge
fromLane
toEdge
toLane
class E1:
124class E1:
125
126    def __init__(self, id, laneID, pos, freq, outputFile):
127        self.id = id
128        self.laneID = laneID
129        self.pos = pos
130        self.freq = freq
131        self.outputFile = outputFile
E1(id, laneID, pos, freq, outputFile)
126    def __init__(self, id, laneID, pos, freq, outputFile):
127        self.id = id
128        self.laneID = laneID
129        self.pos = pos
130        self.freq = freq
131        self.outputFile = outputFile
id
laneID
pos
freq
outputFile
class Net:
134class Net:
135
136    def __init__(self, defaultNode, defaultEdge):
137        self._nodes = {}
138        self._edges = {}
139        self._defaultEdge = defaultEdge
140        if self._defaultEdge is None:
141            self._defaultEdge = Edge(None, None, None, 2, 13.89)
142        self._defaultNode = defaultNode
143        if self._defaultNode is None:
144            self._defaultNode = Node(None, None, None, "traffic_light")
145        self._e1 = {}
146        self.netName = None
147
148    def addNode(self, n):
149        self._nodes[n.nid] = n
150
151    def getNode(self, id):
152        if id in self._nodes:
153            return self._nodes[id]
154        return None
155
156    def addEdge(self, e):
157        self._edges[e.eid] = e
158
159    def addE1Detectors(self, id, laneID, pos, freq, outputFile):
160        e1 = E1(id, laneID, pos, freq, outputFile)
161        self._e1[e1.id] = e1
162        return e1
163
164    def getEdge(self, id):
165        if id in self._edges:
166            return self._edges[id]
167        return None
168
169    def getDefaultEdge(self, n1, n2):
170        return self._defaultEdge
171
172    def buildEdge(self, n1, n2):
173        defEdge = self.getDefaultEdge(n1, n2)
174        splits = []
175        for s in defEdge.splits:
176            splits.append(s)
177        lanes = list(defEdge.lanes)
178        numLanes = defEdge.numLanes
179        maxSpeed = defEdge.maxSpeed
180        e = Edge(n1.nid + "_to_" + n2.nid, n1, n2, numLanes=numLanes,
181                 maxSpeed=maxSpeed, lanes=lanes, splits=splits)
182        return e
183
184    def connectNodes(self, node1, node2, bidi, centralReservation):
185        n1 = self._nodes[node1]
186        n2 = self._nodes[node2]
187        self.addEdge(self.buildEdge(n1, n2))
188        if bidi:
189            self.addEdge(self.buildEdge(n2, n1))
190
191    def getDirectionFromNode(self, n, dir):
192        nc = n.getNetworkCoordinates()
193        eid = n.nid + "_to_" + str(nc[0] + dir[0]) + "/" + str(nc[1] + dir[1])
194        if eid in self._edges:
195            return self._edges[eid]
196        return None
197
198    def getMatchingOutgoing(self, edge, direction):
199        edir = edge.getDirection()
200        if direction == "s":
201            return self.getDirectionFromNode(edge.toNode, edir)
202        elif direction == "t":
203            return self.getDirectionFromNode(edge.toNode, [-1 * edir[0], -1 * edir[1]])
204        elif direction == "r":
205            # look, the following is because SUMO's coordinates don't match:
206            #  the y-direction starts at the bottom, while x on right
207            if edir[0] == 0:
208                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
209            else:
210                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
211        elif direction == "l":
212            # the same as above
213            if edir[0] != 0:
214                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
215            else:
216                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
217        else:
218            raise RuntimeError("Unrecognized direction '%s'" % direction)
219
220    def dir2connection(self, direction, edge, lane, seen):
221        toEdge = self.getMatchingOutgoing(edge, direction)
222        if toEdge is not None:
223            if toEdge.lanes[seen].allowed != edge.lanes[lane].allowed:
224                seen = seen + 1
225            return Connection(edge, lane, toEdge, seen)
226        return None
227
228    def build(self, netName="net.net.xml"):
229        connections = []
230        nodesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
231        print("<nodes>", file=nodesFile)
232        for nid in self._nodes:
233            n = self._nodes[nid]
234            print('    <node id="%s" x="%s" y="%s" type="%s"/>' % (
235                n.nid, n.x, n.y, n.nodeType), file=nodesFile)
236        print("</nodes>", file=nodesFile)
237        nodesFile.close()
238
239        edgesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
240        print("<edges>", file=edgesFile)
241        for eid in self._edges:
242            e = self._edges[eid]
243            print('    <edge id="%s" from="%s" to="%s" numLanes="%s" speed="%s">' % (
244                e.eid, e.fromNode.nid, e.toNode.nid, e.numLanes, e.maxSpeed), file=edgesFile)
245            for s in e.splits:
246                print('        <split pos="%s" lanes="%s"/>' %
247                      (-s.distance, " ".join(map(str, s.lanes))), file=edgesFile)
248
249            """
250        for i,l in enumerate(e.lanes):
251            if l.allowed==None and l.disallowed==None:
252                continue
253            ls =  '        <lane index="%s" ' % (i)
254            if l.allowed!=None:
255                ls = ls + 'allow="%s"' % l.allowed
256            if l.disallowed!=None:
257                ls = ls + 'disallow="%s"' % l.disallowed
258            print >> edgesFile, ls+'/>'
259        """
260
261            connections.extend(e.getConnections(self))
262            print('    </edge>', file=edgesFile)
263
264            hadConstraints = False
265            for i, l in enumerate(e.lanes):
266                if l.allowed is None and l.disallowed is None:
267                    continue
268                hadConstraints = True
269            if hadConstraints:
270                for s in e.splits:
271                    eid = e.eid
272                    if s.distance != 0:
273                        eid = eid + ".%s" % -s.distance
274                    print('    <edge id="%s">' % (eid), file=edgesFile)
275                    for i, l in enumerate(e.lanes):
276                        # if i not in s.lanes:
277                        #    continue
278                        if l.allowed is None and l.disallowed is None:
279                            continue
280                        ls = '        <lane index="%s" ' % (i)
281                        if l.allowed is not None:
282                            ls = ls + 'allow="%s"' % l.allowed
283                        if l.disallowed is not None:
284                            ls = ls + 'disallow="%s"' % l.disallowed
285                        print(ls + '/>', file=edgesFile)
286                    print('    </edge>', file=edgesFile)
287
288        print("</edges>", file=edgesFile)
289        edgesFile.close()
290
291        connectionsFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
292        print("<connections>", file=connectionsFile)
293        for c in connections:
294            eid = c.fromEdge.eid
295            if len(c.fromEdge.splits) > 1:
296                eid = eid + ".-" + str(c.fromEdge.splits[-1].distance)
297            print('    <connection from="%s" to="%s" fromLane="%s" toLane="%s"/>' % (
298                eid, c.toEdge.eid, c.fromLane, c.toLane), file=connectionsFile)
299        for n in self._nodes:
300            if len(self._nodes[n].crossings) == 0:
301                continue
302            for c in self._nodes[n].crossings:
303                print('    <crossing node="%s" edges="%s"/>' % (
304                    n, " ".join(c)), file=connectionsFile)
305        print("</connections>", file=connectionsFile)
306        connectionsFile.close()
307
308        netconvert = sumolib.checkBinary("netconvert")
309
310        subprocess.call([netconvert, "-v", "-n", nodesFile.name, "-e", edgesFile.name, "-x", connectionsFile.name,
311                         "-o", netName])
312        os.remove(nodesFile.name)
313        os.remove(edgesFile.name)
314        os.remove(connectionsFile.name)
315        self.netName = netName
316        return netName
317
318    def buildDetectors(self, filename):
319        e1File = filename
320        fdo = open(e1File, "w")
321        print("<additional>", file=fdo)
322        for e1id in self._e1:
323            e1 = self._e1[e1id]
324            print('    <e1Detector id="%s" lane="%s" pos="%s" freq="%s" file="%s"/>' % (
325                e1.id, e1.laneID, e1.pos, e1.freq, e1.outputFile), file=fdo)
326        print("</additional>", file=fdo)
327        fdo.close()
Net(defaultNode, defaultEdge)
136    def __init__(self, defaultNode, defaultEdge):
137        self._nodes = {}
138        self._edges = {}
139        self._defaultEdge = defaultEdge
140        if self._defaultEdge is None:
141            self._defaultEdge = Edge(None, None, None, 2, 13.89)
142        self._defaultNode = defaultNode
143        if self._defaultNode is None:
144            self._defaultNode = Node(None, None, None, "traffic_light")
145        self._e1 = {}
146        self.netName = None
netName
def addNode(self, n):
148    def addNode(self, n):
149        self._nodes[n.nid] = n
def getNode(self, id):
151    def getNode(self, id):
152        if id in self._nodes:
153            return self._nodes[id]
154        return None
def addEdge(self, e):
156    def addEdge(self, e):
157        self._edges[e.eid] = e
def addE1Detectors(self, id, laneID, pos, freq, outputFile):
159    def addE1Detectors(self, id, laneID, pos, freq, outputFile):
160        e1 = E1(id, laneID, pos, freq, outputFile)
161        self._e1[e1.id] = e1
162        return e1
def getEdge(self, id):
164    def getEdge(self, id):
165        if id in self._edges:
166            return self._edges[id]
167        return None
def getDefaultEdge(self, n1, n2):
169    def getDefaultEdge(self, n1, n2):
170        return self._defaultEdge
def buildEdge(self, n1, n2):
172    def buildEdge(self, n1, n2):
173        defEdge = self.getDefaultEdge(n1, n2)
174        splits = []
175        for s in defEdge.splits:
176            splits.append(s)
177        lanes = list(defEdge.lanes)
178        numLanes = defEdge.numLanes
179        maxSpeed = defEdge.maxSpeed
180        e = Edge(n1.nid + "_to_" + n2.nid, n1, n2, numLanes=numLanes,
181                 maxSpeed=maxSpeed, lanes=lanes, splits=splits)
182        return e
def connectNodes(self, node1, node2, bidi, centralReservation):
184    def connectNodes(self, node1, node2, bidi, centralReservation):
185        n1 = self._nodes[node1]
186        n2 = self._nodes[node2]
187        self.addEdge(self.buildEdge(n1, n2))
188        if bidi:
189            self.addEdge(self.buildEdge(n2, n1))
def getDirectionFromNode(self, n, dir):
191    def getDirectionFromNode(self, n, dir):
192        nc = n.getNetworkCoordinates()
193        eid = n.nid + "_to_" + str(nc[0] + dir[0]) + "/" + str(nc[1] + dir[1])
194        if eid in self._edges:
195            return self._edges[eid]
196        return None
def getMatchingOutgoing(self, edge, direction):
198    def getMatchingOutgoing(self, edge, direction):
199        edir = edge.getDirection()
200        if direction == "s":
201            return self.getDirectionFromNode(edge.toNode, edir)
202        elif direction == "t":
203            return self.getDirectionFromNode(edge.toNode, [-1 * edir[0], -1 * edir[1]])
204        elif direction == "r":
205            # look, the following is because SUMO's coordinates don't match:
206            #  the y-direction starts at the bottom, while x on right
207            if edir[0] == 0:
208                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
209            else:
210                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
211        elif direction == "l":
212            # the same as above
213            if edir[0] != 0:
214                return self.getDirectionFromNode(edge.toNode, [1 * edir[1], 1 * edir[0]])
215            else:
216                return self.getDirectionFromNode(edge.toNode, [-1 * edir[1], -1 * edir[0]])
217        else:
218            raise RuntimeError("Unrecognized direction '%s'" % direction)
def dir2connection(self, direction, edge, lane, seen):
220    def dir2connection(self, direction, edge, lane, seen):
221        toEdge = self.getMatchingOutgoing(edge, direction)
222        if toEdge is not None:
223            if toEdge.lanes[seen].allowed != edge.lanes[lane].allowed:
224                seen = seen + 1
225            return Connection(edge, lane, toEdge, seen)
226        return None
def build(self, netName='net.net.xml'):
228    def build(self, netName="net.net.xml"):
229        connections = []
230        nodesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
231        print("<nodes>", file=nodesFile)
232        for nid in self._nodes:
233            n = self._nodes[nid]
234            print('    <node id="%s" x="%s" y="%s" type="%s"/>' % (
235                n.nid, n.x, n.y, n.nodeType), file=nodesFile)
236        print("</nodes>", file=nodesFile)
237        nodesFile.close()
238
239        edgesFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
240        print("<edges>", file=edgesFile)
241        for eid in self._edges:
242            e = self._edges[eid]
243            print('    <edge id="%s" from="%s" to="%s" numLanes="%s" speed="%s">' % (
244                e.eid, e.fromNode.nid, e.toNode.nid, e.numLanes, e.maxSpeed), file=edgesFile)
245            for s in e.splits:
246                print('        <split pos="%s" lanes="%s"/>' %
247                      (-s.distance, " ".join(map(str, s.lanes))), file=edgesFile)
248
249            """
250        for i,l in enumerate(e.lanes):
251            if l.allowed==None and l.disallowed==None:
252                continue
253            ls =  '        <lane index="%s" ' % (i)
254            if l.allowed!=None:
255                ls = ls + 'allow="%s"' % l.allowed
256            if l.disallowed!=None:
257                ls = ls + 'disallow="%s"' % l.disallowed
258            print >> edgesFile, ls+'/>'
259        """
260
261            connections.extend(e.getConnections(self))
262            print('    </edge>', file=edgesFile)
263
264            hadConstraints = False
265            for i, l in enumerate(e.lanes):
266                if l.allowed is None and l.disallowed is None:
267                    continue
268                hadConstraints = True
269            if hadConstraints:
270                for s in e.splits:
271                    eid = e.eid
272                    if s.distance != 0:
273                        eid = eid + ".%s" % -s.distance
274                    print('    <edge id="%s">' % (eid), file=edgesFile)
275                    for i, l in enumerate(e.lanes):
276                        # if i not in s.lanes:
277                        #    continue
278                        if l.allowed is None and l.disallowed is None:
279                            continue
280                        ls = '        <lane index="%s" ' % (i)
281                        if l.allowed is not None:
282                            ls = ls + 'allow="%s"' % l.allowed
283                        if l.disallowed is not None:
284                            ls = ls + 'disallow="%s"' % l.disallowed
285                        print(ls + '/>', file=edgesFile)
286                    print('    </edge>', file=edgesFile)
287
288        print("</edges>", file=edgesFile)
289        edgesFile.close()
290
291        connectionsFile = tempfile.NamedTemporaryFile(mode="w", delete=False)
292        print("<connections>", file=connectionsFile)
293        for c in connections:
294            eid = c.fromEdge.eid
295            if len(c.fromEdge.splits) > 1:
296                eid = eid + ".-" + str(c.fromEdge.splits[-1].distance)
297            print('    <connection from="%s" to="%s" fromLane="%s" toLane="%s"/>' % (
298                eid, c.toEdge.eid, c.fromLane, c.toLane), file=connectionsFile)
299        for n in self._nodes:
300            if len(self._nodes[n].crossings) == 0:
301                continue
302            for c in self._nodes[n].crossings:
303                print('    <crossing node="%s" edges="%s"/>' % (
304                    n, " ".join(c)), file=connectionsFile)
305        print("</connections>", file=connectionsFile)
306        connectionsFile.close()
307
308        netconvert = sumolib.checkBinary("netconvert")
309
310        subprocess.call([netconvert, "-v", "-n", nodesFile.name, "-e", edgesFile.name, "-x", connectionsFile.name,
311                         "-o", netName])
312        os.remove(nodesFile.name)
313        os.remove(edgesFile.name)
314        os.remove(connectionsFile.name)
315        self.netName = netName
316        return netName
def buildDetectors(self, filename):
318    def buildDetectors(self, filename):
319        e1File = filename
320        fdo = open(e1File, "w")
321        print("<additional>", file=fdo)
322        for e1id in self._e1:
323            e1 = self._e1[e1id]
324            print('    <e1Detector id="%s" lane="%s" pos="%s" freq="%s" file="%s"/>' % (
325                e1.id, e1.laneID, e1.pos, e1.freq, e1.outputFile), file=fdo)
326        print("</additional>", file=fdo)
327        fdo.close()