|
import streamlit as st |
|
import pandas as pd |
|
import numpy as np |
|
from sklearn.neighbors import KNeighborsRegressor |
|
from geopy.distance import geodesic |
|
import googlemaps |
|
from geopy.exc import GeocoderTimedOut |
|
|
|
|
|
def calculate_distance(lat1, lon1, lat2, lon2): |
|
coords_1 = (lat1, lon1) |
|
coords_2 = (lat2, lon2) |
|
return geodesic(coords_1, coords_2).meters |
|
|
|
|
|
def knn_predict(df, target_column, features_columns, k=5): |
|
|
|
X = df[features_columns] |
|
y = df[target_column] |
|
|
|
|
|
knn = KNeighborsRegressor(n_neighbors=k) |
|
|
|
|
|
knn.fit(X, y) |
|
|
|
|
|
predictions = knn.predict(df[features_columns]) |
|
|
|
return predictions |
|
|
|
|
|
st.set_page_config(layout="wide") |
|
|
|
|
|
st.markdown( |
|
""" |
|
<style> |
|
@font-face {font-family: 'Quicksand'; |
|
src: url('data:Quicksand-VariableFont_wght.ttf') format('truetype'); |
|
} |
|
body { |
|
color: white; |
|
background-color: #1e1e1e; |
|
font-family: 'Quicksand', sans-serif; |
|
} |
|
.st-df-header, .st-df-body, .st-df-caption { |
|
color: #f8f9fa; /* Bootstrap table header text color */ |
|
} |
|
.st-eb { |
|
background-color: #343a40; /* Streamlit exception box background color */ |
|
} |
|
</style> |
|
""", |
|
unsafe_allow_html=True |
|
) |
|
|
|
|
|
data = pd.read_excel('ven_ter_fim_PEDÓ.xlsx') |
|
|
|
|
|
selected_coords = 'Direcionada' |
|
radius_visible = True |
|
custom_address_initial = 'Av. Senador Alberto Pasqualini, 177 - Centro, Lajeado - RS, 95900-034' |
|
custom_lat = data['latitude'].median() |
|
custom_lon = data['longitude'].median() |
|
radius_in_meters = 1500 |
|
filtered_data = data |
|
|
|
|
|
max_distance = 0 |
|
for index, row in data.iterrows(): |
|
distance = calculate_distance(row['latitude'], row['longitude'], data['latitude'].mean(), data['longitude'].mean()) |
|
if distance > max_distance: |
|
max_distance = distance |
|
|
|
|
|
zoom_level = round(17 - np.log10(max_distance)) |
|
|
|
|
|
title_html = """ |
|
<style> |
|
body {{ |
|
font-family: 'Quicksand', sans-serif; |
|
}} |
|
</style> |
|
<span style='color: gray; font-size: 50px;'>aval</span> |
|
<span style='color: white; font-size: 50px;'>ia</span> |
|
<span style='color: gray; font-size: 50px;'>.NEXUS</span> |
|
""" |
|
|
|
|
|
factor_html = """ |
|
<style> |
|
body {{ |
|
font-family: 'Quicksand', sans-serif; |
|
}} |
|
</style> |
|
<a href='https://huggingface.co/spaces/DavidSB/avaliaFACTOR' target='_blank' style='text-decoration: none; color: inherit;'> |
|
<span style='color: gray; font-size: 20px;'>aval</span> |
|
<span style='color: white; font-size: 20px;'>ia</span> |
|
<span style='color: gray; font-size: 20px;'>.FACTOR</span> |
|
""" |
|
|
|
|
|
evo_html = """ |
|
<style> |
|
body {{ |
|
font-family: 'Quicksand', sans-serif; |
|
}} |
|
</style> |
|
<a href='https://huggingface.co/spaces/DavidSB/avalia.EVO' target='_blank' style='text-decoration: none; color: inherit;'> |
|
<span style='color: gray; font-size: 20px;'>aval</span> |
|
<span style='color: white; font-size: 20px;'>ia</span> |
|
<span style='color: gray; font-size: 20px;'>.EVO</span> |
|
""" |
|
|
|
|
|
|
|
with st.sidebar: |
|
|
|
|
|
st.sidebar.markdown(title_html, unsafe_allow_html=True) |
|
|
|
selected_coords = st.selectbox('Selecione o tipo de pesquisa', ['Ampla', 'Direcionada']) |
|
|
|
if selected_coords == 'Direcionada': |
|
custom_address = st.text_input('Informe o endereço', custom_address_initial) |
|
radius_visible = True |
|
|
|
else: |
|
custom_address = "Lajeado, Rio Grande do Sul, Brazil" |
|
radius_visible = False |
|
max_distance_all = 0 |
|
|
|
max_distance_all = 0 |
|
|
|
|
|
gmaps = googlemaps.Client(key='AIzaSyDoJ6C7NE2CHqFcaHTnhreOfgJeTk4uSH0') |
|
|
|
try: |
|
location = gmaps.geocode(custom_address)[0]['geometry']['location'] |
|
custom_lat, custom_lon = location['lat'], location['lng'] |
|
except (IndexError, GeocoderTimedOut): |
|
st.error("Erro: Não foi possível geocodificar o endereço fornecido. Por favor, verifique e tente novamente.") |
|
|
|
|
|
if selected_coords == 'Direcionada': |
|
zoom_level = st.slider('Nível de zoom', min_value=1, max_value=15, value=zoom_level) |
|
else: |
|
for index, row in data.iterrows(): |
|
distance_all = calculate_distance(row['latitude'], row['longitude'], data['latitude'].mean(), data['longitude'].mean()) |
|
if distance_all > max_distance_all: |
|
max_distance_all = distance_all |
|
|
|
|
|
zoom_level_all = round(15 - np.log10(max_distance_all)) |
|
|
|
|
|
zoom_level = st.slider('Nível de zoom', min_value=1, max_value=15, value=zoom_level_all) |
|
|
|
|
|
if radius_visible: |
|
radius_in_meters = st.slider('Selecione raio (em metros)', min_value=100, max_value=5000, value=1000) |
|
|
|
|
|
st.sidebar.markdown(factor_html, unsafe_allow_html=True) |
|
st.sidebar.markdown(evo_html, unsafe_allow_html=True) |
|
|
|
|
|
|
|
if selected_coords == 'Direcionada': |
|
filtered_data = data[data.apply(lambda x: calculate_distance(x['latitude'], x['longitude'], custom_lat, custom_lon), axis=1) <= radius_in_meters] |
|
filtered_data = filtered_data.dropna() |
|
|
|
|
|
st.markdown(f"""<style> |
|
.map {{ |
|
width: 100%; |
|
height: 100vh; |
|
}} |
|
</style>""", unsafe_allow_html=True) |
|
|
|
|
|
if selected_coords == 'Direcionada' and radius_visible: |
|
|
|
predicted_vunit = knn_predict(filtered_data, 'Vunit', ['latitude', 'longitude', 'Area']) |
|
|
|
filtered_data['Predicted_Vunit'] = predicted_vunit |
|
|
|
|
|
with st.container(): |
|
if selected_coords == 'Direcionada': |
|
st.map(filtered_data, zoom=zoom_level, use_container_width=True) |
|
elif selected_coords == 'Ampla': |
|
st.map(data, zoom=zoom_level, use_container_width=True) |
|
|
|
|
|
if 'Predicted_Vunit' in filtered_data.columns: |
|
st.write("Valores (R$/m²) previstos com algoritmo KNN:") |
|
st.write(filtered_data[['latitude', 'longitude', 'Vunit', 'Predicted_Vunit']]) |