Skip to content

Commit bf3b590

Browse files
authored
Merge pull request #88 from datakind/customer_states
UX improvements around errors and manual adjustments
2 parents 222e673 + e2b4db7 commit bf3b590

File tree

13 files changed

+1035
-100
lines changed

13 files changed

+1035
-100
lines changed

dkroutingtool/Dockerfile.dev

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ RUN apt-get update
7070

7171
RUN apt-get -y install curl gnupg2
7272

73+
RUN pip install scikit-learn==1.0.2
74+
7375
RUN mkdir data
7476

7577
RUN mkdir data/gps_data_clean

dkroutingtool/compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ services:
44
command: /opt/conda/bin/python src/py/server.py
55
ports:
66
- "5001:5001"
7+
- "8080:8080"
78
frontend:
89
environment:
910
SERVER_HOST: backend

dkroutingtool/local_data/config.json

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
"trips_vehicle_profile": [["avoidsteep3wheeler", 50]],
99
"hours_allowed": 9,
1010
"start_time": "8:00AM",
11-
"consider_elevation": false,
1211
"enable_unload": true,
1312
"unload_vehicles": [
1413
["avoidsteep3wheeler", 50, "waste_basket", "waste_basket"],
@@ -24,13 +23,13 @@
2423
"trips_vehicle_profile": [["avoidsteep3wheeler", 50]],
2524
"enable_unload": false,
2625
"unload_vehicles": [],
27-
"hours_allowed": 5,
28-
"consider_elevation": false
26+
"hours_allowed": 5
2927
}
3028
],
31-
"node_loader_options": {"num_containers_default": 2, "elevation_factor": 300},
29+
"node_loader_options": {"num_containers_default": 2},
3230
"global_solver_options": {
3331
"max_solver_time_min": 1,
34-
"fast_run": true
32+
"fast_run": true,
33+
"clustering_radius": 5
3534
}
3635
}

dkroutingtool/local_start.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ docker run -it \
33
--mount src=`pwd`/scripts,target=/scripts,type=bind \
44
-p 8080:8080 \
55
-p 5001:5001 \
6-
dkroutingtool:dev bash
6+
ghcr.io/datakind/dk-routing:main bash
77

dkroutingtool/manual.ipynb

Lines changed: 174 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"cells": [
33
{
44
"cell_type": "code",
5-
"execution_count": null,
5+
"execution_count": 1,
66
"metadata": {},
77
"outputs": [],
88
"source": [
@@ -12,7 +12,24 @@
1212
},
1313
{
1414
"cell_type": "code",
15-
"execution_count": null,
15+
"execution_count": 2,
16+
"metadata": {},
17+
"outputs": [
18+
{
19+
"name": "stdout",
20+
"output_type": "stream",
21+
"text": [
22+
"/src/py\n"
23+
]
24+
}
25+
],
26+
"source": [
27+
"cd src/py"
28+
]
29+
},
30+
{
31+
"cell_type": "code",
32+
"execution_count": 3,
1633
"metadata": {},
1734
"outputs": [],
1835
"source": [
@@ -26,42 +43,172 @@
2643
"import visualization\n",
2744
"import schedule\n",
2845
"import upload_results\n",
29-
"import manual_viz\n",
30-
"\n",
31-
"\n",
32-
"\n",
33-
"with open('data/config.json', 'r') as opened:\n",
34-
" config = json.load(opened)"
46+
"import manual_viz"
3547
]
3648
},
3749
{
3850
"cell_type": "code",
39-
"execution_count": null,
51+
"execution_count": 4,
4052
"metadata": {},
4153
"outputs": [],
4254
"source": [
43-
"\n",
44-
" \n",
45-
"print(' * Building Time/Distance Matrices')\n",
46-
"#check if node_loader_options are specified\n",
55+
"from config.config_manager import ConfigManager, ConfigFileLocations, GPSInputPaths, ManualEditsInputPaths"
56+
]
57+
},
58+
{
59+
"cell_type": "code",
60+
"execution_count": 5,
61+
"metadata": {},
62+
"outputs": [],
63+
"source": [
64+
"cp ../../build_parameters.yml /src/py/"
65+
]
66+
},
67+
{
68+
"cell_type": "code",
69+
"execution_count": 6,
70+
"metadata": {},
71+
"outputs": [
72+
{
73+
"name": "stdout",
74+
"output_type": "stream",
75+
"text": [
76+
"\u001b[0m\u001b[01;32m__init__.py\u001b[0m* \u001b[01;32mgeojson_to_gpx_converter.py\u001b[0m* \u001b[01;32mreadme.md\u001b[0m*\r\n",
77+
"\u001b[01;34m__pycache__\u001b[0m/ \u001b[01;32mmain_application.py\u001b[0m* \u001b[01;32mrun_routing.py\u001b[0m*\r\n",
78+
"\u001b[01;32mbuild_parameters.yml\u001b[0m* \u001b[01;32mmanage_aws.py\u001b[0m* \u001b[01;32mschedule.py\u001b[0m*\r\n",
79+
"\u001b[01;32mbuild_time_dist_matrix.py\u001b[0m* \u001b[01;32mmanual_viz.py\u001b[0m* \u001b[01;32mscratchpad.py\u001b[0m*\r\n",
80+
"\u001b[01;32mcloud_context.py\u001b[0m* \u001b[01;32mnode_data_pickle.py\u001b[0m* \u001b[01;32mserver.py\u001b[0m*\r\n",
81+
"\u001b[34;42mconfig\u001b[0m/ \u001b[01;32moptimization.py\u001b[0m* \u001b[34;42mui\u001b[0m/\r\n",
82+
"\u001b[01;32melevation_utils.py\u001b[0m* \u001b[01;32mosrm_text_instructions.py\u001b[0m* \u001b[01;32mupload_results.py\u001b[0m*\r\n",
83+
"\u001b[01;32mfile_config.py\u001b[0m* \u001b[34;42moutput\u001b[0m/ \u001b[01;32mvisualization.py\u001b[0m*\r\n"
84+
]
85+
}
86+
],
87+
"source": [
88+
"ls"
89+
]
90+
},
91+
{
92+
"cell_type": "code",
93+
"execution_count": 7,
94+
"metadata": {},
95+
"outputs": [
96+
{
97+
"name": "stderr",
98+
"output_type": "stream",
99+
"text": [
100+
"INFO:root:Missing ('Closed', 'closed'), adding substition\n"
101+
]
102+
}
103+
],
104+
"source": [
105+
"config_manager = ConfigManager.load_from_local(\n",
106+
" '/data/', False, None)"
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": 8,
112+
"metadata": {},
113+
"outputs": [],
114+
"source": [
115+
"import logging"
116+
]
117+
},
118+
{
119+
"cell_type": "code",
120+
"execution_count": 9,
121+
"metadata": {},
122+
"outputs": [
123+
{
124+
"name": "stderr",
125+
"output_type": "stream",
126+
"text": [
127+
"INFO:root:Building Time/Distance Matrices\n",
128+
"INFO:root:Num buckets Assumed: 2\n"
129+
]
130+
}
131+
],
132+
"source": [
133+
"routing_config = config_manager.get_routing_config()\n",
134+
"logging.info('Building Time/Distance Matrices')\n",
135+
"# check if node_loader_options are specified\n",
136+
"config = routing_config.get_raw_json()\n",
47137
"if 'node_loader_options' in config.keys():\n",
48-
" node_data = build_time_dist_matrix.process_nodes(config['node_loader_options'], config['zone_configs'])\n",
49-
"else:\n",
50-
" node_data = build_time_dist_matrix.process_nodes()\n",
51-
"\n",
52-
"print(f' * Starting Model Run at {time.strftime(\"%H:%M:%S\")} (UTC)')\n",
53-
"\n",
54-
"routes_for_mapping_viz, vehicles_viz, zone_route_map = optimization.main(node_data, config)\n",
55-
"\n",
56-
"visualization.main(routes_for_mapping_viz, vehicles_viz, zone_route_map)\n",
57-
"\n"
138+
" node_data = build_time_dist_matrix.process_nodes(\n",
139+
" config_manager,\n",
140+
" config['node_loader_options'],\n",
141+
" config['zone_configs'])"
142+
]
143+
},
144+
{
145+
"cell_type": "code",
146+
"execution_count": 10,
147+
"metadata": {},
148+
"outputs": [
149+
{
150+
"name": "stdout",
151+
"output_type": "stream",
152+
"text": [
153+
"False\n"
154+
]
155+
},
156+
{
157+
"name": "stderr",
158+
"output_type": "stream",
159+
"text": [
160+
"INFO:root:Took 1.80567 seconds to resequence\n",
161+
"INFO:root:Total Distance of all routes: 15.922000000000002km\n",
162+
"INFO:root:Total Time of all routes: 1736.9000000000003min\n"
163+
]
164+
},
165+
{
166+
"name": "stdout",
167+
"output_type": "stream",
168+
"text": [
169+
"False\n"
170+
]
171+
},
172+
{
173+
"name": "stderr",
174+
"output_type": "stream",
175+
"text": [
176+
"INFO:root:Took 2.871233 seconds to resequence\n",
177+
"INFO:root:Total Distance of all routes: 21.7879km\n",
178+
"INFO:root:Total Time of all routes: 2502.3min\n",
179+
"INFO:root:Optmization Complete: Took 00min 06sec to optimize [['East'], ['West']]\n"
180+
]
181+
}
182+
],
183+
"source": [
184+
"solution = optimization.run_optimization(node_data, config)\n",
185+
"visualization_data = visualization.create_visualizations(solution) "
58186
]
59187
},
60188
{
61189
"cell_type": "code",
62190
"execution_count": null,
63191
"metadata": {},
64192
"outputs": [],
193+
"source": []
194+
},
195+
{
196+
"cell_type": "code",
197+
"execution_count": 14,
198+
"metadata": {},
199+
"outputs": [
200+
{
201+
"ename": "ModuleNotFoundError",
202+
"evalue": "No module named 'matplotlib'",
203+
"output_type": "error",
204+
"traceback": [
205+
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
206+
"\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)",
207+
"\u001b[0;32m/tmp/ipykernel_104/3425648575.py\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mdatetime\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mimport\u001b[0m \u001b[0mmatplotlib\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mmatplotlib\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpyplot\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mnumpy\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mpandas\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mpd\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
208+
"\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'matplotlib'"
209+
]
210+
}
211+
],
65212
"source": [
66213
"import datetime\n",
67214
"import matplotlib\n",
@@ -121,9 +268,9 @@
121268
],
122269
"metadata": {
123270
"kernelspec": {
124-
"display_name": "ortools",
271+
"display_name": "Python 3 (ipykernel)",
125272
"language": "python",
126-
"name": "ortools"
273+
"name": "python3"
127274
},
128275
"language_info": {
129276
"codemirror_mode": {
@@ -135,9 +282,9 @@
135282
"name": "python",
136283
"nbconvert_exporter": "python",
137284
"pygments_lexer": "ipython3",
138-
"version": "3.8.3"
285+
"version": "3.7.7"
139286
}
140287
},
141288
"nbformat": 4,
142289
"nbformat_minor": 2
143-
}
290+
}

dkroutingtool/manual.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
jupyter notebook --ip 0.0.0.0 --port 8080 --no-browser --allow-root
1+
pip install notebook==6 && pip install markupsafe==2.0.1 && pip install traitlets==5.1.1 && jupyter notebook --ip 0.0.0.0 --port 8080 --no-browser --allow-root

dkroutingtool/src/py/build_time_dist_matrix.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,13 @@ def process_nodes(config_manager,
692692
else:
693693
node_data = NodeLoader(config_manager).get_nodedata()
694694

695+
try:
696+
file_location = config_manager.config_file_locations.routing_config_file #TODO should integrate into config manager properly eventually
697+
base_path = file_location.split('config.json')[0]
698+
node_data.past_adjustments = pd.read_excel(base_path+'manual_routes_edits.xlsx')
699+
except:
700+
print('No past adjustment file provided, defaults to presolve without it')
701+
695702
return node_data
696703

697704
start_time = time.time()

0 commit comments

Comments
 (0)