Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/district/tazRel2POI.py
185785 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2012-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 tazRel2POI.py
15
# @author Jakob Erdmann
16
# @date 2025-10-02
17
18
"""
19
Creates a POIs for each TAZ where the size indicates attributes of corresponding
20
tazRelations
21
"""
22
23
from __future__ import absolute_import
24
from __future__ import print_function
25
26
import os
27
import sys
28
from collections import defaultdict
29
30
if 'SUMO_HOME' in os.environ:
31
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
32
import sumolib # noqa
33
from sumolib.miscutils import openz # noqa
34
35
36
def get_options(args=None):
37
op = sumolib.options.ArgumentParser(description="Generate trips between random locations",
38
allowed_programs=['duarouter', 'marouter'])
39
# input
40
op.add_argument("-t", "--taz-file", "--taz-files", category="input", dest="taz", required=True,
41
type=op.additional_file,
42
help="define taz file to be loaded")
43
op.add_argument("-d", "--taz-relation-file", category="input", dest="tazrel",
44
required=True, type=op.additional_file,
45
help="define taz file to be loaded")
46
op.add_argument("-n", "--net-file", category="input", dest="netfile",
47
type=op.net_file,
48
help="define net file for determining taz centers")
49
# output
50
op.add_argument("-o", "--output-file", category="output", dest="outfile",
51
required=True, type=op.additional_file,
52
help="define the output poi filename")
53
# processing
54
op.add_argument("-a", "--attribute", category="processing", default="count",
55
help="define the tazRel attribute to read")
56
op.add_argument("-s", "--size-metric", category="processing", dest="sizeMetric", default='all',
57
help="define the metric to visualize ('in', 'out', 'all')")
58
op.add_argument("-r", "--reference-taz", category="processing", dest="refTaz",
59
help="Only include relations that start or end at the given taz id")
60
61
options = op.parse_args(args=args)
62
options.net = None
63
options.taz = options.taz.split(',')
64
return options
65
66
67
def addEdgeShape(net, edge, shape, tazID):
68
if net.hasEdge(edge):
69
e = net.getEdge(edge)
70
shape.append(e.getFromNode().getCoord())
71
shape.append(e.getToNode().getCoord())
72
else:
73
print("Edge '%s' in TAZ '%s' not found." % (edge, tazID), file=sys.stderr)
74
75
76
def main(options):
77
relsFrom = defaultdict(lambda: 0)
78
relsTo = defaultdict(lambda: 0)
79
80
for tazrel in sumolib.xml.parse(options.tazrel, ['tazRelation']):
81
if tazrel.hasAttribute(options.attribute):
82
val = float(tazrel.getAttribute(options.attribute))
83
if options.refTaz is not None and tazrel.attr_from != options.refTaz and tazrel.to != options.refTaz:
84
continue
85
relsFrom[tazrel.attr_from] += val
86
relsTo[tazrel.to] += val
87
88
with openz(options.outfile, 'w') as outf:
89
sumolib.writeXMLHeader(outf, "$Id$", "additional", options=options)
90
for tazfile in options.taz:
91
for taz in sumolib.xml.parse(tazfile, ['taz']):
92
if taz.center:
93
x, y = taz.center.split(',')
94
elif taz.shape:
95
shape = []
96
for xy in taz.shape.split():
97
x, y = xy.split(',')
98
shape.append((float(x), float(y)))
99
bbox = sumolib.geomhelper.addToBoundingBox(shape)
100
x = (bbox[0] + bbox[2]) / 2
101
y = (bbox[1] + bbox[3]) / 2
102
else:
103
# compute shape from edges
104
if options.net is None:
105
if options.netfile is None:
106
print(("Skipping TAZ '%s' because it doesn't define 'center' or 'shape'." % taz.id)
107
+ " Option --net-file must be set to handle this input",
108
file=sys.stderr)
109
continue
110
options.net = sumolib.net.readNet(options.netfile)
111
shape = []
112
if taz.edges:
113
for edge in taz.edges.split():
114
addEdgeShape(options.net, edge, shape, taz.id)
115
if taz.tazSource:
116
for ts in taz.tazSource:
117
addEdgeShape(options.net, ts.id, shape, taz.id)
118
if taz.tazSink:
119
for ts in taz.tazSink:
120
addEdgeShape(options.net, ts.id, shape, taz.id)
121
if not shape:
122
print(("Skipping TAZ '%s' because no edges were found." % taz.id), file=sys.stderr)
123
continue
124
125
bbox = sumolib.geomhelper.addToBoundingBox(shape)
126
x = (bbox[0] + bbox[2]) / 2
127
y = (bbox[1] + bbox[3]) / 2
128
129
if options.sizeMetric == 'in':
130
val = relsTo[taz.id]
131
elif options.sizeMetric == 'out':
132
val = relsFrom[taz.id]
133
else:
134
val = relsTo[taz.id] + relsFrom[taz.id]
135
outf.write(' <poi id="%s" x="%s" y="%s" width="%s">\n' % (
136
taz.id, x, y, val))
137
outf.write(' <param key="in" value="%s"/>\n' % relsTo[taz.id])
138
outf.write(' <param key="out" value="%s"/>\n' % relsFrom[taz.id])
139
outf.write(' <param key="all" value="%s"/>\n' % (relsFrom[taz.id] + relsTo[taz.id]))
140
outf.write(' </poi>\n')
141
outf.write('</additional>\n')
142
143
144
if __name__ == "__main__":
145
try:
146
main(get_options())
147
except ValueError as e:
148
print("Error:", e, file=sys.stderr)
149
sys.exit(1)
150
151