File size: 7,997 Bytes
bbe788d
 
 
897ea2d
bbe788d
9fb5d19
 
 
a580030
 
 
 
 
 
f573577
a580030
 
 
 
 
 
 
 
 
 
 
f573577
a580030
 
 
 
0697975
 
 
 
 
 
 
f2e7a61
9e1bee4
4324c06
cbc8d85
0697975
 
 
994bcfa
0697975
 
 
 
 
 
 
 
 
 
 
 
f573577
bbe788d
f573577
bbe788d
a580030
ff1b036
a580030
2737b30
ff1b036
 
2737b30
a580030
bbe788d
643a822
 
 
 
 
 
 
81d3eef
059564b
81d3eef
5cdc637
02c8225
f573577
9e1bee4
 
 
5cdc637
 
 
 
de141c7
 
 
f573577
02c8225
5cdc637
703e3e3
5cdc637
9e1bee4
 
 
5cdc637
 
 
 
fac9697
af3bf18
 
 
703e3e3
 
5cdc637
703e3e3
5cdc637
9e1bee4
 
 
5cdc637
 
 
 
fac9697
af3bf18
a998bd1
 
99d8e2d
5cdc637
703e3e3
b5290a2
 
02c8225
bbe788d
02c8225
f573577
 
 
02c8225
ff1b036
9fb5d19
ff1b036
287a688
80eb9a3
044f186
b5290a2
ba96f19
80eb9a3
044f186
bbe788d
81d3eef
9fb5d19
 
 
 
 
 
 
 
ba96f19
9fb5d19
b5290a2
ff1b036
81d3eef
be17c91
 
 
 
 
 
5db2dc0
 
be17c91
5db2dc0
 
bbe788d
6262455
 
 
bbe788d
de141c7
fac9697
 
de141c7
 
a580030
ff1b036
d669f57
a580030
fd31ef9
efca6f0
 
 
 
 
 
 
 
897ea2d
ff1b036
f573577
 
 
 
897ea2d
4e8c737
897ea2d
ff1b036
fd31ef9
ff1b036
e949094
897ea2d
f573577
 
7d796d3
f573577
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
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

# Function to calculate distance in meters between two coordinates
def calculate_distance(lat1, lon1, lat2, lon2):
    coords_1 = (lat1, lon1)
    coords_2 = (lat2, lon2)
    return geodesic(coords_1, coords_2).meters

# Function to apply KNN and return V_oferta values
def knn_predict(df, target_column, features_columns, k=5):
    # Separate features and target variable
    X = df[features_columns]
    y = df[target_column]

    # Create KNN regressor
    knn = KNeighborsRegressor(n_neighbors=k)

    # Fit the model
    knn.fit(X, y)

    # Use the model to predict V_oferta for the filtered_data
    predictions = knn.predict(df[features_columns])

    return predictions

# Set wide mode
st.set_page_config(layout="wide")

# Set dark theme
st.markdown(
    """
    <style>
        @font-face {font-family: 'Quicksand';
        src: url('font/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
)


# Create a DataFrame with sample data
data = pd.read_excel('ven_fim_PEDÓ_nov_23.xlsx)

# Initialize variables to avoid NameError
selected_coords = 'Direcionada'
radius_visible = True
custom_address_initial = 'Av. Senador Alberto Pasqualini, 177 - Centro, Lajeado - RS, 95900-034'  # Initial custom address
custom_lat = data['latitude'].median()
custom_lon = data['longitude'].median()
radius_in_meters = 1500
filtered_data = data  # Initialize with the entire dataset

# Find the maximum distance between coordinates
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

# Calculate a zoom level based on the maximum distance
zoom_level = round(17 - np.log10(max_distance))

# Set font to 'Quicksand' for title_html
title_html = """
        <style>
        @font-face {font-family: 'Quicksand';
        src: url('font/Quicksand-VariableFont_wght.ttf') format('truetype');
        }
        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>
    """

# Set font to 'Quicksand' for factor_html
factor_html = """
    <style>
        @font-face {font-family: 'Quicksand';
        src: url('font/Quicksand-VariableFont_wght.ttf') format('truetype');
        }
        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>
"""

# Set font to 'Quicksand' for evo_html
evo_html = """
    <style>
        @font-face {font-family: 'Quicksand';
        src: url('font/Quicksand-VariableFont_wght.ttf') format('truetype');
        }
        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>
"""


# Create a sidebar for controls
with st.sidebar:
    #st.title('avalia.se')

    st.sidebar.markdown(title_html, unsafe_allow_html=True)

    # Add a dropdown for filtering "Tipo"
    selected_tipo = st.selectbox('Filtrar por Tipo', data['Tipo'].unique())
    
    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  # Show radius slider for custom coordinates
        # No need to initialize max_distance_all here
    else:
        custom_address = "Lajeado, Rio Grande do Sul, Brazil"  # Default address
        radius_visible = False  # Hide radius slider for random coordinates
        max_distance_all = 0  # Initialize max_distance_all here

        max_distance_all = 0  # Initialize max_distance_all here

    # Geocode the custom address using the Google Maps API
    gmaps = googlemaps.Client(key='AIzaSyDoJ6C7NE2CHqFcaHTnhreOfgJeTk4uSH0')  # Replace with your API key

    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.")

    # Slider for setting the zoom level
    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

        # Calculate a zoom level based on the maximum distance of the entire dataset
        zoom_level_all = round(15 - np.log10(max_distance_all))

        # Slider for setting the zoom level based on the entire dataset
        zoom_level = st.slider('Nível de zoom', min_value=1, max_value=15, value=zoom_level_all)

    # Conditionally render the radius slider
    if radius_visible:
        radius_in_meters = st.slider('Selecione raio (em metros)', min_value=100, max_value=5000, value=1000)

    # Links to other apps at the bottom of the sidebar
    st.sidebar.markdown(factor_html, unsafe_allow_html=True)
    st.sidebar.markdown(evo_html, unsafe_allow_html=True)


# Filter data based on the radius
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()  # Drop rows with NaN values

# Add a custom CSS class to the map container
st.markdown(f"""<style>
.map {{
  width: 100%;
  height: 100vh;
}}
</style>""", unsafe_allow_html=True)

# Check if KNN should be applied
if selected_coords == 'Direcionada' and radius_visible:
    # Apply KNN and get predicted V_oferta values
    predicted_V_oferta = knn_predict(filtered_data, 'V_oferta', ['latitude', 'longitude', 'Area'])  # Update with your features
    # Add predicted V_oferta values to filtered_data
    filtered_data['Predicted_V_oferta'] = predicted_V_oferta

# Display the map and filtered_data
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)

# Display the predicted V_oferta values if applicable
if 'Predicted_V_oferta' in filtered_data.columns:
    st.write("Valores (R$/m²) previstos com algoritmo KNN:")
    st.write(filtered_data[['latitude', 'longitude', 'V_oferta', 'Predicted_V_oferta']])