diff --git a/urbantrips/dashboard/dash_utils.py b/urbantrips/dashboard/dash_utils.py index 26efa84..300e23f 100644 --- a/urbantrips/dashboard/dash_utils.py +++ b/urbantrips/dashboard/dash_utils.py @@ -354,60 +354,124 @@ def create_data_folium(etapas, agg_hora=False, agg_distancia=False, agg_cols_etapas=[], - agg_cols_viajes=[]): - - etapas = calculate_weighted_means_ods(etapas, - agg_cols_etapas, - ['distance_osm_drive', 'lat1_norm', 'lon1_norm', 'lat2_norm', - 'lon2_norm', 'lat3_norm', 'lon3_norm', 'lat4_norm', 'lon4_norm'], - - 'factor_expansion_linea', - agg_transferencias=agg_transferencias, - agg_modo=agg_modo, - agg_hora=agg_hora, - agg_distancia=agg_distancia, - zero_to_nan=['lat1_norm', 'lon1_norm', 'lat2_norm', 'lon2_norm', 'lat3_norm', 'lon3_norm', 'lat4_norm', 'lon4_norm']) - - etapas[['lat1_norm', - 'lon1_norm', - 'lat2_norm', - 'lon2_norm', - 'lat3_norm', - 'lon3_norm', - 'lat4_norm', - 'lon4_norm']] = etapas[['lat1_norm', - 'lon1_norm', - 'lat2_norm', - 'lon2_norm', - 'lat3_norm', - 'lon3_norm', - 'lat4_norm', - 'lon4_norm']].fillna(0) - - viajes = calculate_weighted_means_ods(etapas, - agg_cols_viajes, - ['distance_osm_drive', - 'lat1_norm', - 'lon1_norm', - 'lat4_norm', - 'lon4_norm'], - 'factor_expansion_linea', - agg_transferencias=agg_transferencias, - agg_modo=agg_modo, - agg_hora=agg_hora, - agg_distancia=agg_distancia, - zero_to_nan=['lat1_norm', 'lon1_norm', 'lat4_norm', 'lon4_norm']) - viajes[['lat1_norm', - 'lon1_norm', - 'lat4_norm', - 'lon4_norm']] = viajes[['lat1_norm', - 'lon1_norm', - 'lat4_norm', - 'lon4_norm']].fillna(0) - - if 'id_polygon' not in viajes_matrices.columns: - viajes_matrices['id_polygon'] = 'NONE' + agg_cols_viajes=[], + desc_etapas = True, + desc_viajes = True, + desc_origenes = True, + desc_destinos = True, + desc_transferencias = False): + + + if desc_transferencias: + + t1 = etapas.loc[etapas.transfer1_norm!='', ['zona', + 'transfer1_norm', + 'lat2_norm', + 'lon2_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'distancia', + 'factor_expansion_linea',]].rename(columns={'transfer1_norm':'transfer', 'lat2_norm':'lat_norm', 'lon2_norm':'lon_norm'}) + t2 = etapas.loc[etapas.transfer2_norm!='', ['zona', + 'transfer2_norm', + 'lat3_norm', + 'lon3_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'distancia', + 'factor_expansion_linea',]].rename(columns={'transfer2_norm':'transfer', 'lat3_norm':'lat_norm', 'lon3_norm':'lon_norm'}) + transferencias = pd.concat([t1,t2], ignore_index=True) + transferencias['id_polygon'] = 'NONE' + + trans_cols_o = ['id_polygon', + 'zona', + 'transfer', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'distancia'] + + transferencias = creo_bubble_od(transferencias, + aggregate_cols=trans_cols_o, + weighted_mean_cols=['lat_norm', 'lon_norm'], + weight_col='factor_expansion_linea', + agg_transferencias=agg_transferencias, + agg_modo=agg_modo, + agg_hora=agg_hora, + agg_distancia=agg_distancia, + od='transfer', + lat='lat_norm', + lon='lon_norm') + else: + transferencias = pd.DataFrame([]) + + if desc_etapas | desc_transferencias: + etapas = calculate_weighted_means_ods(etapas, + agg_cols_etapas, + ['distance_osm_drive', 'lat1_norm', 'lon1_norm', 'lat2_norm', + 'lon2_norm', 'lat3_norm', 'lon3_norm', 'lat4_norm', 'lon4_norm'], + 'factor_expansion_linea', + agg_transferencias=agg_transferencias, + agg_modo=agg_modo, + agg_hora=agg_hora, + agg_distancia=agg_distancia, + zero_to_nan=['lat1_norm', 'lon1_norm', 'lat2_norm', 'lon2_norm', 'lat3_norm', 'lon3_norm', 'lat4_norm', 'lon4_norm']) + + etapas[['lat1_norm', + 'lon1_norm', + 'lat2_norm', + 'lon2_norm', + 'lat3_norm', + 'lon3_norm', + 'lat4_norm', + 'lon4_norm']] = etapas[['lat1_norm', + 'lon1_norm', + 'lat2_norm', + 'lon2_norm', + 'lat3_norm', + 'lon3_norm', + 'lat4_norm', + 'lon4_norm']].fillna(0) + + etapas = df_to_linestrings(etapas, + lat_cols=['lat1_norm', 'lat2_norm', 'lat3_norm', 'lat4_norm'], lon_cols=['lon1_norm', 'lon2_norm', 'lon3_norm', 'lon4_norm']) + etapas = etapas[etapas.inicio_norm != etapas.fin_norm].copy() + + if desc_viajes: + viajes = calculate_weighted_means_ods(etapas, + agg_cols_viajes, + ['distance_osm_drive', + 'lat1_norm', + 'lon1_norm', + 'lat4_norm', + 'lon4_norm'], + 'factor_expansion_linea', + agg_transferencias=agg_transferencias, + agg_modo=agg_modo, + agg_hora=agg_hora, + agg_distancia=agg_distancia, + zero_to_nan=['lat1_norm', 'lon1_norm', 'lat4_norm', 'lon4_norm']) + viajes[['lat1_norm', + 'lon1_norm', + 'lat4_norm', + 'lon4_norm']] = viajes[['lat1_norm', + 'lon1_norm', + 'lat4_norm', + 'lon4_norm']].fillna(0) + + if 'id_polygon' not in viajes_matrices.columns: + viajes_matrices['id_polygon'] = 'NONE' + + viajes = df_to_linestrings(viajes, + lat_cols=['lat1_norm', 'lat4_norm'], lon_cols=['lon1_norm', 'lon4_norm']) + + viajes = viajes[viajes.inicio_norm != viajes.fin_norm].copy() + else: + viajes = pd.DataFrame([]) + matriz = agg_matriz(viajes_matrices, aggregate_cols=['id_polygon', 'zona', 'Origen', 'Destino', 'transferencia', 'modo_agregado', 'rango_hora', 'distancia'], @@ -429,37 +493,41 @@ def create_data_folium(etapas, bubble_cols_d = ['id_polygon', 'zona', 'fin', 'transferencia', 'modo_agregado', 'rango_hora', 'distancia'] - origen = creo_bubble_od(viajes_matrices, - aggregate_cols=bubble_cols_o, - weighted_mean_cols=['lat1', 'lon1'], - weight_col='factor_expansion_linea', - agg_transferencias=agg_transferencias, - agg_modo=agg_modo, - agg_hora=agg_hora, - agg_distancia=agg_distancia, - od='inicio', - lat='lat1', - lon='lon1') - - destino = creo_bubble_od(viajes_matrices, - aggregate_cols=bubble_cols_d, - weighted_mean_cols=['lat4', 'lon4'], - weight_col='factor_expansion_linea', - agg_transferencias=agg_transferencias, - agg_modo=agg_modo, - agg_hora=agg_hora, - agg_distancia=agg_distancia, - od='fin', - lat='lat4', - lon='lon4') - - etapas = df_to_linestrings(etapas, - lat_cols=['lat1_norm', 'lat2_norm', 'lat3_norm', 'lat4_norm'], lon_cols=['lon1_norm', 'lon2_norm', 'lon3_norm', 'lon4_norm']) + if desc_origenes: + origen = creo_bubble_od(viajes_matrices, + aggregate_cols=bubble_cols_o, + weighted_mean_cols=['lat1', 'lon1'], + weight_col='factor_expansion_linea', + agg_transferencias=agg_transferencias, + agg_modo=agg_modo, + agg_hora=agg_hora, + agg_distancia=agg_distancia, + od='inicio', + lat='lat1', + lon='lon1') + else: + origen = pd.DataFrame([]) + + if desc_destinos: + destino = creo_bubble_od(viajes_matrices, + aggregate_cols=bubble_cols_d, + weighted_mean_cols=['lat4', 'lon4'], + weight_col='factor_expansion_linea', + agg_transferencias=agg_transferencias, + agg_modo=agg_modo, + agg_hora=agg_hora, + agg_distancia=agg_distancia, + od='fin', + lat='lat4', + lon='lon4') + else: + destino = pd.DataFrame([]) + + if not desc_etapas: + etapas = pd.DataFrame([]) - viajes = df_to_linestrings(viajes, - lat_cols=['lat1_norm', 'lat4_norm'], lon_cols=['lon1_norm', 'lon4_norm']) - return etapas, viajes, matriz, origen, destino + return etapas, viajes, matriz, origen, destino, transferencias @st.cache_data @@ -518,4 +586,15 @@ def extract_hex_colors_from_cmap(cmap, n=5): # Convert the colors to hex format hex_colors = [mcolors.rgb2hex(color) for color in colors] - return hex_colors \ No newline at end of file + return hex_colors + +@st.cache_data +def bring_latlon(): + try: + latlon = levanto_tabla_sql('agg_etapas', 'dash', 'SELECT lat1_norm, lon1_norm FROM agg_etapas ORDER BY RANDOM() LIMIT 100;') + lat = latlon['lat1_norm'].mean() + lon = latlon['lon1_norm'].mean() + latlon = [lat, lon] + except: + latlon = [-34.593, -58.451] + return latlon \ No newline at end of file diff --git "a/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" "b/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" index 1f1bb11..bf57c32 100644 --- "a/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" +++ "b/urbantrips/dashboard/pages/3_L\303\255neas de Deseo.py" @@ -2,7 +2,7 @@ import pandas as pd import geopandas as gpd import folium -from streamlit_folium import st_folium +from streamlit_folium import st_folium, folium_static import mapclassify import plotly.express as px from folium import Figure @@ -11,41 +11,48 @@ levanto_tabla_sql, get_logo, create_data_folium, traigo_indicadores, extract_hex_colors_from_cmap, - iniciar_conexion_db, normalize_vars - + iniciar_conexion_db, normalize_vars, + bring_latlon ) -from streamlit_folium import folium_static def crear_mapa_lineas_deseo(df_viajes, df_etapas, zonif, origenes, destinos, + transferencias, var_fex, cmap_viajes='Blues', cmap_etapas='Greens', map_title='', savefile='', k_jenks=5, - ): + latlon=''): m = '' - if (len(df_viajes) > 0) | (len(df_etapas) > 0) | (len(origenes) > 0) | (len(destinos) > 0): - if len(df_etapas) > 0: - y_val = df_etapas.sample(100, replace=True).geometry.representative_point().y.mean() - x_val = df_etapas.sample(100, replace=True).geometry.representative_point().x.mean() - elif len(df_viajes) > 0: - y_val = df_viajes.sample(100, replace=True).geometry.representative_point().y.mean() - x_val = df_viajes.sample(100, replace=True).geometry.representative_point().x.mean() - elif len(origenes) > 0: - y_val = origenes.sample(100, replace=True).geometry.representative_point().y.mean() - x_val = origenes.sample(100, replace=True).geometry.representative_point().x.mean() - elif len(destinos) > 0: - y_val = destinos.sample(100, replace=True).geometry.representative_point().y.mean() - x_val = destinos.sample(100, replace=True).geometry.representative_point().x.mean() + # if (len(df_viajes) > 0) | (len(df_etapas) > 0) | (len(origenes) > 0) | (len(destinos) > 0) | (len(transferencias) > 0) | (desc_zonif): + if True: + if len(latlon) == 0: + if len(df_etapas) > 0: + y_val = df_etapas.sample(100, replace=True).geometry.representative_point().y.mean() + x_val = df_etapas.sample(100, replace=True).geometry.representative_point().x.mean() + elif len(df_viajes) > 0: + y_val = df_viajes.sample(100, replace=True).geometry.representative_point().y.mean() + x_val = df_viajes.sample(100, replace=True).geometry.representative_point().x.mean() + elif len(origenes) > 0: + y_val = origenes.sample(100, replace=True).geometry.representative_point().y.mean() + x_val = origenes.sample(100, replace=True).geometry.representative_point().x.mean() + elif len(destinos) > 0: + y_val = destinos.sample(100, replace=True).geometry.representative_point().y.mean() + x_val = destinos.sample(100, replace=True).geometry.representative_point().x.mean() + elif len(transferencias) > 0: + y_val = transferencias.sample(100, replace=True).geometry.representative_point().y.mean() + x_val = transferencias.sample(100, replace=True).geometry.representative_point().x.mean() + + latlon = [y_val, x_val] fig = Figure(width=800, height=600) - m = folium.Map(location=[y_val, x_val], + m = folium.Map(location=latlon, zoom_start=10, tiles='cartodbpositron') colors_viajes = extract_hex_colors_from_cmap( @@ -176,6 +183,37 @@ def crear_mapa_lineas_deseo(df_viajes, n += 1 line_w += 5 + if len(transferencias) > 0: + try: + bins = [transferencias['factor_expansion_linea'].min()-1] + \ + mapclassify.FisherJenks( + transferencias['factor_expansion_linea'], k=5).bins.tolist() + except ValueError: + bins = [transferencias['factor_expansion_linea'].min()-1] + \ + mapclassify.FisherJenks( + transferencias['factor_expansion_linea'], k=5-3).bins.tolist() + + range_bins = range(0, len(bins)-1) + bins_labels = [ + f'{int(bins[n])} a {int(bins[n+1])} transferencias' for n in range_bins] + + transferencias['cuts'] = pd.cut( + transferencias['factor_expansion_linea'], bins=bins, labels=bins_labels) + + n = 0 + line_w = 10 + for i in bins_labels: + + transferencias[transferencias.cuts == i].explore( + m=m, + color="#FF0000", + style_kwds={'fillOpacity': 0.1, 'weight': line_w}, + name=i, + tooltip=False, + ) + n += 1 + line_w += 5 + # Agrego zonificación if len(zonif) > 0: geojson = zonif.to_json() @@ -194,7 +232,7 @@ def crear_mapa_lineas_deseo(df_viajes, fields=['id'], labels=False, sticky=False) ).add_to(m) - folium.LayerControl(name='xxx').add_to(m) + folium.LayerControl(name='mapa').add_to(m) return m @@ -330,11 +368,16 @@ def hay_cambios_en_filtros(current, last): distancia_all = ['Todas'] + distancia_all_[distancia_all_.distancia != '99'].distancia.unique().tolist() distancia = col1.selectbox('Distancia', options=distancia_all) - desc_etapas = col1.checkbox( - 'Etapas', value=False) - - desc_viajes = col1.checkbox( - 'Viajes', value=True) + desc_et_vi = col1.selectbox('Datos de', options=['Etapas', 'Viajes', 'Ninguno'], index=1) + if desc_et_vi == 'Viajes': + desc_viajes = True + desc_etapas = False + elif desc_et_vi == 'Etapas': + desc_viajes = False + desc_etapas = True + else: + desc_viajes = False + desc_etapas = False desc_origenes = col1.checkbox( ':blue[Origenes]', value=False) @@ -342,6 +385,9 @@ def hay_cambios_en_filtros(current, last): desc_destinos = col1.checkbox( ':orange[Destinos]', value=False) + desc_transferencias = col1.checkbox( + ':red[Transferencias]', value=False) + desc_zonif = col1.checkbox( 'Mostrar zonificación', value=True) if desc_zonif: @@ -359,10 +405,13 @@ def hay_cambios_en_filtros(current, last): 'rango_hora': None if rango_hora == 'Todos' else rango_hora, 'distancia': None if distancia == 'Todas' else distancia, } + current_options = { 'desc_etapas': desc_etapas, 'desc_viajes': desc_viajes, 'desc_origenes': desc_origenes, 'desc_destinos': desc_destinos, + 'desc_et_vi': desc_et_vi, + 'desc_transferencias': desc_transferencias, 'desc_zonif': desc_zonif, } @@ -445,55 +494,38 @@ def hay_cambios_en_filtros(current, last): st.session_state.desc_transfers = True else: st.session_state.desc_transfers = False - # if transf_list == 'Con transferencia': - # st.session_state.etapas_ = st.session_state.etapas_[(st.session_state.etapas_.transferencia == 1)] - # st.session_state.matrices_ = st.session_state.matrices_[(st.session_state.matrices_.transferencia == 1)] - # elif transf_list == 'Sin transferencia': - # st.session_state.etapas_ = st.session_state.etapas_[(st.session_state.etapas_.transferencia == 0)] - # st.session_state.matrices_ = st.session_state.matrices_[(st.session_state.matrices_.transferencia == 0)] - # else: - # st.session_state.etapas_ = pd.DataFrame([]) - # st.session_state.matrices_ = pd.DataFrame([]) - + if modos_list == 'Todos': st.session_state.desc_modos = True else: st.session_state.desc_modos = False - # st.session_state.etapas_ = st.session_state.etapas_[ - # (st.session_state.etapas_.modo_agregado.str.lower() == modos_list.lower())] - # st.session_state.matrices_ = st.session_state.matrices_[ - # (st.session_state.matrices_.modo_agregado.str.lower() == modos_list.lower())] if rango_hora == 'Todos': st.session_state.desc_horas = True else: st.session_state.desc_horas = False - # st.session_state.etapas_ = st.session_state.etapas_[(st.session_state.etapas_.rango_hora == rango_hora)] - # st.session_state.matrices_ = st.session_state.matrices_[(st.session_state.matrices_.rango_hora == rango_hora)] if distancia == 'Todas': st.session_state.desc_distancia = True else: st.session_state.desc_distancia = False - # st.session_state.etapas_ = st.session_state.etapas_[(st.session_state.etapas_.distancia == distancia)] - # st.session_state.matrices_ = st.session_state.matrices_[(st.session_state.matrices_.distancia == distancia)] st.session_state.agg_cols_etapas = ['zona', - 'inicio_norm', - 'transfer1_norm', - 'transfer2_norm', - 'fin_norm', - 'transferencia', - 'modo_agregado', - 'rango_hora', - 'distancia'] + 'inicio_norm', + 'transfer1_norm', + 'transfer2_norm', + 'fin_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'distancia'] st.session_state.agg_cols_viajes = ['zona', - 'inicio_norm', - 'fin_norm', - 'transferencia', - 'modo_agregado', - 'rango_hora', - 'distancia'] + 'inicio_norm', + 'fin_norm', + 'transferencia', + 'modo_agregado', + 'rango_hora', + 'distancia'] if len(st.session_state.etapas_)==0: col2.write('No hay datos para mostrar') @@ -508,53 +540,57 @@ def hay_cambios_en_filtros(current, last): st.session_state.last_options = current_options.copy() st.session_state.data_cargada = True - st.session_state.etapas, st.session_state.viajes, st.session_state.matriz, st.session_state.origenes, st.session_state.destinos = create_data_folium(st.session_state.etapas_, - st.session_state.matrices_, - agg_transferencias=st.session_state.desc_transfers, - agg_modo=st.session_state.desc_modos, - agg_hora=st.session_state.desc_horas, - agg_distancia=st.session_state.desc_distancia, - agg_cols_etapas=st.session_state.agg_cols_etapas, - agg_cols_viajes=st.session_state.agg_cols_viajes) - - st.session_state.etapas = st.session_state.etapas[st.session_state.etapas.inicio_norm != st.session_state.etapas.fin_norm].copy() - st.session_state.viajes = st.session_state.viajes[st.session_state.viajes.inicio_norm != st.session_state.viajes.fin_norm].copy() - - if not desc_etapas: - st.session_state.etapas = pd.DataFrame([]) - - if not desc_viajes: - st.session_state.viajes = pd.DataFrame([]) - - if not desc_origenes: - st.session_state.origenes = pd.DataFrame([]) - - if not desc_destinos: - st.session_state.destinos = pd.DataFrame([]) - - if (len(st.session_state.etapas) > 0) | (len(st.session_state.viajes) > 0) | (len(st.session_state.origenes) > 0) | (len(st.session_state.destinos) > 0): - - m = crear_mapa_lineas_deseo(df_viajes=st.session_state.viajes, - df_etapas=st.session_state.etapas, - zonif=zonif, - origenes=st.session_state.origenes, - destinos=st.session_state.destinos, - var_fex='factor_expansion_linea', - cmap_viajes='Blues', - cmap_etapas='Greens', - map_title='Líneas de Deseo', - savefile='', - k_jenks=5) - if m: - st.session_state.map = m + st.session_state.etapas, \ + st.session_state.viajes, \ + st.session_state.matriz, \ + st.session_state.origenes, \ + st.session_state.destinos, \ + st.session_state.transferencias = create_data_folium(st.session_state.etapas_, + st.session_state.matrices_, + agg_transferencias=st.session_state.desc_transfers, + agg_modo=st.session_state.desc_modos, + agg_hora=st.session_state.desc_horas, + agg_distancia=st.session_state.desc_distancia, + agg_cols_etapas=st.session_state.agg_cols_etapas, + agg_cols_viajes=st.session_state.agg_cols_viajes, + desc_etapas=desc_etapas, + desc_viajes=desc_viajes, + desc_origenes=desc_origenes, + desc_destinos=desc_destinos, + desc_transferencias=desc_transferencias) + + + if ((len(st.session_state.etapas) > 0) \ + | (len(st.session_state.viajes) > 0) \ + | (len(st.session_state.origenes) > 0) \ + | (len(st.session_state.destinos) > 0) \ + | (len(st.session_state.transferencias) > 0))\ + | (desc_zonif): + + latlon = bring_latlon() + st.session_state.map = crear_mapa_lineas_deseo(df_viajes=st.session_state.viajes, + df_etapas=st.session_state.etapas, + zonif=zonif, + origenes=st.session_state.origenes, + destinos=st.session_state.destinos, + transferencias=st.session_state.transferencias, + var_fex='factor_expansion_linea', + cmap_viajes='Blues', + cmap_etapas='Greens', + map_title='Líneas de Deseo', + savefile='', + k_jenks=5, + latlon=latlon) + if st.session_state.map: with col2: folium_static(st.session_state.map, width=1000, height=800) + # output = st_folium(st.session_state.map, width=1000, height=800, key='m', returned_objects=["center"]) else: col2.text("No hay datos suficientes para mostrar el mapa.") - - + else: + col2.text("No hay datos suficientes para mostrar el mapa.") with st.expander('Indicadores'): diff --git a/urbantrips/dashboard/pages/4_Poligonos.py b/urbantrips/dashboard/pages/4_Poligonos.py index 4c7750a..2a56783 100644 --- a/urbantrips/dashboard/pages/4_Poligonos.py +++ b/urbantrips/dashboard/pages/4_Poligonos.py @@ -35,8 +35,8 @@ def crear_mapa_poligonos(df_viajes, if (len(df_viajes) > 0) | (len(df_etapas) > 0) | (len(origenes) > 0) | (len(destinos) > 0): fig = Figure(width=800, height=600) - m = folium.Map(location=[poly.sample(100, replace=True).geometry.representative_point().y.mean( - ), poly.sample(100, replace=True).geometry.representative_point().x.mean()], zoom_start=9, tiles='cartodbpositron') + m = folium.Map(location=[poly.geometry.representative_point().y.mean( + ), poly.geometry.representative_point().x.mean()], zoom_start=9, tiles='cartodbpositron') colors_viajes = extract_hex_colors_from_cmap( cmap='viridis_r', n=k_jenks) @@ -347,11 +347,16 @@ def hay_cambios_en_filtros(current, last): distancia_all = ['Todas'] + distancia_all_[distancia_all_.distancia != '99'].distancia.unique().tolist() distancia = col1.selectbox('Distancia', options=distancia_all) - desc_etapas = col1.checkbox( - 'Etapas', value=False) - - desc_viajes = col1.checkbox( - 'Viajes', value=True) + desc_et_vi = col1.selectbox('Datos de', options=['Etapas', 'Viajes', 'Ninguno'], index=1) + if desc_et_vi == 'Viajes': + desc_viajes = True + desc_etapas = False + elif desc_et_vi == 'Etapas': + desc_viajes = False + desc_etapas = True + else: + desc_viajes = False + desc_etapas = False desc_origenes = col1.checkbox( ':blue[Origenes]', value=False) @@ -398,7 +403,8 @@ def hay_cambios_en_filtros(current, last): 'desc_destinos': desc_destinos, 'desc_zonif': desc_zonif, 'show_poly' : st.session_state.show_poly, - 'desc_cuenca': desc_cuenca + 'desc_cuenca': desc_cuenca, + 'desc_et_vi': desc_et_vi } @@ -484,40 +490,34 @@ def hay_cambios_en_filtros(current, last): st.session_state.data_cargada = True - st.session_state.etapas, st.session_state.viajes, st.session_state.matriz, st.session_state.origenes, st.session_state.destinos = create_data_folium(st.session_state.etapas_, - st.session_state.matrices_, - agg_transferencias=st.session_state.desc_transfers, - agg_modo=st.session_state.desc_modos, - agg_hora=st.session_state.desc_horas, - agg_distancia=st.session_state.desc_distancia, - agg_cols_etapas=st.session_state.agg_cols_etapas, - agg_cols_viajes=st.session_state.agg_cols_viajes) - - - - st.session_state.etapas = st.session_state.etapas[st.session_state.etapas.inicio_norm != st.session_state.etapas.fin_norm].copy() - st.session_state.viajes = st.session_state.viajes[st.session_state.viajes.inicio_norm != st.session_state.viajes.fin_norm].copy() - - if not desc_etapas: - st.session_state.etapas = pd.DataFrame([]) - - if not desc_viajes: - st.session_state.viajes = pd.DataFrame([]) - - if not desc_origenes: - st.session_state.origenes = pd.DataFrame([]) - - if not desc_destinos: - st.session_state.destinos = pd.DataFrame([]) + st.session_state.etapas, \ + st.session_state.viajes, \ + st.session_state.matriz, \ + st.session_state.origenes, \ + st.session_state.destinos, \ + st.session_state.transferencias = create_data_folium(st.session_state.etapas_, + st.session_state.matrices_, + agg_transferencias=st.session_state.desc_transfers, + agg_modo=st.session_state.desc_modos, + agg_hora=st.session_state.desc_horas, + agg_distancia=st.session_state.desc_distancia, + agg_cols_etapas=st.session_state.agg_cols_etapas, + agg_cols_viajes=st.session_state.agg_cols_viajes, + desc_etapas=desc_etapas, + desc_viajes=desc_viajes, + desc_origenes=desc_origenes, + desc_destinos=desc_destinos, + desc_transferencias=False + ) - if (len(st.session_state.etapas) > 0) | (len(st.session_state.viajes) > 0) | (len(st.session_state.origenes) > 0) | (len(st.session_state.destinos) > 0): + if (len(st.session_state.etapas) > 0) | (len(st.session_state.viajes) > 0) | (len(st.session_state.origenes) > 0) | (len(st.session_state.destinos) > 0) | (len(st.session_state.transferencias) > 0) | (desc_zonif): m = crear_mapa_poligonos(df_viajes=st.session_state.viajes, df_etapas=st.session_state.etapas, poly=st.session_state.poly, zonif=st.session_state.zonif, origenes=st.session_state.origenes, - destinos=st.session_state.destinos, + destinos=st.session_state.destinos, var_fex='factor_expansion_linea', cmap_viajes='Blues', cmap_etapas='Greens', @@ -534,9 +534,6 @@ def hay_cambios_en_filtros(current, last): else: col2.text("No hay datos suficientes para mostrar el mapa.") - - - with st.expander('Indicadores'): col1, col2, col3 = st.columns([2, 2, 2]) diff --git "a/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" "b/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" index 35a7436..3f58e68 100644 --- "a/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" +++ "b/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" @@ -10,12 +10,12 @@ from folium import plugins from shapely import wkt from dash_utils import ( - iniciar_conexion_db, get_logo + iniciar_conexion_db, get_logo, bring_latlon ) from streamlit_folium import folium_static +pd.options.display.float_format = '{:,.0f}'.format - -def levanto_tabla_sql(tabla_sql, tabla_tipo="dash", query=''): +def levanto_tabla_sql_local(tabla_sql, tabla_tipo="dash", query=''): conn = iniciar_conexion_db(tipo=tabla_tipo) @@ -43,7 +43,7 @@ def levanto_tabla_sql(tabla_sql, tabla_tipo="dash", query=''): @st.cache_data def traigo_mes_dia(): - mes_dia = levanto_tabla_sql('etapas_agregadas', 'dash', 'SELECT DISTINCT mes, tipo_dia FROM etapas_agregadas;') + mes_dia = levanto_tabla_sql_local('etapas_agregadas', 'dash', 'SELECT DISTINCT mes, tipo_dia FROM etapas_agregadas;') mes = mes_dia.mes.values.tolist() tipo_dia = mes_dia.tipo_dia.values.tolist() return mes, tipo_dia @@ -72,6 +72,7 @@ def main(): logo = get_logo() st.image(logo) + latlon = bring_latlon() mes_lst, tipo_dia_lst = traigo_mes_dia() with st.expander('Selecciono zonas', expanded=True): @@ -82,7 +83,7 @@ def main(): resolution = 8 # Initialize Folium map - m = folium.Map(location=[-34.593, -58.451], zoom_start=10) + m = folium.Map(location=latlon, zoom_start=10) draw = plugins.Draw( export=False, draw_options={'polygon': True, 'rectangle': True}, @@ -118,8 +119,8 @@ def main(): zona2_str = json.dumps(zona2) col2.code(zona2_str, language='python') - with st.expander('Resultados', expanded=True): - col1, col2, col3, col4 = st.columns([1, 2, 2, 3]) + with st.expander('Zonas', expanded=False): + col1, col2, col3, col4, col5 = st.columns([1, 2, 2, 2, 2]) zona1 = st.session_state['zona_1'] zona2 = st.session_state['zona_2'] @@ -130,12 +131,100 @@ def main(): desc_tipo_dia = col1.selectbox( 'Tipo dia', options=tipo_dia_lst) + if len(zona1) > 0: + h3_values1 = ", ".join(f"'{item}'" for item in zona1) + ## Etapas + query1 = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values1}));" + etapas1 = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query1) + etapas1['Zona_1'] = 'Zona 1' + + ## Viajes + query1 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values1}) );" + viajes1 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query1) + viajes1['Zona_1'] = 'Zona 1' + + modos_e1 = etapas1.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', + 'nombre_linea': 'Línea', 'modo': 'Modo'}) + + modos_v1 = viajes1.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + + # Calculate the total and append as a new row + total_row1e = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e1['Etapas'].sum()] + }) + modos_e1 = pd.concat([modos_e1, total_row1e], ignore_index=True) + + + # Calculate the total and append as a new row + total_row1 = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v1['Viajes'].sum()] + }) + modos_v1 = pd.concat([modos_v1, total_row1], ignore_index=True) + + col2.title('Zona 1') + col2.write('Etapas') + modos_e1['Etapas'] = modos_e1['Etapas'].round() + col2.dataframe(modos_e1.set_index('Modo'), height=400, width=400) + col3.title('') + col3.write('Viajes') + modos_v1['Viajes'] = modos_v1['Viajes'].round() + col3.dataframe(modos_v1.set_index('Modo'), height=400, width=300) + if len(zona2) > 0: + h3_values2 = ", ".join(f"'{item}'" for item in zona2) + ## Etapas + query2 = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values2}));" + etapas2 = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query2) + etapas2['Zona_2'] = 'Zona 2' + + ## Viajes + query2 = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values2}) );" + viajes2 = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query2) + viajes2['Zona_2'] = 'Zona 2' + + modos_e2 = etapas2.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', + 'nombre_linea': 'Línea', 'modo': 'Modo'}) + + modos_v2 = viajes2.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + # Calculate the total and append as a new row + total_row2e = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e2['Etapas'].sum()] + }) + modos_e2 = pd.concat([modos_e2, total_row2e], ignore_index=True) + + # Calculate the total and append as a new row + total_row2 = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v2['Viajes'].sum()] + }) + modos_v2 = pd.concat([modos_v2, total_row2], ignore_index=True) + + + col4.title('Zona 2') + col4.write('Etapas') + modos_e2['Etapas'] = modos_e2['Etapas'].round() + col4.dataframe(modos_e2.set_index('Modo'), height=400, width=400) + + modos_v2['Viajes'] = modos_v2['Viajes'].round() + col5.title('') + col5.write('Viajes') + # col5.markdown(modos_v2.to_html(index=False), unsafe_allow_html=True) + col5.dataframe(modos_v2.set_index('Modo'), height=400, width=300) + + with st.expander('Viajes entre zonas', expanded=True): + col1, col2, col3, col4 = st.columns([1, 2, 2, 3]) if len(zona1) > 0 and len(zona2) > 0: h3_values = ", ".join(f"'{item}'" for item in zona1 + zona2) ## Etapas query = f"SELECT * FROM etapas_agregadas WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" - etapas = levanto_tabla_sql('etapas_agregadas', tabla_tipo='dash', query=query) + etapas = levanto_tabla_sql_local('etapas_agregadas', tabla_tipo='dash', query=query) etapas['Zona_1'] = '' etapas['Zona_2'] = '' @@ -145,23 +234,32 @@ def main(): etapas.loc[etapas.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' etapas = etapas[(etapas.Zona_1 != '') & (etapas.Zona_2 != '') & (etapas.Zona_1 != etapas.Zona_2) & (etapas.Zona_1 != etapas.Zona_2)] - - zonasod_e = etapas.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().round().rename(columns={'factor_expansion_linea':'Viajes'}) - zonasod_e['Viajes'] = zonasod_e['Viajes'].astype(int) + etapas = etapas.fillna('') + + zonasod_e = etapas.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas'}) - modos_e = etapas.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().round().rename(columns={'factor_expansion_linea':'Viajes', + modos_e = etapas.groupby(['modo', 'nombre_linea'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Etapas', 'nombre_linea': 'Línea', 'modo': 'Modo'}) - modos_e['Viajes'] = modos_e['Viajes'].astype(int) - col2.write('Etapas') - col2.markdown(zonasod_e.to_html(index=False), unsafe_allow_html=True) - col2.markdown(modos_e.to_html(index=False), unsafe_allow_html=True) + # Calculate the total and append as a new row + total_rowe = pd.DataFrame({ + 'Modo': ['Total'], + 'Línea': ['-'], + 'Etapas': [modos_e['Etapas'].sum()] + }) + modos_e = pd.concat([modos_e, total_rowe], ignore_index=True) + + modos_e['Etapas'] = modos_e['Etapas'].round() + col2.write('Etapas') + col2.markdown(zonasod_e.to_html(index=False), unsafe_allow_html=True) + col2.dataframe(modos_e.set_index('Modo'), height=500, width=400) + ## Viajes query = f"SELECT * FROM viajes_agregados WHERE mes = '{desc_mes}' AND tipo_dia = '{desc_tipo_dia}' AND (h3_o IN ({h3_values}) OR h3_d IN ({h3_values}));" - viajes = levanto_tabla_sql('viajes_agregados', tabla_tipo='dash', query=query) + viajes = levanto_tabla_sql_local('viajes_agregados', tabla_tipo='dash', query=query) viajes['Zona_1'] = '' viajes['Zona_2'] = '' @@ -170,18 +268,26 @@ def main(): viajes.loc[viajes.h3_d.isin(zona1), 'Zona_2'] = 'Zona 1' viajes.loc[viajes.h3_d.isin(zona2), 'Zona_2'] = 'Zona 2' viajes = viajes[(viajes.Zona_1 != '') & (viajes.Zona_2 != '') & (viajes.Zona_1 != viajes.Zona_2) & (viajes.Zona_1 != viajes.Zona_2)] - - zonasod_e = viajes.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().round().rename(columns={'factor_expansion_linea':'Viajes'}) - zonasod_e['Viajes'] = zonasod_e['Viajes'].astype(int) + zonasod_v = viajes.groupby(['Zona_1', 'Zona_2'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes'}) + - modos_v = viajes.groupby(['modo'], as_index=False).factor_expansion_linea.sum().round().rename(columns={'factor_expansion_linea':'Viajes', - 'modo': 'Modo'}) - modos_v['Viajes'] = modos_v['Viajes'].astype(int) + modos_v = viajes.groupby(['modo'], as_index=False).factor_expansion_linea.sum().rename(columns={'factor_expansion_linea':'Viajes', + 'modo': 'Modo'}) + + # Calculate the total and append as a new row + total_row = pd.DataFrame({ + 'Modo': ['Total'], + 'Viajes': [modos_v['Viajes'].sum()] + }) + modos_v = pd.concat([modos_v, total_row], ignore_index=True) + col3.write('Viajes') - col3.markdown(zonasod_e.to_html(index=False), unsafe_allow_html=True) - col3.markdown(modos_v.to_html(index=False), unsafe_allow_html=True) + col3.markdown(zonasod_v.to_html(index=False), unsafe_allow_html=True) + modos_v['Viajes'] = modos_v['Viajes'].round() + # col3.markdown(modos_v.to_html(index=False), unsafe_allow_html=True) + col3.dataframe(modos_v.set_index('Modo'), height=500, width=300) ## Mapa @@ -202,7 +308,7 @@ def zona_to_geometry(h3_list): folium.GeoJson(gdf, name="GeoData").add_to(m2) with col4: - st_folium(m2, width=700, height=700) + output2 = st_folium(m2, width=700, height=700) if __name__ == '__main__': main() diff --git a/urbantrips/lineas_deseo/__init__.py b/urbantrips/lineas_deseo/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/urbantrips/lineas_deseo/lineas_deseo.py b/urbantrips/lineas_deseo/lineas_deseo.py index de12b4e..9d059b5 100644 --- a/urbantrips/lineas_deseo/lineas_deseo.py +++ b/urbantrips/lineas_deseo/lineas_deseo.py @@ -8,7 +8,7 @@ from urbantrips.geo.geo import h3_to_lat_lon, h3toparent, h3_to_geodataframe, point_to_h3, create_h3_gdf from urbantrips.utils.check_configs import check_config from shapely.geometry import Point -from urbantrips.utils.utils import leer_alias +from urbantrips.utils.utils import leer_alias, leer_configs_generales from urbantrips.carto import carto @@ -1409,12 +1409,16 @@ def proceso_poligonos(check_configs=True): poligonos = levanto_tabla_sql('poligonos') if len(poligonos) > 0: + + configs = leer_configs_generales() + res = configs['resolucion_h3'] + print('identifica viajes en polígonos') # Read trips and jorneys etapas, viajes = load_and_process_data() # Select cases based fron polygon etapas_selec, viajes_selec, polygons, polygons_h3 = select_cases_from_polygons( - etapas[etapas.od_validado == 1], viajes[viajes.od_validado == 1], poligonos, res=8) + etapas[etapas.od_validado == 1], viajes[viajes.od_validado == 1], poligonos, res=res) etapas_agrupadas, etapas_sin_agrupar, viajes_matrices, zonificaciones = preparo_lineas_deseo( etapas_selec, viajes_selec, polygons_h3, poligonos=poligonos, res=[6])