import streamlit as st import pandas as pd import os import joblib import numpy as np import math import folium import json import base64 from io import BytesIO from pathlib import Path from PIL import Image from streamlit_folium import st_folium # --- UTILS --- @st.cache_data def get_image_base64(img_path): img = Image.open(img_path).convert("RGBA") w, h = img.size buffered = BytesIO() img.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode("ascii") return f"data:image/png;base64,{img_str}", w, h def calculate_error(z_real, x_real, y_real, z_pred, x_pred, y_pred): z_err = abs(z_real - z_pred) dist_err = math.sqrt((x_real - x_pred)**2 + (y_real - y_pred)**2) return z_err, dist_err def show_test_inference(cfg): st.subheader("๐งช Test Inferenza Offline") MODEL_DIR = Path("/data/model") TEST_SAMPLES_DIR = Path("/data/train/testsamples") MAPS_DIR = Path("/data/maps") available_models = sorted([m.name for m in MODEL_DIR.glob("model_camp_*.joblib")], reverse=True) test_files = sorted([f.name for f in TEST_SAMPLES_DIR.glob("*.csv")]) if not available_models or not test_files: st.warning("Verifica la presenza di modelli e campioni di test.") return col1, col2 = st.columns(2) selected_model = col1.selectbox("๐ฏ Seleziona Modello:", available_models) selected_test = col2.selectbox("๐ Seleziona Fingerprint:", test_files) if "test_results" not in st.session_state: st.session_state.test_results = None if st.button("๐ ESEGUI TEST DI PRECISIONE", type="primary", use_container_width=True): try: m_pkg = joblib.load(MODEL_DIR / selected_model) delim = cfg.get('paths', {}).get('csv_delimiter', ';') df_test = pd.read_csv(TEST_SAMPLES_DIR / selected_test, sep=delim) row = df_test.iloc[0] z_real, x_real, y_real = int(round(float(row['z']))), float(row['x']), float(row['y']) gws = m_pkg['gateways_order'] fill = m_pkg.get('nan_fill', -110.0) X_in = np.array([[float(row.get(gw, fill)) for gw in gws]]) z_pred = int(m_pkg['floor_clf'].predict(X_in)[0]) x_pred, y_pred = -1.0, -1.0 if z_pred in m_pkg['xy_by_floor']: xy = m_pkg['xy_by_floor'][z_pred].predict(X_in)[0] x_pred, y_pred = float(xy[0]), float(xy[1]) z_err, dist_err = calculate_error(z_real, x_real, y_real, z_pred, x_pred, y_pred) st.session_state.test_results = { "z_real": z_real, "x_real": x_real, "y_real": y_real, "z_pred": z_pred, "x_pred": x_pred, "y_pred": y_pred, "z_err": z_err, "dist_err": dist_err, "model_used": selected_model } except Exception as e: st.error(f"Errore: {e}") if st.session_state.test_results: res = st.session_state.test_results # --- RIPRISTINO INFORMAZIONI COORDINATE --- c_info1, c_info2 = st.columns(2) with c_info1: st.info(f"๐ **Test Reale** | Piano: {res['z_real']} | X: **{res['x_real']}** | Y: **{res['y_real']}**") with c_info2: st.success(f"๐ฎ **Predizione** | Piano: {res['z_pred']} | X: **{round(res['x_pred'],1)}** | Y: **{round(res['y_pred'],1)}**") # --- LEGENDA AGGIORNATA CON NUOVI COLORI --- st.markdown(f"""