Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/computePassengerCounts.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 computePassengerCounts.py
15
# @author Jakob Erdmann
16
# @date 2021-10-19
17
18
19
from __future__ import print_function
20
from __future__ import absolute_import
21
import os
22
import sys
23
from collections import defaultdict
24
25
if 'SUMO_HOME' in os.environ:
26
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
27
import sumolib # noqa
28
from sumolib.miscutils import parseTime # noqa
29
30
31
def get_options(args=None):
32
parser = sumolib.options.ArgumentParser(description="Compute Stopping Place usage")
33
parser.add_argument("-s", "--stop-output-file", dest="stopOutput",
34
help="simulation stop-output file")
35
parser.add_argument("-t", "--stopping-place", dest="stoppingPlace",
36
help="stoppingPlace type (busStop, parkingArea...)", default="busStop")
37
parser.add_argument("--csv", action="store_true", default=False,
38
help="write in CSV format")
39
parser.add_argument("--containers", action="store_true", default=False,
40
help="count containers instead of persons")
41
parser.add_argument("--only-changes", action="store_true", default=False, dest="onlyChanges",
42
help="write output only for steps where the occupancy changes")
43
parser.add_argument("-b", "--begin", default=None, help="begin time (when writting all steps)")
44
parser.add_argument("-e", "--end", default=None, help="end time (when writting all steps)")
45
options = parser.parse_args(args=args)
46
if not options.stopOutput:
47
parser.print_help()
48
sys.exit()
49
50
if options.begin:
51
options.begin = int(parseTime(options.begin))
52
if options.end:
53
options.end = int(parseTime(options.end))
54
return options
55
56
57
def main(options):
58
# declare veh counts
59
pCounts = defaultdict(list)
60
61
time = None
62
for stop in sumolib.xml.parse(options.stopOutput, "stopinfo"):
63
initial = stop.initialPersons
64
loaded = stop.loadedPersons
65
unloaded = stop.unloadedPersons
66
if options.containers:
67
initial = stop.initialContainers
68
loaded = stop.loadedContainers
69
unloaded = stop.unloadedContainers
70
71
if stop.id not in pCounts:
72
pCounts[stop.id].append((parseTime(stop.started) - 1, int(initial)))
73
pCounts[stop.id].append((parseTime(stop.started), -int(unloaded)))
74
pCounts[stop.id].append((parseTime(stop.ended), int(loaded)))
75
# iterate over pCounts
76
for veh, times in pCounts.items():
77
times.sort()
78
steps = []
79
tPrev = None
80
count = 0
81
for t, change in times:
82
if t != tPrev and tPrev is not None:
83
steps.append((tPrev, count))
84
count += change
85
tPrev = t
86
steps.append((tPrev, count))
87
88
if not options.onlyChanges:
89
# fill missing steps
90
steps2 = []
91
index = 0
92
number = 0
93
if options.begin is not None:
94
time = options.begin
95
# skip steps before begin
96
while steps[index][0] < time and index < len(steps):
97
index += 1
98
else:
99
time = int(steps[0][0])
100
101
abort = False
102
while index < len(steps):
103
# fill gaps between steps
104
newTime, newNumber = steps[index]
105
for t in range(time, int(newTime)):
106
steps2.append((float(t), number))
107
if options.end is not None and t == options.end:
108
abort = True
109
break
110
if abort:
111
break
112
steps2.append((newTime, newNumber))
113
if options.end is not None and newTime == options.end:
114
break
115
number = newNumber
116
time = int(newTime) + 1
117
index += 1
118
119
steps = steps2
120
121
suffix = ".csv" if options.csv else ".xml"
122
with open(veh + suffix, "w") as outf:
123
# write header
124
if options.csv:
125
# write CSV header
126
outf.write("step,number\n")
127
for time, number in steps:
128
outf.write("%s,%s\n" % (time, number))
129
else:
130
# write XML header
131
outf.write("<?xml version= \"1.0\" encoding=\"UTF-8\"?>\n\n")
132
# open route rag
133
outf.write('<vehicle id="%s">\n' % veh)
134
for time, number in steps:
135
outf.write(' <step time="%s" number="%s"/>\n' % (time, number))
136
outf.write("</vehicle>\n")
137
138
139
if __name__ == "__main__":
140
main(get_options())
141
142