UrbanFlow / backend /export_json.py
Subh775's picture
heavy add-ons: 13+ features implemented
d9ebe88
"""
Structured JSON artifact export with complete run metadata.
Produces a self-contained JSON document suitable for programmatic
consumption, API integration, and archival.
"""
import json
import os
from datetime import datetime, timezone
def export_json(data, video_meta, engine_config, out_dir):
"""Generate a comprehensive JSON export of the analysis run.
Args:
data: Engine result dict (counts, congestion, events, etc.)
video_meta: dict with filename, fps, frames, duration, resolution, pixels
engine_config: dict with imgsz, conf, iou, stride, etc.
out_dir: Output directory path
Returns:
Filename string or None
"""
class_in = data.get("class_in", {})
class_out = data.get("class_out", {})
congestion = data.get("congestion", [])
raw_events = data.get("raw_events", [])
pcu_data = data.get("pcu", {})
speed_data = data.get("speed", {})
# Build events list from raw_events (skip header row)
events = []
for row in raw_events[1:]:
events.append({
"frame": row[0],
"timestamp_sec": row[1],
"vehicle_id": row[2],
"class_name": row[3],
"direction": row[4],
})
total_in = sum(class_in.values())
total_out = sum(class_out.values())
doc = {
"urbanflow_version": "1.1",
"generated_at": datetime.now(timezone.utc).isoformat(),
"video": video_meta,
"engine": {
"model": "VehicleNet-Y26s (OpenVINO INT8)",
"imgsz": engine_config.get("imgsz", 736),
"conf": engine_config.get("conf", 0.12),
"iou": engine_config.get("iou", 0.6),
"stride": engine_config.get("detect_stride", 2),
"tracker": "ByteTrack (custom)",
"batch": 2,
},
"performance": {
"processing_time_sec": data.get("processing_time", 0),
"actual_fps": data.get("actual_fps", 0),
"speed_vs_realtime": data.get("speed_vs_realtime", 0),
},
"counts": {
"total_in": total_in,
"total_out": total_out,
"total": total_in + total_out,
"per_class_in": {str(k): v for k, v in class_in.items()},
"per_class_out": {str(k): v for k, v in class_out.items()},
},
"pcu": pcu_data,
"speed_distribution": speed_data.get("distribution", {}),
"congestion": {
"peak": max(congestion) if congestion else 0,
"average": round(sum(congestion) / len(congestion), 1) if congestion else 0,
"timeline": congestion,
},
"flow_times": data.get("flow_times", []),
"events": events,
}
path = os.path.join(out_dir, "analysis.json")
with open(path, "w") as f:
json.dump(doc, f, indent=2, default=str)
return "analysis.json"