|
|
import matplotlib.pyplot as plt |
|
|
import numpy as np |
|
|
from reportlab.lib.pagesizes import letter |
|
|
from reportlab.pdfgen import canvas |
|
|
from reportlab.lib.utils import ImageReader |
|
|
import os |
|
|
from datetime import datetime |
|
|
|
|
|
def create_percentage_circle(percentage, title): |
|
|
""" |
|
|
Create a circular progress bar for percentage visualization. |
|
|
""" |
|
|
fig, ax = plt.subplots(figsize=(4, 4)) |
|
|
ax.set_aspect("equal") |
|
|
|
|
|
circle = plt.Circle((0.5, 0.5), 0.4, color="lightgray") |
|
|
ax.add_patch(circle) |
|
|
|
|
|
theta = np.linspace(0, 360 * (percentage / 100), 100) |
|
|
x = 0.5 + 0.4 * np.cos(np.radians(theta)) |
|
|
y = 0.5 + 0.4 * np.sin(np.radians(theta)) |
|
|
ax.plot(x, y, color="blue", linewidth=20) |
|
|
|
|
|
ax.text(0.5, 0.5, f"{percentage:.1f}%", ha="center", va="center", fontsize=20) |
|
|
ax.set_title(title, fontsize=12) |
|
|
ax.axis("off") |
|
|
|
|
|
output_path = f"screenshots/circle_{int(percentage)}_{int(np.random.randint(1000))}.png" |
|
|
plt.savefig(output_path, bbox_inches="tight") |
|
|
plt.close() |
|
|
|
|
|
return output_path |
|
|
|
|
|
def generate_pdf_report(summary, screenshots, output_path): |
|
|
""" |
|
|
Generate a PDF report using reportlab with summary and embedded screenshots. |
|
|
""" |
|
|
c = canvas.Canvas(output_path, pagesize=letter) |
|
|
width, height = letter |
|
|
|
|
|
|
|
|
c.setFont("Helvetica", 16) |
|
|
c.drawString(100, height - 50, "Road Safety Analysis Report") |
|
|
c.setFont("Helvetica", 12) |
|
|
c.drawString(100, height - 70, f"Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") |
|
|
|
|
|
|
|
|
c.setFont("Helvetica", 12) |
|
|
c.drawString(100, height - 100, "Analysis Summary:") |
|
|
y = height - 120 |
|
|
for line in summary.split('\n'): |
|
|
if line.strip(): |
|
|
c.drawString(120, y, line.strip()) |
|
|
y -= 20 |
|
|
if y < 100: |
|
|
c.showPage() |
|
|
y = height - 50 |
|
|
|
|
|
|
|
|
if screenshots: |
|
|
c.showPage() |
|
|
c.setFont("Helvetica", 12) |
|
|
c.drawString(100, height - 50, "Incident Screenshots:") |
|
|
y = height - 70 |
|
|
for i, screenshot in enumerate(screenshots[:5]): |
|
|
if os.path.exists(screenshot): |
|
|
img = ImageReader(screenshot) |
|
|
img_width = 200 |
|
|
img_height = img_width * (img.getSize()[1] / img.getSize()[0]) |
|
|
if y - img_height < 50: |
|
|
c.showPage() |
|
|
y = height - 50 |
|
|
c.drawImage(screenshot, 100, y - img_height, width=img_width, height=img_height) |
|
|
c.drawString(100, y - img_height - 20, f"Incident Frame {i+1}") |
|
|
y -= img_height + 30 |
|
|
|
|
|
c.save() |