From c59d58e4a48d9dc87411ac6b76f28356b3790baf Mon Sep 17 00:00:00 2001 From: Sebastian Anapolsky Date: Fri, 8 Nov 2024 17:40:18 -0300 Subject: [PATCH 1/5] dash fix centra mapa en zonas --- urbantrips/dashboard/dash_utils.py | 14 +++++++++++++- .../pages/5_An\303\241lisis de zonas.py" | 15 ++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/urbantrips/dashboard/dash_utils.py b/urbantrips/dashboard/dash_utils.py index 26efa84..ae21f65 100644 --- a/urbantrips/dashboard/dash_utils.py +++ b/urbantrips/dashboard/dash_utils.py @@ -518,4 +518,16 @@ 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: + print('error') + latlon = [-34.593, -58.451] + return latlon \ No newline at end of file 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..d8d0be6 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 -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}, @@ -135,7 +136,7 @@ def main(): 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'] = '' @@ -161,7 +162,7 @@ def main(): ## 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'] = '' @@ -202,7 +203,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() From d138967f824178f63f1cc379f78c770f056afc38 Mon Sep 17 00:00:00 2001 From: Sebastian Anapolsky Date: Mon, 11 Nov 2024 10:28:44 -0300 Subject: [PATCH 2/5] correcciones en el dash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - nueva funcionalidad en dash de zonas - optimización de uso de tablas - transferencias --- .gitignore | 1 + configs/configuraciones_generales.yaml | 164 ++++++++---- urbantrips/dashboard/dash_utils.py | 233 +++++++++++------- .../pages/3_L\303\255neas de Deseo.py" | 232 +++++++++-------- urbantrips/dashboard/pages/4_Poligonos.py | 73 +++--- .../pages/5_An\303\241lisis de zonas.py" | 143 +++++++++-- 6 files changed, 562 insertions(+), 284 deletions(-) diff --git a/.gitignore b/.gitignore index 459c006..8b38332 100644 --- a/.gitignore +++ b/.gitignore @@ -145,3 +145,4 @@ dmypy.json .github/desktop.ini *.ini +configs/configuraciones_generales.yaml diff --git a/configs/configuraciones_generales.yaml b/configs/configuraciones_generales.yaml index ab28df8..ccaf72b 100755 --- a/configs/configuraciones_generales.yaml +++ b/configs/configuraciones_generales.yaml @@ -1,86 +1,91 @@ # Archivo de configuración para urbantrips # Bases de datos -nombre_archivo_trx: "transacciones_amba_test.csv" # Especificar el archivo con las transacciones a consumir -alias_db_data: "amba_test" # nombre del sqlite donde se guardan los datos procesados -alias_db_insumos: "amba_test" # nombre del sqlite donde se guardan los insumos generales -alias_db_dashboard: "amba_test" # nombre del sqlite donde se guardan los datos a mostrar en el dashboard +nombre_archivo_trx: "UT_AMBA-2024-5-14-AP_m40.csv" # Especificar el archivo con las transacciones a consumir +alias_db_data: "amba_2024_m40" # nombre del sqlite donde se guardan los datos procesados +alias_db_insumos: "amba_2024_m40" # nombre del sqlite donde se guardan los insumos generales +alias_db_dashboard: "amba_2024_m40" # nombre del sqlite donde se guardan los datos a mostrar en el dashboard # Nombre de columnas en el archivo de transacciones nombres_variables_trx: id_trx: "id" # columna con id único del archivo de transacciones - fecha_trx: "fecha" # columna con fecha de la transacción - id_tarjeta_trx: "id_tarjeta" # columna con id de la tarjeta + fecha_trx: "fecha_trx" # columna con fecha de la transacción + id_tarjeta_trx: "id_tarjeta_trx" # columna con id de la tarjeta modo_trx: "modo" # columna con modo de transporte - hora_trx: "hora" # columna con hora de la transacción + hora_trx: # columna con hora de la transacción id_linea_trx: "id_linea" # columna con el id de la línea id_ramal_trx: "id_ramal" # columna con el ramal de la línea - interno_trx: "interno_bus" # columna con interno de la línea - orden_trx: "etapa_red_sube" # columna con el orden de la transacción (si falta hora/minuto en fecha_trx) - latitud_trx: "lat" # columna con la latitud de la transacción - longitud_trx: "lon" # columna con longitud de la transacción - factor_expansion: # columna con el factor de expansión + interno_trx: "interno" # columna con interno de la línea + orden_trx: # columna con el orden de la transacción (si falta hora/minuto en fecha_trx) + genero: "genero" # Indica el género asignado a la tarjeta + tarifa: "ats" # Indica el tipo de tarifa asignado a la transacción + latitud_trx: "latitude" # columna con la latitud de la transacción + longitud_trx: "longitude" # columna con longitud de la transacción + factor_expansion: "fex_linea" # columna con el factor de expansión # Parámetros de transacciones -ordenamiento_transacciones: "orden_trx" # especifica si ordena transacciones por fecha ("fecha_completa") o por variable orden_trx ("orden_trx") en la tabla nombres_variables_trx +ordenamiento_transacciones: "fecha_completa" # especifica si ordena transacciones por fecha ("fecha_completa") o por variable orden_trx ("orden_trx") en la tabla nombres_variables_trx ventana_viajes: 120 # ventana de tiempo para que una transacción sea de un mismo viaje (ej. 60 minutos) ventana_duplicado: 5 # ventana de tiempo si hay duplicado de transacción (ej. Viaje con acompañante) # Elimina transacciones inválidas de la tabla de transacciones tipo_trx_invalidas: tipo_trx_tren: [ # Lista con el contenido a eliminar de la variable seleccionada - "CHECK OUT SIN CHECKIN", - "CHECK OUT", + "COUT", + "COUTS", ] # Imputación de destino tolerancia_parada_destino: 2200 # Distancia para la validación de los destinos (metros) -imputar_destinos_min_distancia: False # Busca la parada que minimiza la distancia con respecto a la siguiente trancción +imputar_destinos_min_distancia: True # Busca la parada que minimiza la distancia con respecto a la siguiente trancción # Parámetros geográficos resolucion_h3: 8 # Resolución de los hexágonos -epsg_m: 9265 # Parámetros geográficos: crs +epsg_m: 5347 # Parámetros geográficos: crs -formato_fecha: "%d/%m/%Y" # Configuración fecha y hora -columna_hora: True +formato_fecha: "%d/%m/%Y %H:%M:%S" # Configuración fecha y hora +columna_hora: False geolocalizar_trx: False -nombre_archivo_gps: # Especificar el archivo con los datos gps de las líneas +nombre_archivo_gps: "UT_GPS-2024-5.csv" # Especificar el archivo con los datos gps de las líneas # Nombre de columnas en el archivo de GPS nombres_variables_gps: - id_gps: - id_linea_gps: - id_ramal_gps: - interno_gps: - fecha_gps: - latitud_gps: - longitud_gps: - velocity_gps: - servicios_gps: # Indica cuando se abre y cierra un servicio - distance_gps: + id_gps: "id" + id_linea_gps: "idlinea_gps" + id_ramal_gps: "idramal_gps" + interno_gps: "interno_gps" + fecha_gps: "fecha_gps" + latitud_gps: "lat_gps" + longitud_gps: "lon_gps" + velocity_gps: "vel_gps" + distance_gps: + servicios_gps: "serv_val" # Indica cuando se abre y cierra un servicio # Información para procesamiento de líneas -nombre_archivo_informacion_lineas: "lineas_amba_test.csv" # Archivo .csv con lineas, debe contener ("id_linea", "nombre_linea", "modo") +nombre_archivo_informacion_lineas: "UT_LINEAS-2024.csv" # Archivo .csv con lineas, debe contener ("id_linea", "nombre_linea", "modo") lineas_contienen_ramales: True # Especificar si las líneas de colectivo contienen ramales -nombre_archivo_paradas: "stops.csv" +nombre_archivo_paradas: "stops_amba_2023.csv" imprimir_lineas_principales: 5 # Imprimir las lineas principales - "All" imprime todas las líneas # Servicios GPS -utilizar_servicios_gps: False # Especifica si ve van a utilizar los servicios GPS -valor_inicio_servicio: # Valor de la variable que marca el inicio del servicio -valor_fin_servicio: # Valor de la variable que marca el fin del servicio +utilizar_servicios_gps: True # Especifica si ve van a utilizar los servicios GPS +valor_inicio_servicio: "INI" # Valor de la variable que marca el inicio del servicio +valor_fin_servicio: "FIN" # Valor de la variable que marca el fin del servicio modos: - autobus: "COL" - tren: "TRE" - metro: "SUB" + autobus: "COLE" + tren: "FFCC" + metro: "SUBTE" tranvia: brt: + cable: + lancha: + otros: # Capas geográficas con recorridos de líneas -recorridos_geojson: "recorridos_amba.geojson" # archivo geojson con el trazado de las líneas de transporte público +recorridos_geojson: "recorridos_amba_2023.geojson" # archivo geojson con el trazado de las líneas de transporte público filtro_latlong_bbox: minx: -59.3 @@ -90,12 +95,77 @@ filtro_latlong_bbox: # Zonificaciones zonificaciones: - geo1: - var1: + geo1: "zonas.geojson" + var1: "Zona" orden1: - geo2: - var2: - orden2: + geo2: "partidos.geojson" + var2: "Partido" + orden2: [ + "Comuna 1", + "Comuna 2", + "Comuna 3", + "Comuna 4", + "Comuna 5", + "Comuna 6", + "Comuna 7", + "Comuna 8", + "Comuna 9", + "Comuna 10", + "Comuna 11", + "Comuna 12", + "Comuna 13", + "Comuna 14", + "Comuna 15", + "Almirante Brown", + "Avellaneda", + "Berazategui", + "Berisso", + "Brandsen", + "Campana", + "Carmen de Areco", + "Cañuelas", + "Ensenada", + "Escobar", + "Esteban Echeverría", + "Exaltación de la Cruz", + "Ezeiza", + "Florencio Varela", + "General Las Heras", + "General Rodríguez", + "General San Martín", + "Hurlingham", + "Ituzaingó", + "José C. Paz", + "La Matanza", + "La Plata", + "Lanús", + "Lobos", + "Lomas de Zamora", + "Luján", + "Magdalena", + "Malvinas Argentinas", + "Marcos Paz", + "Mercedes", + "Merlo", + "Moreno", + "Morón", + "Navarro", + "Pilar", + "Presidente Perón", + "Punta Indio", + "Quilmes", + "San Andrés de Giles", + "San Antonio de Areco", + "San Fernando", + "San Isidro", + "San Miguel", + "San Vicente", + "Tigre", + "Tres de Febrero", + "Vicente López", + "Zárate", + ] + geo3: var3: orden3: @@ -106,5 +176,7 @@ zonificaciones: var5: orden5: -poligonos: # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. -tiempos_viaje_estaciones: +poligonos: "poligonos.geojson" # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. + +tiempos_viaje_estaciones: "travel_time_stations.csv" # Especificar una tabla de tiempo de viaje en minutos entre estaciones para modos sin gps + diff --git a/urbantrips/dashboard/dash_utils.py b/urbantrips/dashboard/dash_utils.py index ae21f65..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 @@ -528,6 +596,5 @@ def bring_latlon(): lon = latlon['lon1_norm'].mean() latlon = [lat, lon] except: - print('error') 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 d8d0be6..3f58e68 100644 --- "a/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" +++ "b/urbantrips/dashboard/pages/5_An\303\241lisis de zonas.py" @@ -13,7 +13,7 @@ iniciar_conexion_db, get_logo, bring_latlon ) from streamlit_folium import folium_static - +pd.options.display.float_format = '{:,.0f}'.format def levanto_tabla_sql_local(tabla_sql, tabla_tipo="dash", query=''): @@ -119,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'] @@ -131,6 +131,94 @@ 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) @@ -146,19 +234,28 @@ 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}));" @@ -171,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 From 007e851d1801a92e31e20fc55d271e60d6e0842d Mon Sep 17 00:00:00 2001 From: Sebastian Anapolsky Date: Mon, 11 Nov 2024 11:56:39 -0300 Subject: [PATCH 3/5] Update lineas_deseo.py - bring resolution from config --- urbantrips/lineas_deseo/lineas_deseo.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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]) From b2da1a442eaa0d2cb9710bb85f355527aa300389 Mon Sep 17 00:00:00 2001 From: Sebastian Anapolsky Date: Tue, 12 Nov 2024 11:24:05 -0300 Subject: [PATCH 4/5] Create __init__.py --- urbantrips/lineas_deseo/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 urbantrips/lineas_deseo/__init__.py diff --git a/urbantrips/lineas_deseo/__init__.py b/urbantrips/lineas_deseo/__init__.py new file mode 100644 index 0000000..e69de29 From c6f534e9991e782322e71cf4047008f5474e110a Mon Sep 17 00:00:00 2001 From: alephcero Date: Tue, 12 Nov 2024 12:28:32 -0300 Subject: [PATCH 5/5] Restore configs --- .gitignore | 1 - configs/configuraciones_generales.yaml | 164 +++++++------------------ 2 files changed, 46 insertions(+), 119 deletions(-) diff --git a/.gitignore b/.gitignore index 8b38332..459c006 100644 --- a/.gitignore +++ b/.gitignore @@ -145,4 +145,3 @@ dmypy.json .github/desktop.ini *.ini -configs/configuraciones_generales.yaml diff --git a/configs/configuraciones_generales.yaml b/configs/configuraciones_generales.yaml index ccaf72b..ab28df8 100755 --- a/configs/configuraciones_generales.yaml +++ b/configs/configuraciones_generales.yaml @@ -1,91 +1,86 @@ # Archivo de configuración para urbantrips # Bases de datos -nombre_archivo_trx: "UT_AMBA-2024-5-14-AP_m40.csv" # Especificar el archivo con las transacciones a consumir -alias_db_data: "amba_2024_m40" # nombre del sqlite donde se guardan los datos procesados -alias_db_insumos: "amba_2024_m40" # nombre del sqlite donde se guardan los insumos generales -alias_db_dashboard: "amba_2024_m40" # nombre del sqlite donde se guardan los datos a mostrar en el dashboard +nombre_archivo_trx: "transacciones_amba_test.csv" # Especificar el archivo con las transacciones a consumir +alias_db_data: "amba_test" # nombre del sqlite donde se guardan los datos procesados +alias_db_insumos: "amba_test" # nombre del sqlite donde se guardan los insumos generales +alias_db_dashboard: "amba_test" # nombre del sqlite donde se guardan los datos a mostrar en el dashboard # Nombre de columnas en el archivo de transacciones nombres_variables_trx: id_trx: "id" # columna con id único del archivo de transacciones - fecha_trx: "fecha_trx" # columna con fecha de la transacción - id_tarjeta_trx: "id_tarjeta_trx" # columna con id de la tarjeta + fecha_trx: "fecha" # columna con fecha de la transacción + id_tarjeta_trx: "id_tarjeta" # columna con id de la tarjeta modo_trx: "modo" # columna con modo de transporte - hora_trx: # columna con hora de la transacción + hora_trx: "hora" # columna con hora de la transacción id_linea_trx: "id_linea" # columna con el id de la línea id_ramal_trx: "id_ramal" # columna con el ramal de la línea - interno_trx: "interno" # columna con interno de la línea - orden_trx: # columna con el orden de la transacción (si falta hora/minuto en fecha_trx) - genero: "genero" # Indica el género asignado a la tarjeta - tarifa: "ats" # Indica el tipo de tarifa asignado a la transacción - latitud_trx: "latitude" # columna con la latitud de la transacción - longitud_trx: "longitude" # columna con longitud de la transacción - factor_expansion: "fex_linea" # columna con el factor de expansión + interno_trx: "interno_bus" # columna con interno de la línea + orden_trx: "etapa_red_sube" # columna con el orden de la transacción (si falta hora/minuto en fecha_trx) + latitud_trx: "lat" # columna con la latitud de la transacción + longitud_trx: "lon" # columna con longitud de la transacción + factor_expansion: # columna con el factor de expansión # Parámetros de transacciones -ordenamiento_transacciones: "fecha_completa" # especifica si ordena transacciones por fecha ("fecha_completa") o por variable orden_trx ("orden_trx") en la tabla nombres_variables_trx +ordenamiento_transacciones: "orden_trx" # especifica si ordena transacciones por fecha ("fecha_completa") o por variable orden_trx ("orden_trx") en la tabla nombres_variables_trx ventana_viajes: 120 # ventana de tiempo para que una transacción sea de un mismo viaje (ej. 60 minutos) ventana_duplicado: 5 # ventana de tiempo si hay duplicado de transacción (ej. Viaje con acompañante) # Elimina transacciones inválidas de la tabla de transacciones tipo_trx_invalidas: tipo_trx_tren: [ # Lista con el contenido a eliminar de la variable seleccionada - "COUT", - "COUTS", + "CHECK OUT SIN CHECKIN", + "CHECK OUT", ] # Imputación de destino tolerancia_parada_destino: 2200 # Distancia para la validación de los destinos (metros) -imputar_destinos_min_distancia: True # Busca la parada que minimiza la distancia con respecto a la siguiente trancción +imputar_destinos_min_distancia: False # Busca la parada que minimiza la distancia con respecto a la siguiente trancción # Parámetros geográficos resolucion_h3: 8 # Resolución de los hexágonos -epsg_m: 5347 # Parámetros geográficos: crs +epsg_m: 9265 # Parámetros geográficos: crs -formato_fecha: "%d/%m/%Y %H:%M:%S" # Configuración fecha y hora -columna_hora: False +formato_fecha: "%d/%m/%Y" # Configuración fecha y hora +columna_hora: True geolocalizar_trx: False -nombre_archivo_gps: "UT_GPS-2024-5.csv" # Especificar el archivo con los datos gps de las líneas +nombre_archivo_gps: # Especificar el archivo con los datos gps de las líneas # Nombre de columnas en el archivo de GPS nombres_variables_gps: - id_gps: "id" - id_linea_gps: "idlinea_gps" - id_ramal_gps: "idramal_gps" - interno_gps: "interno_gps" - fecha_gps: "fecha_gps" - latitud_gps: "lat_gps" - longitud_gps: "lon_gps" - velocity_gps: "vel_gps" - distance_gps: - servicios_gps: "serv_val" # Indica cuando se abre y cierra un servicio + id_gps: + id_linea_gps: + id_ramal_gps: + interno_gps: + fecha_gps: + latitud_gps: + longitud_gps: + velocity_gps: + servicios_gps: # Indica cuando se abre y cierra un servicio + distance_gps: # Información para procesamiento de líneas -nombre_archivo_informacion_lineas: "UT_LINEAS-2024.csv" # Archivo .csv con lineas, debe contener ("id_linea", "nombre_linea", "modo") +nombre_archivo_informacion_lineas: "lineas_amba_test.csv" # Archivo .csv con lineas, debe contener ("id_linea", "nombre_linea", "modo") lineas_contienen_ramales: True # Especificar si las líneas de colectivo contienen ramales -nombre_archivo_paradas: "stops_amba_2023.csv" +nombre_archivo_paradas: "stops.csv" imprimir_lineas_principales: 5 # Imprimir las lineas principales - "All" imprime todas las líneas # Servicios GPS -utilizar_servicios_gps: True # Especifica si ve van a utilizar los servicios GPS -valor_inicio_servicio: "INI" # Valor de la variable que marca el inicio del servicio -valor_fin_servicio: "FIN" # Valor de la variable que marca el fin del servicio +utilizar_servicios_gps: False # Especifica si ve van a utilizar los servicios GPS +valor_inicio_servicio: # Valor de la variable que marca el inicio del servicio +valor_fin_servicio: # Valor de la variable que marca el fin del servicio modos: - autobus: "COLE" - tren: "FFCC" - metro: "SUBTE" + autobus: "COL" + tren: "TRE" + metro: "SUB" tranvia: brt: - cable: - lancha: - otros: # Capas geográficas con recorridos de líneas -recorridos_geojson: "recorridos_amba_2023.geojson" # archivo geojson con el trazado de las líneas de transporte público +recorridos_geojson: "recorridos_amba.geojson" # archivo geojson con el trazado de las líneas de transporte público filtro_latlong_bbox: minx: -59.3 @@ -95,77 +90,12 @@ filtro_latlong_bbox: # Zonificaciones zonificaciones: - geo1: "zonas.geojson" - var1: "Zona" + geo1: + var1: orden1: - geo2: "partidos.geojson" - var2: "Partido" - orden2: [ - "Comuna 1", - "Comuna 2", - "Comuna 3", - "Comuna 4", - "Comuna 5", - "Comuna 6", - "Comuna 7", - "Comuna 8", - "Comuna 9", - "Comuna 10", - "Comuna 11", - "Comuna 12", - "Comuna 13", - "Comuna 14", - "Comuna 15", - "Almirante Brown", - "Avellaneda", - "Berazategui", - "Berisso", - "Brandsen", - "Campana", - "Carmen de Areco", - "Cañuelas", - "Ensenada", - "Escobar", - "Esteban Echeverría", - "Exaltación de la Cruz", - "Ezeiza", - "Florencio Varela", - "General Las Heras", - "General Rodríguez", - "General San Martín", - "Hurlingham", - "Ituzaingó", - "José C. Paz", - "La Matanza", - "La Plata", - "Lanús", - "Lobos", - "Lomas de Zamora", - "Luján", - "Magdalena", - "Malvinas Argentinas", - "Marcos Paz", - "Mercedes", - "Merlo", - "Moreno", - "Morón", - "Navarro", - "Pilar", - "Presidente Perón", - "Punta Indio", - "Quilmes", - "San Andrés de Giles", - "San Antonio de Areco", - "San Fernando", - "San Isidro", - "San Miguel", - "San Vicente", - "Tigre", - "Tres de Febrero", - "Vicente López", - "Zárate", - ] - + geo2: + var2: + orden2: geo3: var3: orden3: @@ -176,7 +106,5 @@ zonificaciones: var5: orden5: -poligonos: "poligonos.geojson" # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. - -tiempos_viaje_estaciones: "travel_time_stations.csv" # Especificar una tabla de tiempo de viaje en minutos entre estaciones para modos sin gps - +poligonos: # Especificar una capa geográfica de polígonos en formato .geojson. El archivo requiere las siguientes columnas: ['id', 'tipo', 'geometry']. 'id' es el id o nombre del polígono, tipo puede ser 'poligono' o 'cuenca'. +tiempos_viaje_estaciones: