Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/route/cutTrips.py
193784 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2012-2026 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 cutTrips.py
15
# @author Jakob Erdmann
16
# @date 2017-04-11
17
18
"""
19
Cut down trips from a large scenario to a sub-scenario.
20
Only trips that start and end in the sub-scenario network are kept
21
(This differs from cutRoutes.py which also keeps routes passing through the
22
sub-scenario network)
23
"""
24
from __future__ import absolute_import
25
from __future__ import print_function
26
27
import os
28
import sys
29
30
from collections import defaultdict
31
import sort_routes
32
33
if 'SUMO_HOME' in os.environ:
34
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
35
import sumolib # noqa
36
37
38
def get_options(args=None):
39
USAGE = """Usage %(prog)s [options] <new_net.xml> <trips> [<trips2> ...]
40
If the given routes contain exit times these will be used to compute new
41
departure times. If the option --orig-net is given departure times will be
42
extrapolated based on edge-lengths and maximum speeds multiplied with --speed-factor"""
43
optParser = sumolib.options.ArgumentParser(usage=USAGE)
44
optParser.add_argument("-v", "--verbose", action="store_true",
45
default=False, help="Give more output")
46
optParser.add_argument("-o", "--trips-output", dest="output", category='output',
47
help="output trip file")
48
optParser.add_argument("-a", "--additional-input", category='input',
49
help="additional file for taz (must already be cut)")
50
optParser.add_argument("-b", "--big", action="store_true", default=False,
51
help="Perform out-of-memory sort using module sort_routes "
52
"(slower but more memory efficient)")
53
optParser.add_argument("network", category='input', help="Provide an input network")
54
optParser.add_argument("routeFiles", nargs="*", category='input',
55
help="If the given routes contain exit times, "
56
"these will be used to compute new departure times")
57
return optParser.parse_args(args=args)
58
59
60
def cut_trips(aEdges, options, validTaz):
61
areaEdges = set(aEdges)
62
num_trips = 0
63
num_returned = 0
64
65
for routeFile in options.routeFiles:
66
print("Parsing trips from %s" % routeFile)
67
for trip in sumolib.xml.parse(routeFile, 'trip'):
68
num_trips += 1
69
if trip.attr_from is not None and trip.attr_from not in areaEdges:
70
continue
71
if trip.to is not None and trip.to not in areaEdges:
72
continue
73
if trip.fromTaz is not None and trip.fromTaz not in validTaz:
74
continue
75
if trip.toTaz is not None and trip.toTaz not in validTaz:
76
continue
77
yield float(trip.depart), trip
78
num_returned += 1
79
80
print("Parsing persontrips from %s" % routeFile)
81
ignored_planitems = defaultdict(lambda: 0)
82
num_persons = 0
83
num_persontrips = 0
84
from_ok = 0
85
to_ok = 0
86
for person in sumolib.xml.parse(routeFile, 'person'):
87
num_persons += 1
88
if person.walk is not None:
89
ignored_planitems['walk'] += len(person.walk)
90
del person.walk
91
if person.stop is not None:
92
ignored_planitems['stop'] += len(person.stop)
93
del person.stop
94
if person.ride is not None:
95
ignored_planitems['ride'] += len(person.ride)
96
del person.ride
97
if person.personTrip is not None:
98
kept_pt = []
99
for pt in person.personTrip:
100
skip = False
101
if pt.attr_from in areaEdges:
102
from_ok += 1
103
else:
104
skip = True
105
if pt.to in areaEdges:
106
to_ok += 1
107
else:
108
skip = True
109
110
if skip:
111
continue
112
kept_pt.append(pt)
113
num_persontrips += 1
114
if kept_pt:
115
person.personTrip = kept_pt
116
yield float(person.depart), person
117
118
print("Parsed %s trips and kept %s" % (num_trips, num_returned))
119
if num_persons > 0:
120
print("Parsed %s persons and kept %s persontrips" % (num_trips,
121
num_persontrips))
122
print("Discared %s person that departed in the area and %s persons that arrived in the area" % (
123
from_ok, to_ok))
124
if ignored_planitems:
125
print("Ignored plan items:")
126
for itemtype, count in ignored_planitems.items():
127
print(" %s %ss" % (count, itemtype))
128
129
130
def writer(file, trip):
131
file.write(trip.toXML(' '))
132
133
134
def main(options):
135
net = sumolib.net.readNet(options.network)
136
edges = set([e.getID() for e in net.getEdges()])
137
print("Valid area contains %s edges" % len(edges))
138
139
def write_to_file(vehicles, f):
140
f.write('<!-- generated with %s for %s from %s -->\n' %
141
(os.path.basename(__file__), options.network, options.routeFiles))
142
f.write(
143
('<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
144
'xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">\n'))
145
num_trips = 0
146
num_persons = 0
147
for _, v in vehicles:
148
if v.name == 'trip':
149
num_trips += 1
150
else:
151
num_persons += 1
152
writer(f, v)
153
f.write('</routes>\n')
154
if num_persons > 0:
155
print("Wrote %s trips and %s persons" % (num_trips, num_persons))
156
else:
157
print("Wrote %s trips" % (num_trips))
158
159
validTaz = set()
160
if options.additional_input:
161
for taz in sumolib.xml.parse(options.additional_input, 'taz'):
162
validTaz.add(taz.id)
163
164
if options.big:
165
# write output unsorted
166
tmpname = options.output + ".unsorted"
167
with sumolib.openz(tmpname, 'w') as f:
168
write_to_file(
169
cut_trips(edges, options, validTaz), f)
170
# sort out of memory
171
sort_routes.main([tmpname, '--big', '--outfile', options.output] + (['--verbose'] if options.verbose else []))
172
else:
173
routes = list(cut_trips(edges, options, validTaz))
174
routes.sort(key=lambda v: v[0])
175
with sumolib.openz(options.output, 'w') as f:
176
write_to_file(routes, f)
177
178
179
if __name__ == "__main__":
180
main(get_options())
181
182