"""
Check order of arriving and leaving vehicles at stopping places.
Report if vehicles change their order at a stop (a vehicle arrives later but leaves earlier)
Also Reports if vehicle stop times are inconsistent with itself (times jump backwards)
"""
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
from collections import defaultdict
import fnmatch
if 'SUMO_HOME' in os.environ:
sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
import sumolib
from sumolib.miscutils import parseTime, humanReadableTime
else:
sys.exit("please declare environment variable 'SUMO_HOME'")
def get_options(args=None):
parser = sumolib.options.ArgumentParser(description="Sample routes to match counts")
parser.add_argument("-r", "--route-files", category='input', dest="routeFiles",
help="Input route file")
parser.add_argument("-H", "--human-readable-time", dest="hrTime", action="store_true", default=False,
help="Write time values as hour:minute:second or day:hour:minute:second rathern than seconds")
parser.add_argument("-p", "--ignore-parking", dest="ignoreParking", action="store_true", default=False,
help="Do not report conflicts with parking vehicles")
parser.add_argument("--until-from-duration", action="store_true", default=False, dest="untilFromDuration",
help="Use stop arrival+duration instead of 'until' to compute overtaking")
parser.add_argument("--filter-ids", category="processing", dest="filterIDs",
help="only consider stops for vehicles in the given list of ids")
parser.add_argument("--stop-table", dest="stopTable",
help="Print timetable information for the given list of busStops")
options = parser.parse_args(args=args)
if options.routeFiles:
options.routeFiles = options.routeFiles.split(',')
else:
print("Argument --route-files is mandatory", file=sys.stderr)
sys.exit()
if options.filterIDs:
options.filterIDs = set(options.filterIDs.split(','))
return options
def main(options):
tf = humanReadableTime if options.hrTime else lambda x: x
stopTimes = defaultdict(list)
for routefile in options.routeFiles:
for vehicle in sumolib.xml.parse(routefile, ['vehicle', 'trip'], heterogeneous=True):
if vehicle.stop is None:
continue
if options.filterIDs and vehicle.id not in options.filterIDs:
continue
lastUntil = None
stops = list(vehicle.stop)
for i, stop in enumerate(stops):
isParking = stop.parking in ["true", "True", "1"]
if isParking and options.ignoreParking:
continue
if options.untilFromDuration:
if stop.arrival:
until = parseTime(stop.arrival) + parseTime(stop.duration)
else:
print("Cannot compute 'until' for Vehicle %s because 'arrival' is not defined" %
vehicle.id, file=sys.stderr)
else:
until = parseTime(stop.until)
arrival = parseTime(stop.arrival) if stop.arrival else until - parseTime(stop.duration)
if until < arrival:
print("Vehicle %s has 'until' before 'arrival' (%s, %s) at stop %s" % (
vehicle.id, tf(arrival), tf(until), stop.busStop), file=sys.stderr)
if lastUntil is not None and until < lastUntil:
print("Vehicle %s has 'until' (%s) before previous 'until' (%s) at stop %s" % (
vehicle.id, tf(until), tf(lastUntil), stop.busStop), file=sys.stderr)
lastUntil = until
flags = ''
if isParking:
flags += "p"
if i == 0:
flags += "F"
if i == len(stops) - 1:
flags += "L"
if float(stop.getAttributeSecure("speed", "0")) > 0:
flags += "w"
stopTimes[stop.busStop].append([arrival, until, vehicle.id,
stop.getAttributeSecure("tripId", ""),
stop.getAttributeSecure("started", ""),
stop.getAttributeSecure("ended", ""),
flags
])
for stop, times in stopTimes.items():
times.sort()
for i, (a, u, v, t, s, e, f) in enumerate(times):
for i2, (a2, u2, v2, t2, s2, e2, f2) in enumerate(times[i + 1:]):
if u2 <= u:
times[i][-1] += "o"
times[i + 1 + i2][-1] += "O"
print("Vehicle %s (%s, %s) overtakes %s (%s, %s) at stop %s" % (
v2, tf(a2), tf(u2), v, tf(a), tf(u), stop), file=sys.stderr)
if options.stopTable:
times = []
stopIDs = []
for stopID in options.stopTable.split(','):
if stopID in stopTimes:
stopIDs.append(stopID)
elif "*" in stopID:
for candID in sorted(stopTimes.keys()):
if fnmatch.fnmatch(candID, stopID):
stopIDs.append(candID)
else:
print("No vehicle stops at busStop '%s' found" % stopID, file=sys.stderr)
for stopID in stopIDs:
times += [t + [stopID] for t in stopTimes[stopID]]
if stopIDs:
print("# busStop: %s" % ','.join(stopIDs))
if len(stopIDs) == 1:
print("arrival\tuntil\tveh\ttripId\tstarted\tended\tflags")
for a, u, v, t, s, e, f, i in sorted(times):
print("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (tf(a), tf(u), v, t, s, e, f))
else:
print("arrival\tuntil\tveh\ttripId\tstarted\tended\tflags\tbusStop")
for a, u, v, t, s, e, f, i in sorted(times):
print("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (tf(a), tf(u), v, t, s, e, f, i))
if __name__ == "__main__":
main(get_options())