Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/route/addTAZ.py
169674 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2010-2025 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file addTAZ.py
15
# @author Jakob Erdmann
16
# @date 2021-08-27
17
18
from __future__ import print_function
19
from __future__ import absolute_import
20
import os
21
import sys
22
import random
23
from collections import defaultdict
24
import xml.etree.ElementTree as ET
25
26
if 'SUMO_HOME' in os.environ:
27
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
28
import sumolib # noqa
29
30
31
def get_options(args=None):
32
optParser = sumolib.options.ArgumentParser(description="Add fromTaz and toTaz to a route file")
33
optParser.add_argument("-r", "--route-file", category='input', dest="routefile",
34
help="define the input route file (mandatory)")
35
optParser.add_argument("-a", "-taz-files", category='input', dest="tazfiles",
36
help="define the files to load TAZ (districts) from (mandatory)")
37
optParser.add_argument("-o", "--output-file", category='output', dest="outfile",
38
help="define the output filename (mandatory)")
39
optParser.add_argument("-s", "--seed", type=int, default=42, help="random seed")
40
41
options = optParser.parse_args(args=args)
42
if not options.routefile or not options.tazfiles or not options.outfile:
43
optParser.print_help()
44
sys.exit(1)
45
46
options.tazfiles = options.tazfiles.split()
47
return options
48
49
50
def main(options):
51
random.seed(options.seed)
52
edgeFromTaz = defaultdict(list)
53
edgeToTaz = defaultdict(list)
54
numTaz = 0
55
for tazfile in options.tazfiles:
56
for taz in sumolib.xml.parse(tazfile, 'taz'):
57
numTaz += 1
58
if taz.edges:
59
for edge in taz.edges.split():
60
edgeFromTaz[edge].append(taz.id)
61
edgeToTaz[edge].append(taz.id)
62
if taz.tazSource:
63
for source in taz.tazSource:
64
edgeFromTaz[source.id].append(taz.id)
65
if taz.tazSink:
66
for sink in taz.tazSource:
67
edgeToTaz[source.id].append(taz.id)
68
69
ambiguousSource = []
70
ambiguousSink = []
71
for edge, tazs in edgeFromTaz.items():
72
if len(tazs) > 1:
73
ambiguousSource.append(edge)
74
for edge, tazs in edgeToTaz.items():
75
if len(tazs) > 1:
76
ambiguousSink.append(edge)
77
78
print("read %s TAZ" % numTaz)
79
80
if len(ambiguousSource) > 0:
81
print("edges %s (total %s) are sources for more than one TAZ" %
82
(ambiguousSource[:5], len(ambiguousSource)))
83
if len(ambiguousSink) > 0:
84
print("edges %s (total %s) are sinks for more than one TAZ" %
85
(ambiguousSink[:5], len(ambiguousSink)))
86
87
inputRoutes = ET.parse(options.routefile)
88
89
class nl: # nonlocal integral variables
90
numFromNotFound = 0
91
numToNotFound = 0
92
numVehicles = 0
93
94
def addAttrs(vehicle, fromEdge, toEdge):
95
vehID = vehicle.attrib['id']
96
if fromEdge in edgeFromTaz:
97
fromTaz = random.choice(edgeFromTaz[fromEdge])
98
vehicle.set('fromTaz', fromTaz)
99
else:
100
nl.numFromNotFound += 1
101
if nl.numFromNotFound < 5:
102
print("No fromTaz found for edge '%s' of vehicle '%s' " % (fromEdge, vehID))
103
if toEdge in edgeToTaz:
104
toTaz = random.choice(edgeToTaz[toEdge])
105
vehicle.set('toTaz', toTaz)
106
else:
107
nl.numToNotFound += 1
108
if nl.numToNotFound < 5:
109
print("No toTaz found for edge '%s' of vehicle '%s' " % (toEdge, vehID))
110
111
for vehicle in inputRoutes.getroot().iter('vehicle'):
112
nl.numVehicles += 1
113
vehID = vehicle.attrib['id']
114
edges = None
115
for child in vehicle:
116
if child.tag == "route":
117
edges = child.attrib['edges']
118
break
119
elif child.tag == "routeDistribution":
120
for child2 in child.getchildren():
121
if child2.tag == "route":
122
edges = child2.attrib['edges']
123
break
124
break
125
126
if edges is None:
127
print("No edges found for vehicle '%s'" % vehID)
128
else:
129
edges = edges.split()
130
addAttrs(vehicle, edges[0], edges[-1])
131
132
for trip in inputRoutes.getroot().iter('trip'):
133
addAttrs(trip, trip.attrib['from'], trip.attrib['to'])
134
135
print("read %s vehicles" % nl.numVehicles)
136
if nl.numFromNotFound > 0 or nl.numToNotFound > 0:
137
print("No fromTaz found for %s edges and no toTaz found for %s edges" % (
138
nl.numFromNotFound, nl.numToNotFound))
139
inputRoutes.write(options.outfile)
140
141
142
if __name__ == "__main__":
143
if not main(get_options()):
144
sys.exit(1)
145
146