-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
112 lines (100 loc) Β· 4.77 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import extract
import ORTools
import re
import streamlit as st
def main(lat_long, loc_identifier, start_idx, end_idx, priority_locs, p_d, time_lim):
"""Optimize and display the output GMaps Route URL"""
output_G_maps_URL1, output_G_maps_URL2, final_points = ORTools.optimize(
lat_long, loc_identifier, start_idx, end_idx, priority_locs, p_d, time_lim)
if len(final_points) <= 25:
st.write(f"[Optimized Route π]({output_G_maps_URL2})")
st.write(
f"If above URL doesn't work, try [this π]({output_G_maps_URL1}).")
st.write(
f"The first URL prioritizes preserving the original names of the locations, but may not be as accurate.π")
st.write(
f"The second URL is more accurate, but may alter the names of the locations.π")
st.write(f"In both cases, slight manual adjustments may be necessary.π οΈ")
else:
st.write(f"Optimized Route π")
st.write(
f"Apparently GMaps URL doesn't work for more than 25 nodes π. Check 'Show Co-Ordinates'.")
if agree:
st.json(final_points)
def check_seq(s, nmax):
"""Check if fixed sequence input is valid"""
if s == "":
return True
pattern = re.compile(r"^\d+(,\d+)*$")
match = pattern.match(s)
if match:
numbers = [int(n) for n in s.split(",")]
return all(1 <= n <= nmax for n in numbers) and len(numbers) > 1
else:
return False
def check_seq_pd(s, nmax):
"""Check if pickup & delivery input is valid"""
if s == "":
return True
pattern = re.compile(r"^\d+(,\d+)*$")
match = pattern.match(s)
if match:
numbers = [int(n) for n in s.split(",")]
return all(1 <= n <= nmax for n in numbers) and len(numbers) % 2 == 0
else:
return False
if __name__ == "__main__":
st.set_page_config(
page_title="MultiStopOPT",
page_icon="π£οΈ",
layout="centered",
initial_sidebar_state="auto"
)
st.subheader("Optimize Multi-Stop Routes on Google Maps πΊοΈ")
num_loc = st.number_input(
"Num_Locations across all URLs (Max 150)\n", min_value=2, max_value=150, step=1)
num_urls = st.number_input("Num_URLs\n", min_value=1, max_value=15, step=1)
urls = []
for i in range(num_urls):
url = st.text_input("G_Maps Route URL\n", key=i)
urls.append(url)
start_idx = st.number_input("Start_Location (Locations are numbered from 1 and follow the URL sequence. 0 implies not fixed.) \n",
min_value=0, max_value=num_loc, step=1, value=0)
end_idx = st.number_input(
"End_Location\n", min_value=0, max_value=num_loc, step=1, value=0)
priority_locs = st.text_input(
"Locations that will follow a fixed sequence in the final route (E.g. input 3,5,10 => locations 3, 5 and 10 will be in this order)\n")
p_d = st.text_input(
"Pickup & Delivery (E.g. input 3,5,5,12,15,17 => 3->5, 5->12 and 15->17) (Note: No concept of load for now.)\n")
time_lim = st.number_input(
"Time_Limit (sec)\n", min_value=1, max_value=60, step=1, value=1)
agree = st.checkbox("Show Co-Ordinates")
if st.button("Optimize π§"):
if "" not in urls and ((start_idx == 0 and end_idx == 0) or (start_idx != end_idx)):
lat_long, loc_identifier = extract.get_lat_long(urls, num_loc)
try:
assert ((-1, -1) not in lat_long)
assert (check_seq(priority_locs, num_loc))
assert (check_seq_pd(p_d, num_loc))
#assert (len(loc_identifer) == num_loc)
main(lat_long, loc_identifier, start_idx, end_idx,
priority_locs, p_d, time_lim)
except:
if ((-1, -1) in lat_long):
st.write("Check Num_Locations π.")
elif (check_seq(priority_locs, num_loc) == 0):
st.write("Check Fixed Sequence π.")
elif (check_seq_pd(p_d, num_loc) == 0):
st.write("Check Pickup & Delivery π.")
else:
st.write(
"Something Went Wrong π")
else:
if "" in urls:
st.write("Check URLs π.")
elif (start_idx == end_idx):
st.write("Start_Location can't be same as End_Location π.")
st.subheader("About π")
st.write("Powered by Google OR-Tools [Apache License 2.0](https://github.com/google/or-tools/blob/92eab40155d5566039c92662632f196174f8da47/LICENSE) and geopy [MIT License](https://github.com/geopy/geopy/blob/ef48a8cbb85f842c0820333e53e7ebde7db382a3/LICENSE)")
st.write(
"Copyright (c) 2022 [Regista6](https://github.com/Regista6) ([Source](https://github.com/Regista6/MultiStopOPT))")