Lbasara commited on
Commit
6c7d496
·
1 Parent(s): 53357c4

Correction bugs dépendance et refacto

Browse files
Files changed (4) hide show
  1. CHANGELOG.md +17 -1
  2. app.py +7 -37
  3. requirements.txt +1 -2
  4. tableur.py +36 -1
CHANGELOG.md CHANGED
@@ -6,6 +6,23 @@ The format is based on [Keep a Changelog],
6
  and this project adheres to [Semantic Versioning].
7
 
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  ## [0.2.2] - 2025-10-16
10
 
11
  ### Added
@@ -23,7 +40,6 @@ and this project adheres to [Semantic Versioning].
23
  ### Security
24
 
25
 
26
-
27
  ## [0.2.1] - 2025-10-10
28
 
29
  ### Added
 
6
  and this project adheres to [Semantic Versioning].
7
 
8
 
9
+ ## [0.2.3] - 2025-10-29
10
+
11
+ ### Added
12
+
13
+ ### Changed
14
+ * Refacto : fetch_matrices dans un fichier externe
15
+
16
+ ### Deprecated
17
+
18
+ ### Removed
19
+
20
+ ### Fixed
21
+ * Tableur n'avait pas toutes les dépendances incluses
22
+
23
+ ### Security
24
+
25
+
26
  ## [0.2.2] - 2025-10-16
27
 
28
  ### Added
 
40
  ### Security
41
 
42
 
 
43
  ## [0.2.1] - 2025-10-10
44
 
45
  ### Added
app.py CHANGED
@@ -1,28 +1,25 @@
1
- import os
2
-
3
  import requests
4
  import folium
5
  import colorcet as cc
6
  import shapely
7
- import numpy as np
8
  import plotly.express as px
9
  import panel as pn
10
  import pandas as pd
11
  import geopandas as gpd
12
- import openrouteservice as ors
13
 
14
  from time import sleep
15
- from dotenv import load_dotenv
16
  from bokeh.models.widgets.tables import DateFormatter
17
  from vrp import calcul_routes
18
 
19
  from tableur import Tableur
 
 
20
 
21
 
22
- load_dotenv()
23
  pn.extension("tabulator", 'filedropper', 'plotly')
24
- ors_apikey=os.environ.get("ors_apikey")
25
- client = ors.Client(key=ors_apikey)
26
  wgs84="EPSG:4326"
27
  l93="EPSG:9794"
28
  pal=cc.glasbey_dark
@@ -61,35 +58,9 @@ def add_coo(adresse, details=False):
61
  suggestion=feature['properties']['label']
62
  return (coo, suggestion, score) if details else coo
63
 
64
- def gdf2lonlat(gdf):
65
- return list(zip(*(gdf.geometry.x, gdf.geometry.y)))
66
-
67
-
68
-
69
-
70
 
71
 
72
- def fetch_matrices(dfadr):
73
- max_elements=3500
74
- nb_loc=len(dfadr)
75
- nb_loc_per_step=max_elements//nb_loc
76
- nb_steps=int(np.ceil(nb_loc/nb_loc_per_step))
77
-
78
- lrep=[]
79
- for i in np.arange(nb_steps):
80
- idx_dest=np.arange(i*nb_loc_per_step, min([(i+1)*nb_loc_per_step, nb_loc])).tolist()
81
- lrep.append(ors.distance_matrix.distance_matrix(client=client,
82
- locations=gdf2lonlat(dfadr),
83
- destinations=idx_dest,
84
- metrics=["distance", "duration"],
85
- units="km",
86
- resolve_locations=True))
87
-
88
- mat_dist=np.concat([il["distances"] for il in lrep], axis=1)
89
- mat_dur=np.concat([il["durations"] for il in lrep], axis=1)
90
-
91
- return mat_dist, mat_dur
92
-
93
 
94
  def mat_figs(dfadr, mat_dist, mat_dur):
95
  labels=[ f'{row["oid"]}:{row["lieu"]}' for _, row in dfadr.iterrows()]
@@ -194,7 +165,6 @@ def tous_calculs(_):
194
  tabs.append(('Matrice de durées', pn.pane.Plotly(fig_dur, width=1100, height=1000 )))
195
 
196
  sol=calcul_routes(dfp, ladr, mat_dist, mat_dur, duree_taxi.value, duree_ecole.value, capacité.value)
197
- #print(sol.to_dict()["summary"])
198
 
199
  gpu=dfp.loc[list({u["id"] for u in sol.to_dict()["unassigned"]})][['suggestion', 'indice école', 'ECOLE', 'arrivée_max']].copy()
200
  gpu["Distance (km)"]=gpu.apply(lambda row: mat_dist[ladr.index(row["suggestion"])][ladr.index( row["ECOLE"])], axis=1)
@@ -223,5 +193,5 @@ tabs=pn.Tabs(
223
 
224
  template= pn.template.MaterialTemplate(title="Problème de tournée des véhicules avec capacités et fenêtre temporelle")
225
  template.main.append(tabs)
226
- template.header.append("v0.2.2")
227
  template.servable()
 
 
 
1
  import requests
2
  import folium
3
  import colorcet as cc
4
  import shapely
 
5
  import plotly.express as px
6
  import panel as pn
7
  import pandas as pd
8
  import geopandas as gpd
9
+
10
 
11
  from time import sleep
12
+
13
  from bokeh.models.widgets.tables import DateFormatter
14
  from vrp import calcul_routes
15
 
16
  from tableur import Tableur
17
+ from routingmat import fetch_matrices
18
+
19
 
20
 
 
21
  pn.extension("tabulator", 'filedropper', 'plotly')
22
+
 
23
  wgs84="EPSG:4326"
24
  l93="EPSG:9794"
25
  pal=cc.glasbey_dark
 
58
  suggestion=feature['properties']['label']
59
  return (coo, suggestion, score) if details else coo
60
 
 
 
 
 
 
 
61
 
62
 
63
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
 
65
  def mat_figs(dfadr, mat_dist, mat_dur):
66
  labels=[ f'{row["oid"]}:{row["lieu"]}' for _, row in dfadr.iterrows()]
 
165
  tabs.append(('Matrice de durées', pn.pane.Plotly(fig_dur, width=1100, height=1000 )))
166
 
167
  sol=calcul_routes(dfp, ladr, mat_dist, mat_dur, duree_taxi.value, duree_ecole.value, capacité.value)
 
168
 
169
  gpu=dfp.loc[list({u["id"] for u in sol.to_dict()["unassigned"]})][['suggestion', 'indice école', 'ECOLE', 'arrivée_max']].copy()
170
  gpu["Distance (km)"]=gpu.apply(lambda row: mat_dist[ladr.index(row["suggestion"])][ladr.index( row["ECOLE"])], axis=1)
 
193
 
194
  template= pn.template.MaterialTemplate(title="Problème de tournée des véhicules avec capacités et fenêtre temporelle")
195
  template.main.append(tabs)
196
+ template.header.append("v0.2.3")
197
  template.servable()
requirements.txt CHANGED
@@ -1,4 +1,3 @@
1
- python-dotenv==1.1.1
2
  anyio==4.11.0
3
  argon2-cffi==25.1.0
4
  argon2-cffi-bindings==25.1.0
@@ -107,12 +106,12 @@ pyogrio==0.11.1
107
  pyparsing==3.2.5
108
  pyproj==3.7.2
109
  pyproject-hooks==1.2.0
 
110
  pyshp==2.3.1
111
  python-dateutil==2.9.0.post0
112
  python-json-logger==3.3.0
113
  pytz==2025.2
114
  pyviz-comms==3.0.6
115
- #pyvroom @ file:///home/laurent/Code/taxis/pyvroom
116
  pyvroom==1.14
117
  pyyaml==6.0.3
118
  pyzmq==27.1.0
 
 
1
  anyio==4.11.0
2
  argon2-cffi==25.1.0
3
  argon2-cffi-bindings==25.1.0
 
106
  pyparsing==3.2.5
107
  pyproj==3.7.2
108
  pyproject-hooks==1.2.0
109
+ pyrouting==1.3.0
110
  pyshp==2.3.1
111
  python-dateutil==2.9.0.post0
112
  python-json-logger==3.3.0
113
  pytz==2025.2
114
  pyviz-comms==3.0.6
 
115
  pyvroom==1.14
116
  pyyaml==6.0.3
117
  pyzmq==27.1.0
tableur.py CHANGED
@@ -1,4 +1,3 @@
1
-
2
  import numpy as np
3
 
4
  import dateparser
@@ -9,10 +8,46 @@ from bokeh.models.widgets.tables import DateFormatter
9
  from io import BytesIO, StringIO
10
  from datetime import timedelta
11
 
 
 
 
 
 
 
 
 
12
 
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def frenchdrop(dropper: pn.widgets.FileDropper):
17
  """Example of a FileDropper with French labels via JS injection."""
18
  js_locale = r"""
 
 
1
  import numpy as np
2
 
3
  import dateparser
 
8
  from io import BytesIO, StringIO
9
  from datetime import timedelta
10
 
11
+ import requests
12
+ import shapely
13
+
14
+ from time import sleep
15
+
16
+
17
+ def cree_adresse(df, cols):
18
+ return df[cols].astype(str).agg(' '.join, axis=1).str.strip()
19
 
20
 
21
+ def geocode(adresse, as_point=False, as_dict=False):
22
+ r=requests.get(url="https://data.geopf.fr/geocodage/search",
23
+ params={"q": adresse})
24
+ if not r.ok:
25
+ return None
26
+ try:
27
+ js=r.json()
28
+ feature=js['features'][0]
29
+ if as_point:
30
+ return shapely.Point(feature['geometry']['coordinates'])
31
+ if as_dict:
32
+ return {js["query"] : feature}
33
+ return feature
34
+ except:
35
+ return None
36
 
37
 
38
+ def add_coo(adresse, details=False):
39
+ feature=geocode(adresse)
40
+ if feature is None:
41
+ sleep(0.1)
42
+ feature=geocode(adresse)
43
+ if feature is None:
44
+ return None, None, 0
45
+ coo=shapely.Point(feature['geometry']['coordinates'])
46
+ score=feature['properties']['score']
47
+ suggestion=feature['properties']['label']
48
+ return (coo, suggestion, score) if details else coo
49
+
50
+
51
  def frenchdrop(dropper: pn.widgets.FileDropper):
52
  """Example of a FileDropper with French labels via JS injection."""
53
  js_locale = r"""