|
2 | 2 |
|
3 | 3 | import duckdb |
4 | 4 | import streamlit as st |
| 5 | +import geopandas as gpd |
| 6 | +import folium |
| 7 | +import streamlit_folium as st_folium |
| 8 | +import os |
| 9 | + |
| 10 | +# Set page configuration as the first Streamlit command |
| 11 | +st.set_page_config(layout="wide", page_title="Interactive Real Estate Map", page_icon="🌍") |
| 12 | + |
5 | 13 | from init_db import init_db |
| 14 | +from maptab import map_tab |
| 15 | + |
| 16 | + |
6 | 17 |
|
7 | 18 | @st.cache_data(hash_funcs={duckdb.DuckDBPyConnection: id}) |
8 | | -def get_regioni(conn): |
9 | | - return conn.execute("SELECT DISTINCT Regione FROM luoghi order by Regione").df() |
| 19 | +def get_regions(conn): |
| 20 | + return conn.execute("SELECT DISTINCT Regione FROM luoghi ORDER BY Regione").df() |
10 | 21 |
|
11 | 22 | @st.cache_data(hash_funcs={duckdb.DuckDBPyConnection: id}) |
12 | | -def get_comuni(conn, regione): |
13 | | - return conn.execute(f"SELECT DISTINCT Comune_descrizione FROM luoghi WHERE Regione = '{regione}' order by Comune_descrizione").df() |
| 23 | +def get_municipalities(conn, region): |
| 24 | + return conn.execute(f"SELECT DISTINCT Comune_descrizione FROM luoghi WHERE Regione = '{region}' ORDER BY Comune_descrizione").df() |
| 25 | + |
| 26 | +@st.cache_data |
| 27 | +def load_geodataframe(file_path): |
| 28 | + return gpd.read_file(file_path) |
14 | 29 |
|
| 30 | +def create_map(data_gdf, highlight_column): |
| 31 | + m = folium.Map(location=[42.5, 12.5], zoom_start=6, tiles="cartodbpositron") |
| 32 | + |
| 33 | + for _, row in data_gdf.iterrows(): |
| 34 | + feature = folium.GeoJson( |
| 35 | + row["geometry"], |
| 36 | + name=row[highlight_column], |
| 37 | + tooltip=row[highlight_column], |
| 38 | + style_function=lambda x: { |
| 39 | + "fillColor": "blue", |
| 40 | + "color": "black", |
| 41 | + "weight": 1, |
| 42 | + "fillOpacity": 0.4, |
| 43 | + }, |
| 44 | + highlight_function=lambda x: {"weight": 3, "fillOpacity": 0.7}, |
| 45 | + popup=folium.Popup(f"<b>{row[highlight_column]}</b>", parse_html=True) |
| 46 | + ) |
| 47 | + feature.add_to(m) |
| 48 | + |
| 49 | + return m |
15 | 50 |
|
16 | 51 | def main(): |
17 | 52 | """ |
18 | 53 | Main function that serves as the entry point for the application. |
19 | 54 | """ |
20 | 55 | try: |
21 | | - conn = duckdb.connect(database = "dati-immobiliari.duckdb") |
| 56 | + conn = duckdb.connect(database="dati-immobiliari.duckdb") |
22 | 57 | init_db(conn) |
23 | | - |
24 | | - st.set_page_config(layout="wide") |
25 | | - |
26 | | - st.title("Dati immobiliari Agenzia delle Entrate") |
27 | | - st.caption("Dati del 2024") |
28 | | - |
29 | | - |
30 | | - show_all_columns = st.checkbox("Mostra tutte le colonne", value=False) |
31 | | - |
32 | | - default_columns = { |
33 | | - "Comune_descrizione" : "Comune", |
34 | | - "Descr_Tipologia" : "Tipologia", |
35 | | - "Zona_Descr" : "Zona", |
36 | | - "Compr_min" : "Prezzo acquisto minimo al mq (€)", |
37 | | - "Compr_max" : "Prezzo acquisto massimo al mq (€)", |
38 | | - "Loc_min" : "Prezzo locazione minimo al mq (€)", |
39 | | - "Loc_max" : "Prezzo locazione massimo al mq (€)" |
40 | | - } |
41 | | - |
42 | | - regioni_dataset = get_regioni(conn)["Regione"] |
43 | | - selected_regione =st.selectbox("Seleziona la regione", regioni_dataset) |
44 | | - |
45 | | - if(selected_regione != None): |
46 | | - comuni_dataset = get_comuni(conn, selected_regione)["Comune_descrizione"] |
47 | | - selected_comune = st.selectbox("Seleziona il comune", comuni_dataset) |
48 | | - |
49 | | - if(selected_comune != None): |
50 | | - |
51 | | - selected_tipologia = st.selectbox("Seleziona la tipologia", ("Abitazioni civili", "Uffici", "Negozi")) |
52 | | - |
53 | | - if(selected_tipologia != None): |
54 | | - result = conn.execute(f"SELECT * FROM joined_data WHERE Regione = '{selected_regione}' and Comune_descrizione = '{selected_comune}' and Descr_Tipologia = '{selected_tipologia}'").df() |
55 | | - readable_columns = {**default_columns, **{col: col for col in result.columns if col not in default_columns}} |
56 | | - |
57 | | - if(show_all_columns): |
58 | | - st.dataframe(result) |
59 | | - |
60 | | - else: |
61 | | - |
62 | | - display_df = result[list(default_columns.keys())].rename(columns=default_columns) |
63 | | - st.dataframe(display_df) |
64 | | - |
| 58 | + |
| 59 | + tableTab, mapTab = st.tabs(["Table", "Map"]) |
| 60 | + |
| 61 | + with tableTab: |
| 62 | + st.title("Italian Real Estate Prices") |
| 63 | + st.caption("Downloaded from Agenzia delle Entrate - current data is from 1st semester 2024") |
| 64 | + |
| 65 | + show_all_columns = st.checkbox("Show all columns", value=False) |
| 66 | + |
| 67 | + default_columns = { |
| 68 | + "Comune_descrizione": "Municipality", |
| 69 | + "Descr_Tipologia": "Type", |
| 70 | + "Zona_Descr": "Zones", |
| 71 | + "Compr_min": "Minimum purchase price per sqm (€)", |
| 72 | + "Compr_max": "Maximum purchase price per sqm (€)", |
| 73 | + "Loc_min": "Minimum rental price per sqm (€)", |
| 74 | + "Loc_max": "Maximum rental price per sqm (€)" |
| 75 | + } |
| 76 | + |
| 77 | + regions_dataset = get_regions(conn)["Regione"] |
| 78 | + selected_region = st.selectbox("Select a region", regions_dataset) |
| 79 | + |
| 80 | + if selected_region is not None: |
| 81 | + municipalities_dataset = get_municipalities(conn, selected_region)["Comune_descrizione"] |
| 82 | + selected_municipality = st.selectbox("Select a municipality", municipalities_dataset) |
| 83 | + |
| 84 | + if selected_municipality is not None: |
| 85 | + selected_building_type = st.selectbox("Select the type of building", ("Residential buildings", "Offices", "Shops")) |
| 86 | + |
| 87 | + building_types = { |
| 88 | + "Residential buildings": "Abitazioni civili", |
| 89 | + "Offices": "Uffici", |
| 90 | + "Shops": "Negozi" |
| 91 | + } |
| 92 | + |
| 93 | + if selected_building_type is not None: |
| 94 | + result = conn.execute(f"SELECT * FROM joined_data WHERE Regione = '{selected_region}' and Comune_descrizione = '{selected_municipality}' and Descr_Tipologia = '{building_types[selected_building_type]}'").df() |
| 95 | + readable_columns = {**default_columns, **{col: col for col in result.columns if col not in default_columns}} |
| 96 | + |
| 97 | + if show_all_columns: |
| 98 | + st.dataframe(result) |
| 99 | + else: |
| 100 | + display_df = result[list(default_columns.keys())].rename(columns=default_columns) |
| 101 | + st.dataframe(display_df) |
| 102 | + |
| 103 | + with mapTab: |
| 104 | + pass |
| 105 | + |
65 | 106 | except Exception as e: |
66 | | - print(f"An error occurred: {e}") |
| 107 | + st.error(f"An error occurred: {e}") |
67 | 108 | return 1 |
68 | 109 |
|
69 | 110 | return 0 |
|
0 commit comments