import geopandas as gpd import pandas as pd import requests import zipfile import io import os # Descargar y descomprimir el archivo url = "https://geoportal.madrid.es/fsdescargas/IDEAM_WBGEOPORTAL/CALLEJERO/VIALES/VIALES_SHP.zip" print("Descargando datos...") response = requests.get(url) zip_file = zipfile.ZipFile(io.BytesIO(response.content)) zip_file.extractall("viales_madrid") print("Datos descargados y descomprimidos") # Cargamos el shapefile shp_file = None for file in os.listdir("viales_madrid"): if file.endswith(".shp"): shp_file = os.path.join("viales_madrid", file) break if shp_file is None: raise FileNotFoundError("No se encontró el archivo .shp en el zip") print(f"Cargando shapefile: {shp_file}") gdf = gpd.read_file(shp_file) # Información básica del fichero print(f"Número de viales cargados: {len(gdf)}") print(f"Columnas disponibles: {gdf.columns.tolist()}") # Inspeccionar las primeras filas para entender los datos print("\nPrimeras 5 filas del dataset:") print(gdf[['CV_TX_DENO', 'DEN_TX_NOM', 'DEN_TX_PAR']].head()) # Calcular la longitud de cada vial en metros print("\nCalculando longitudes...") gdf = gdf.to_crs(epsg=25830) # CRS proyectado para España (metros) gdf['longitud_metros'] = gdf.geometry.length # Calcular las estadísticas que nos interesan estadisticas = { 'Media': gdf['longitud_metros'].mean(), 'Mediana': gdf['longitud_metros'].median(), 'Mínimo': gdf['longitud_metros'].min(), 'Máximo': gdf['longitud_metros'].max(), 'Total': gdf['longitud_metros'].sum(), 'Cantidad de viales': len(gdf) } # Mostrar resultados de forma básica print("\n" + "="*50) print("ESTADÍSTICAS DE LONGITUD DE VIALES DE MADRID") print("="*50) for stat, value in estadisticas.items(): if stat in ['Total', 'Media', 'Mediana', 'Mínimo', 'Máximo']: print(f"{stat}: {value:,.2f} metros") else: print(f"{stat}: {value:,}") # Estadísticas más concretas print(f"\nLongitud promedio por vial: {estadisticas['Media']:,.2f} metros") print(f"Longitud total de calles: {estadisticas['Total']/1000:,.2f} kilómetros") # Mostrar algunos ejemplos para las explicaciones # Viales más largos, tienen que corresponder a autopistas print(f"\n--- Top 10 viales más largos ---") # Usar DEN_TX_NOM para el nombre y CV_TX_DENO para tipo de vía top_largas = gdf.nlargest(10, 'longitud_metros')[['CV_TX_DENO', 'DEN_TX_NOM', 'longitud_metros']] for idx, row in top_largas.iterrows(): nombre = f"{row['CV_TX_DENO']} {row['DEN_TX_NOM']}" if pd.notna(row['DEN_TX_NOM']) else "Sin nombre" print(f"{nombre}: {row['longitud_metros']:,.2f} metros") # Viales más cortos, corresponden a pasajes y plazas print(f"\n--- Top 10 viales más cortos ---") top_cortas = gdf.nsmallest(10, 'longitud_metros')[['CV_TX_DENO', 'DEN_TX_NOM', 'longitud_metros']] for idx, row in top_cortas.iterrows(): nombre = f"{row['CV_TX_DENO']} {row['DEN_TX_NOM']}" if pd.notna(row['DEN_TX_NOM']) else "Sin nombre" print(f"{nombre}: {row['longitud_metros']:,.2f} metros") # Análisis adicional por tipo de vía por si fuera necesario posteriormente print(f"\n--- Estadísticas por tipo de vía ---") if 'CV_TX_DENO' in gdf.columns: stats_por_tipo = gdf.groupby('CV_TX_DENO')['longitud_metros'].agg([ ('count', 'count'), ('longitud_total', 'sum'), ('longitud_promedio', 'mean'), ('longitud_maxima', 'max') ]).round(2) print(stats_por_tipo.sort_values('longitud_total', ascending=False))