v0.2.0 Readable time, distance, price, road ; legend added
Browse files- CHANGELOG.md +21 -2
- app.py +9 -10
- autoroute.py +37 -1
CHANGELOG.md
CHANGED
|
@@ -10,11 +10,14 @@ and this project adheres to [Semantic Versioning].
|
|
| 10 |
- /
|
| 11 |
|
| 12 |
|
| 13 |
-
## [0.
|
| 14 |
|
| 15 |
### Added
|
| 16 |
|
| 17 |
-
-
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
### Changed
|
| 20 |
|
|
@@ -24,7 +27,23 @@ and this project adheres to [Semantic Versioning].
|
|
| 24 |
|
| 25 |
### Fixed
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
|
| 29 |
### Security
|
| 30 |
|
|
|
|
| 10 |
- /
|
| 11 |
|
| 12 |
|
| 13 |
+
## [0.2.0] - 2025-02-28
|
| 14 |
|
| 15 |
### Added
|
| 16 |
|
| 17 |
+
- Better map display features in general; in particular:
|
| 18 |
+
- Every segment has a readable distance, time, price and road.
|
| 19 |
+
- Every path has a legend aggregating those elements (except road).
|
| 20 |
+
- Button can't be clicked while computing.
|
| 21 |
|
| 22 |
### Changed
|
| 23 |
|
|
|
|
| 27 |
|
| 28 |
### Fixed
|
| 29 |
|
| 30 |
+
### Security
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
## [0.1.0] - 2025-02-27
|
| 35 |
+
|
| 36 |
+
### Added
|
| 37 |
+
|
| 38 |
+
- First online demo
|
| 39 |
|
| 40 |
+
### Changed
|
| 41 |
+
|
| 42 |
+
### Deprecated
|
| 43 |
+
|
| 44 |
+
### Removed
|
| 45 |
+
|
| 46 |
+
### Fixed
|
| 47 |
|
| 48 |
### Security
|
| 49 |
|
app.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
|
|
| 1 |
import osmnx as ox
|
| 2 |
import panel as pn
|
| 3 |
import param
|
| 4 |
import colorcet as cc
|
| 5 |
import autoroute
|
| 6 |
|
| 7 |
-
map_kwds={"font_size": 15}
|
| 8 |
transformer = autoroute.to_Lambert93()
|
| 9 |
|
| 10 |
pn.extension()
|
|
@@ -19,6 +19,7 @@ calcul=pn.widgets.Button(button_type= "primary", name="Calculer parcours")
|
|
| 19 |
carte=pn.pane.plot.Folium(min_height=1000, sizing_mode='stretch_both')
|
| 20 |
|
| 21 |
def calculs(dummy):
|
|
|
|
| 22 |
orig_coo=ox.geocoder.geocode(par.orig_adr)
|
| 23 |
dest_coo=ox.geocoder.geocode(par.dest_adr)
|
| 24 |
calcul.name="Téléchargement carte"
|
|
@@ -32,20 +33,18 @@ def calculs(dummy):
|
|
| 32 |
df=autoroute.tariftimedf(Gc, orig_id, dest_id)
|
| 33 |
calcul.name="Affichage résultats"
|
| 34 |
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
carte.object=m
|
| 43 |
|
| 44 |
calcul.on_click(calculs)
|
| 45 |
|
| 46 |
|
| 47 |
app=pn.template.MaterialTemplate(
|
| 48 |
-
title="Autoroute v0.
|
| 49 |
sidebar=[pn.Param(par, name="Paramètres"), calcul],
|
| 50 |
main=carte,
|
| 51 |
)
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
import osmnx as ox
|
| 3 |
import panel as pn
|
| 4 |
import param
|
| 5 |
import colorcet as cc
|
| 6 |
import autoroute
|
| 7 |
|
|
|
|
| 8 |
transformer = autoroute.to_Lambert93()
|
| 9 |
|
| 10 |
pn.extension()
|
|
|
|
| 19 |
carte=pn.pane.plot.Folium(min_height=1000, sizing_mode='stretch_both')
|
| 20 |
|
| 21 |
def calculs(dummy):
|
| 22 |
+
calcul.disabled=True
|
| 23 |
orig_coo=ox.geocoder.geocode(par.orig_adr)
|
| 24 |
dest_coo=ox.geocoder.geocode(par.dest_adr)
|
| 25 |
calcul.name="Téléchargement carte"
|
|
|
|
| 33 |
df=autoroute.tariftimedf(Gc, orig_id, dest_id)
|
| 34 |
calcul.name="Affichage résultats"
|
| 35 |
|
| 36 |
+
gpfs=pd.concat([autoroute.clean_gfast(autoroute.ox.routing.route_to_gdf(Gc, row["path"], weight= "travel_time"))
|
| 37 |
+
for _, row in df.iterrows()])
|
| 38 |
+
|
| 39 |
+
carte.object=gpfs.explore(column="legend", tooltip= ["poids", "rue"], cmap=cc.b_glasbey_category10,
|
| 40 |
+
map_kwds={"font_size": 12}, style_kwds={"weight": 3}, highlight_kwds={"weight": 5})
|
| 41 |
+
calcul.disabled=False
|
|
|
|
|
|
|
| 42 |
|
| 43 |
calcul.on_click(calculs)
|
| 44 |
|
| 45 |
|
| 46 |
app=pn.template.MaterialTemplate(
|
| 47 |
+
title="Autoroute v0.2.0",
|
| 48 |
sidebar=[pn.Param(par, name="Paramètres"), calcul],
|
| 49 |
main=carte,
|
| 50 |
)
|
autoroute.py
CHANGED
|
@@ -171,5 +171,41 @@ def add_tarifs(G):
|
|
| 171 |
Gc.add_edges_from(ltup)
|
| 172 |
return Gc
|
| 173 |
|
| 174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
|
|
|
|
| 171 |
Gc.add_edges_from(ltup)
|
| 172 |
return Gc
|
| 173 |
|
| 174 |
+
def readable_place(row):
|
| 175 |
+
name= "\n".join(row["name"]) if isinstance(row["name"], list) else row["name"]
|
| 176 |
+
ref= row["ref"][0] if isinstance(row["ref"], list) else row["ref"]
|
| 177 |
+
if pd.isna(name):
|
| 178 |
+
return str(row["ref"])
|
| 179 |
+
return name if pd.isna(ref) else f'{row["ref"]} {name}'
|
| 180 |
+
|
| 181 |
+
def readable_dist(dm):
|
| 182 |
+
if dm<1000:
|
| 183 |
+
return f"{dm:.0f}m"
|
| 184 |
+
elif dm<10000:
|
| 185 |
+
return f"{dm/1000:.1f}km"
|
| 186 |
+
else:
|
| 187 |
+
return f"{dm/1000:.0f}km"
|
| 188 |
+
|
| 189 |
+
def readable_time(ts):
|
| 190 |
+
if ts<60:
|
| 191 |
+
return f"{ts:.0f}s"
|
| 192 |
+
elif ts<3600:
|
| 193 |
+
return f"{ts//60:.0f}min {ts%60:.0f}s"
|
| 194 |
+
else:
|
| 195 |
+
return f"{ts//3600:.0f}h {(ts//60)%60:.0f}min"
|
| 196 |
+
|
| 197 |
+
def readable_tarif(row):
|
| 198 |
+
if "tarif" not in row or row["tarif"]==0:
|
| 199 |
+
return ""
|
| 200 |
+
else:
|
| 201 |
+
return f', {row["tarif"]}€'
|
| 202 |
+
|
| 203 |
+
def readable_agg(row):
|
| 204 |
+
return f'{readable_time(row["travel_time"])}, {readable_dist(row["length"])}{readable_tarif(row)}'
|
| 205 |
+
|
| 206 |
+
def clean_gfast(gfast):
|
| 207 |
+
gfast["poids"]=gfast.apply(readable_agg, axis=1)
|
| 208 |
+
gfast["legend"] = readable_agg(gfast[list(set(gfast.columns) & {"travel_time", "tarif", "length"})].sum())
|
| 209 |
+
gfast["rue"] = gfast.apply(readable_place, axis=1)
|
| 210 |
+
return gfast
|
| 211 |
|