Path: blob/main/tools/output/computeStoppingPlaceUsage.py
169674 views
#!/usr/bin/env python1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2# Copyright (C) 2010-2025 German Aerospace Center (DLR) and others.3# This program and the accompanying materials are made available under the4# terms of the Eclipse Public License 2.0 which is available at5# https://www.eclipse.org/legal/epl-2.0/6# This Source Code may also be made available under the following Secondary7# Licenses when the conditions for such availability set forth in the Eclipse8# Public License 2.0 are satisfied: GNU General Public License, version 29# or later which is available at10# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1213# @file computeStoppingPlaceUsage.py14# @author Jakob Erdmann15# @date 2021-03-23161718from __future__ import print_function19from __future__ import absolute_import20import os21import sys22from collections import defaultdict2324if 'SUMO_HOME' in os.environ:25sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))26import sumolib # noqa27from sumolib.miscutils import parseTime # noqa282930def get_options(args=None):31parser = sumolib.options.ArgumentParser(description="Compute Stopping Place usage")32parser.add_argument("-s", "--stop-output-file", dest="stopOutput",33help="simulation stop-output file")34parser.add_argument("-t", "--stopping-place", dest="stoppingPlace",35help="stoppingPlace type (busStop, parkingArea...)", default="parkingArea")36parser.add_argument("--csv", action="store_true", default=False,37help="write in CSV format")38parser.add_argument("--only-changes", action="store_true", default=False, dest="onlyChanges",39help="write output only for steps where the occupancy changes")40parser.add_argument("-b", "--begin", default=None, help="begin time (when writting all steps)")41parser.add_argument("-e", "--end", default=None, help="end time (when writting all steps)")42options = parser.parse_args(args=args)43if not options.stopOutput:44parser.print_help()45sys.exit()4647if options.begin:48options.begin = int(parseTime(options.begin))49if options.end:50options.end = int(parseTime(options.end))51return options525354def main(options):55# declare veh counts56vehCounts = defaultdict(list)5758time = None59for stop in sumolib.xml.parse(options.stopOutput, "stopinfo"):60splace = stop.getAttributeSecure(options.stoppingPlace, "")61if splace != "":62vehCounts[splace].append((parseTime(stop.started), 1))63vehCounts[splace].append((parseTime(stop.ended), -1))64# iterate over vehCounts65for splace, times in vehCounts.items():66times.sort()67steps = []68tPrev = None69count = 070for t, change in times:71if t != tPrev and tPrev is not None:72steps.append((tPrev, count))73count += change74tPrev = t75steps.append((tPrev, count))7677if not options.onlyChanges:78# fill missing steps79steps2 = []80index = 081number = 082if options.begin is not None:83time = options.begin84# skip steps before begin85while steps[index][0] < time and index < len(steps):86index += 187else:88time = int(steps[0][0])8990abort = False91while index < len(steps):92# fill gaps between steps93newTime, newNumber = steps[index]94for t in range(time, int(newTime)):95steps2.append((float(t), number))96if options.end is not None and t == options.end:97abort = True98break99if abort:100break101steps2.append((newTime, newNumber))102if options.end is not None and newTime == options.end:103break104number = newNumber105time = int(newTime) + 1106index += 1107108steps = steps2109110suffix = ".csv" if options.csv else ".xml"111with open(splace + suffix, "w") as outf:112# write header113if options.csv:114# write CSV header115outf.write("step,number\n")116for time, number in steps:117outf.write("%s,%s\n" % (time, number))118else:119# write XML header120outf.write("<?xml version= \"1.0\" encoding=\"UTF-8\"?>\n\n")121# open route rag122outf.write("<stoppingPlace>\n")123for time, number in steps:124outf.write(' <step time="%s" number="%s"/>\n' % (time, number))125outf.write("</stoppingPlace>\n")126127128if __name__ == "__main__":129main(get_options())130131132