dharak003's picture
Upload 24 files
dba26ff verified
import os
import pandas as pd
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter
import tempfile
import matplotlib.pyplot as plt
from reportlab.lib import colors
from Damage_calculation import DamageCalculator
from reportlab.platypus import Table, TableStyle
class PDFReportGenerator:
def __init__(self, output_csv, output_folder, pdf_path):
self.output_csv = output_csv
self.damage_folder = os.path.join(output_folder, 'damage/labels')
self.parts_folder = os.path.join(output_folder, 'parts/labels')
self.pdf_path = pdf_path
self.calculator = DamageCalculator()
def create_pie_chart(self, part_class, damage_summary):
part_damage = damage_summary.get(part_class, {})
if not part_damage:
return None
damage_labels = list(part_damage['damage_types'].keys()) + ['Undamaged']
damage_values = list(part_damage['damage_types'].values()) + [part_damage['undamaged']]
fig, ax = plt.subplots(figsize=(6, 6)) # Adjust the figure size to ensure the pie is circular
ax.pie(damage_values, labels=damage_labels, autopct='%1.1f%%', startangle=140, textprops={'fontsize': 14}) # Increase font size
ax.axis('equal')
img_temp_path = tempfile.mktemp(suffix=".png")
plt.savefig(img_temp_path, bbox_inches='tight') # Ensure the pie chart is properly sized
plt.close(fig)
return img_temp_path
def add_table_to_pdf(self, pdf, dataframe, x_position, y_position):
# Replace NaN values with '-'
dataframe = dataframe.fillna('-')
data = [dataframe.columns.to_list()] + dataframe.values.tolist()
table = Table(data)
# Define table style
style = TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.grey),
('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
('ALIGN', (0, 0), (-1, -1), 'CENTER'),
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 12),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
('BACKGROUND', (0, 1), (-1, -1), colors.beige),
('GRID', (0, 0), (-1, -1), 1, colors.black)
])
table.setStyle(style)
# Convert the table to a PDF flowable and draw it on the canvas
table.wrapOn(pdf, x_position, y_position)
table.drawOn(pdf, x_position, y_position)
def generate_report(self):
df = pd.read_csv(self.output_csv)
car_parts = df['Car Parts'].unique()
# Initialize damage summary dictionary
damage_summary = {}
# Populate damage and parts file paths
damage_files = sorted(os.listdir(self.damage_folder))
parts_files = sorted(os.listdir(self.parts_folder))
# Iterate over the damage and parts files
for damage_file, parts_file in zip(damage_files, parts_files):
damage_path = os.path.join(self.damage_folder, damage_file)
parts_path = os.path.join(self.parts_folder, parts_file)
damage_classes, damage_polygons = self.calculator.parse_coordinates(damage_path)
part_classes, part_polygons = self.calculator.parse_coordinates(parts_path)
damage_polygons = list(zip(damage_classes, damage_polygons))
part_polygons = list(zip(part_classes, part_polygons))
part_summary = self.calculator.summarize_damage_by_part(damage_polygons, part_polygons)
for part, summary in part_summary.items():
if part not in damage_summary:
damage_summary[part] = summary
else:
for damage_type, percentage in summary['damage_types'].items():
if damage_type not in damage_summary[part]['damage_types']:
damage_summary[part]['damage_types'][damage_type] = 0
damage_summary[part]['damage_types'][damage_type] += percentage
damage_summary[part]['undamaged'] += summary['undamaged']
pdf = canvas.Canvas(self.pdf_path, pagesize=letter)
pdf.setTitle("Car Damage Estimation Report")
width, height = letter
y_position = height - 40
for part_class in car_parts:
if part_class == 'Total':
continue
pdf.setFont("Helvetica-Bold", 12)
pdf.drawString(30, y_position, f'Damage Report for {part_class}')
y_position -= 20
pie_chart_path = self.create_pie_chart(part_class, damage_summary)
if pie_chart_path:
pdf.drawImage(pie_chart_path, 50, y_position - 300, width=275, height=275) # Adjust size to maintain aspect ratio
y_position -= 320
# Clean up the temporary file
os.remove(pie_chart_path)
if y_position < 100:
pdf.showPage()
y_position = height - 40
# Add title above the table
y_position -= 40
pdf.setFont("Helvetica-Bold", 14)
pdf.drawString(50, y_position, "Cost Breakdown Table")
y_position -= 200
# Add table from CSV to the PDF
self.add_table_to_pdf(pdf, df, 30, y_position-100)
pdf.save()