#!/usr/bin/env python3 from __future__ import annotations import argparse import json from collections import Counter from pathlib import Path from typing import Any from patch_traffic_lanes import FLAGS, as_int, has_flag, looks_like_lane def visit(value: Any): if isinstance(value, dict): lanes = value.get("lanes") if isinstance(lanes, list) and any(looks_like_lane(lane) for lane in lanes): for lane in lanes: if looks_like_lane(lane): yield lane for child in value.values(): yield from visit(child) elif isinstance(value, list): for child in value: yield from visit(child) def bucket(flags: int) -> str: if has_flag(flags, "Highway"): return "highway" if has_flag(flags, "Pavement"): return "pavement" if has_flag(flags, "CrossWalk"): return "crosswalk" if has_flag(flags, "Road"): return "road" return "other" def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("json_file", type=Path) args = parser.parse_args() data = json.loads(args.json_file.read_text(encoding="utf-8")) speeds: dict[str, Counter[int]] = { "all": Counter(), "highway": Counter(), "road": Counter(), "pavement": Counter(), "crosswalk": Counter(), "other": Counter(), } flags_counter: Counter[int] = Counter() for lane in visit(data): flags = as_int(lane.get("flags")) speed = as_int(lane.get("maxSpeed")) if flags is None or speed is None: continue speeds["all"][speed] += 1 speeds[bucket(flags)][speed] += 1 flags_counter[flags] += 1 for name, counter in speeds.items(): print(f"{name}: {sum(counter.values())} lanes") print(" " + ", ".join(f"{speed}:{count}" for speed, count in counter.most_common(20))) print("top flags:") for flags, count in flags_counter.most_common(20): names = [name for name, bit in FLAGS.items() if flags & bit] print(f" {flags}: {count} ({', '.join(names)})") return 0 if __name__ == "__main__": raise SystemExit(main())