|
|
import streamlit as st |
|
|
import fitz |
|
|
import pandas as pd |
|
|
import re |
|
|
|
|
|
st.set_page_config(page_title="Villa Quantity Surveyor", layout="wide") |
|
|
|
|
|
st.title("🏗️ Villa Quantity Surveyor") |
|
|
st.markdown("Upload your villa drawing in PDF format to get detailed quantity estimation and floor-wise breakdown.") |
|
|
|
|
|
|
|
|
|
|
|
def extract_text_from_pdf(uploaded_file): |
|
|
doc = fitz.open(stream=uploaded_file.read(), filetype="pdf") |
|
|
text_data = "" |
|
|
for page in doc: |
|
|
text_data += page.get_text() |
|
|
return text_data |
|
|
|
|
|
def parse_floor_data(text): |
|
|
floors = {"Ground Floor": {}, "First Floor": {}, "Second Floor": {}} |
|
|
matches = re.findall(r'(Ground|First|Second) Floor.*?(?=(Ground|First|Second) Floor|$)', text, re.DOTALL) |
|
|
for match in matches: |
|
|
floor_name = match[0] + " Floor" |
|
|
content = match[1] if isinstance(match, tuple) and len(match) > 1 else "" |
|
|
rooms = re.findall(r'(Room|Bedroom|Kitchen|Toilet|Bath|Living|Drawing).*?(\d+\.?\d*) ?x ?(\d+\.?\d*)', content) |
|
|
floor_area = 0 |
|
|
paint_area = 0 |
|
|
room_list = [] |
|
|
|
|
|
for room in rooms: |
|
|
name = room[0] |
|
|
width = float(room[1]) |
|
|
length = float(room[2]) |
|
|
height = 3 |
|
|
wall_area = 2 * height * (width + length) |
|
|
room_area = width * length |
|
|
floor_area += room_area |
|
|
paint_area += wall_area |
|
|
room_list.append({ |
|
|
"Room": name, |
|
|
"Width (m)": width, |
|
|
"Length (m)": length, |
|
|
"Wall Area for Paint (m²)": wall_area, |
|
|
"Floor Area (m²)": room_area |
|
|
}) |
|
|
|
|
|
floors[floor_name]["Total Floor Area (m²)"] = floor_area |
|
|
floors[floor_name]["Total Paint Area (m²)"] = paint_area |
|
|
floors[floor_name]["Rooms"] = room_list |
|
|
|
|
|
return floors |
|
|
|
|
|
def estimate_quantities(floor_data): |
|
|
explanation = "Estimated based on standard villa layout, assuming 3m height walls and standard block dimensions.\n" |
|
|
quantities = { |
|
|
"Bricks (1000 bricks)": 0, |
|
|
"Cement (bags)": 0, |
|
|
"Sand (m³)": 0, |
|
|
"Paint (litres)": 0 |
|
|
} |
|
|
|
|
|
total_paint_area = 0 |
|
|
total_wall_area = 0 |
|
|
for floor in floor_data.values(): |
|
|
total_paint_area += floor["Total Paint Area (m²)"] |
|
|
for room in floor["Rooms"]: |
|
|
width = room["Width (m)"] |
|
|
length = room["Length (m)"] |
|
|
height = 3 |
|
|
wall_area = 2 * height * (width + length) |
|
|
total_wall_area += wall_area |
|
|
|
|
|
|
|
|
quantities["Bricks (1000 bricks)"] = round(total_wall_area / 20) |
|
|
quantities["Cement (bags)"] = round(total_wall_area / 5) |
|
|
quantities["Sand (m³)"] = round(total_wall_area / 10, 2) |
|
|
quantities["Paint (litres)"] = round(total_paint_area / 10) |
|
|
|
|
|
return quantities, explanation |
|
|
|
|
|
|
|
|
|
|
|
uploaded_file = st.file_uploader("📤 Upload Villa Drawing (PDF)", type=["pdf"]) |
|
|
|
|
|
if uploaded_file: |
|
|
with st.spinner("📖 Reading and analyzing drawing..."): |
|
|
text = extract_text_from_pdf(uploaded_file) |
|
|
floor_data = parse_floor_data(text) |
|
|
quantities, explanation = estimate_quantities(floor_data) |
|
|
|
|
|
st.subheader("📊 Quantity Estimation") |
|
|
st.write(quantities) |
|
|
st.markdown("#### 📌 Explanation:") |
|
|
st.markdown(explanation) |
|
|
|
|
|
for floor_name, data in floor_data.items(): |
|
|
st.markdown(f"### 🏢 {floor_name}") |
|
|
st.write(f"**Total Floor Area:** {data['Total Floor Area (m²)']} m²") |
|
|
st.write(f"**Total Paint Area:** {data['Total Paint Area (m²)']} m²") |
|
|
df_rooms = pd.DataFrame(data["Rooms"]) |
|
|
st.dataframe(df_rooms) |
|
|
|