workflow/analyse_speed_limits_essonne.py
2025-07-17 14:39:07 +02:00

82 lines
No EOL
3 KiB
Python

import osmnx as ox
import pandas as pd
import matplotlib.pyplot as plt
import networkx as nx
# 1. Télécharger les routes principales de l'Essonne
# On cible les types de routes principales
highway_types = ["motorway", "trunk", "primary", "secondary"]
# Essonne (département 91, France)
place = "Essonne, France"
print("Téléchargement du graphe routier...")
G = ox.graph_from_place(place, network_type='drive', custom_filter='["highway"~"motorway|trunk|primary|secondary"]')
# 2. Extraire les limitations de vitesse et calculer la longueur
edges = ox.graph_to_gdfs(G, nodes=False, edges=True)
# On normalise les limitations de vitesse
def parse_maxspeed(val):
# Si c'est une liste ou un array, on prend le premier élément
if isinstance(val, (list, tuple)):
if len(val) == 0:
return None
val = val[0]
if pd.isna(val):
return None
try:
# On ne garde que le nombre
return int(str(val).split()[0])
except Exception:
return None
edges['maxspeed_norm'] = edges['maxspeed'].apply(parse_maxspeed)
# Calcul de la longueur en km
edges['length_km'] = edges['length'] / 1000
# 3. Statistiques
speed_stats = edges.groupby('maxspeed_norm')['length_km'].sum().reset_index()
speed_stats = speed_stats.rename(columns={'maxspeed_norm': 'limitation_vitesse', 'length_km': 'longueur_km'})
# Combien de km sans limitation ?
no_speed = edges[edges['maxspeed_norm'].isna()]['length_km'].sum()
# Remplacer les NaN par -1 pour les routes sans limitation spécifiée
speed_stats['limitation_vitesse'] = speed_stats['limitation_vitesse'].fillna(-1).astype(int)
# 4. Export CSV
speed_stats.to_csv('limitations_vitesse_essonne.csv', index=False)
# 5. Graphique SVG
fig, ax = plt.subplots(figsize=(12, 12))
# Routes avec limitation: gris, sans limitation: rouge
edges_with_speed = edges[edges['maxspeed_norm'].notna()]
edges_no_speed = edges[edges['maxspeed_norm'].isna()]
edges_with_speed.plot(ax=ax, linewidth=0.7, color='grey', alpha=0.5)
edges_no_speed.plot(ax=ax, linewidth=1.2, color='red', alpha=0.8)
ax.set_title("Routes principales de l'Essonne sans limitation de vitesse (en rouge)")
ax.axis('off')
plt.tight_layout()
plt.savefig('routes_sans_limitation_essonne.svg', format='svg')
# 5b. Histogramme des limitations de vitesse
plt.figure(figsize=(10,6))
plt.bar(speed_stats['limitation_vitesse'].astype(str), speed_stats['longueur_km'], color='skyblue', edgecolor='black')
plt.xlabel('Limitation de vitesse (km/h)')
plt.ylabel('Longueur totale (km)')
plt.title("Histogramme des limitations de vitesse sur les routes principales de l'Essonne")
plt.tight_layout()
plt.savefig('histogramme_limitations_vitesse_essonne.png')
print("Histogramme sauvegardé sous histogramme_limitations_vitesse_essonne.png")
# 6. Résumé console
print("\nRésumé:")
print(speed_stats)
print(f"\nLongueur totale sans limitation de vitesse: {no_speed:.2f} km")
print("CSV sauvegardé sous limitations_vitesse_essonne.csv")
print("SVG sauvegardé sous routes_sans_limitation_essonne.svg")