summaryrefslogtreecommitdiff
path: root/dashboard_website/router.py
diff options
context:
space:
mode:
authoritsGarrin <garrin.shieh@gmail.com>2024-07-02 14:54:18 -0700
committeritsGarrin <garrin.shieh@gmail.com>2024-07-02 14:54:18 -0700
commitcc2a87f3e9949db97ffad300fdd87afcafed78c8 (patch)
treea175f72731f653f22eb9f83e7e2e2de876da5c25 /dashboard_website/router.py
parent84cd1770bca064998521cb5f44ddb309d9b5247b (diff)
reformatted code
Diffstat (limited to 'dashboard_website/router.py')
-rw-r--r--dashboard_website/router.py136
1 files changed, 94 insertions, 42 deletions
diff --git a/dashboard_website/router.py b/dashboard_website/router.py
index 8f73c99..e0e0720 100644
--- a/dashboard_website/router.py
+++ b/dashboard_website/router.py
@@ -8,33 +8,37 @@ from datastructs import *
host = "http://acetyl.net:5000" # queries acetyl.net:5000, the OSRM engine
-endtime = datetime.datetime(2023, 11, 18, hour=18, minute=45) # 11/18/2023 6:35pm
+endtime = datetime.datetime(2023, 11, 18, hour=18, minute=45) # 11/18/2023 6:35pm
# external facing functions
+
# gets single leg route between bike and clue
# should be HD and GeoJSON
def getRouteFullJSON(bike, clue):
- bike = bike.toJSON(); clue = clue.toJSON()
+ bike = bike.toJSON()
+ clue = clue.toJSON()
url = f"{host}/route/v1/bike/{bike['longitude']},{bike['latitude']};{clue['longitude']},{clue['latitude']}?steps=true&overview=full&geometries=geojson"
r = requests.get(url)
return r.json()
def getRouteHDPolyline(bike, clue):
- bike = bike.toJSON(); clue = clue.toJSON()
+ bike = bike.toJSON()
+ clue = clue.toJSON()
url = f"{host}/route/v1/bike/{bike['longitude']},{bike['latitude']};{clue['longitude']},{clue['latitude']}?overview=full&geometries=geojson"
r = requests.get(url)
- p = r.json()['routes'][0]['geometry']['coordinates']
+ p = r.json()["routes"][0]["geometry"]["coordinates"]
return p
def getRouteFastPolyline(bike, clue):
- bike = bike.toJSON(); clue = clue.toJSON()
+ bike = bike.toJSON()
+ clue = clue.toJSON()
url = f"{host}/route/v1/bike/{bike['longitude']},{bike['latitude']};{clue['longitude']},{clue['latitude']}?geometries=geojson"
r = requests.get(url)
- p = r.json()['routes'][0]['geometry']['coordinates']
+ p = r.json()["routes"][0]["geometry"]["coordinates"]
return p
@@ -44,8 +48,8 @@ def getZSP(bike, home, clue_cluster):
# determines clusters based on current bikes and clues
def getClusters(bikes, clues, endpoint):
- clusters = [[] for bike in bikes ]
- route_geos = [[] for bike in bikes ]
+ clusters = [[] for bike in bikes]
+ route_geos = [[] for bike in bikes]
times = {}
active_indices = [i for i in range(len(bikes)) if bikes[i].status == "ACTIVE"]
active_bikes = [bike for bike in bikes if bike.status == "ACTIVE"]
@@ -54,10 +58,12 @@ def getClusters(bikes, clues, endpoint):
active_clues = [clue for clue in clues if clue.status == "UNVISITED"]
# select only active bikes
# select only unvisited clues
- clusters_t, route_geos_t, times_t = cluster_and_optimize(active_clues, active_bikes, endpoint)
+ clusters_t, route_geos_t, times_t = cluster_and_optimize(
+ active_clues, active_bikes, endpoint
+ )
for i in range(len(active_indices)):
route_geos[active_indices[i]] = route_geos_t[i]
- clusters[active_indices[i]] = clusters_t[i]
+ clusters[active_indices[i]] = clusters_t[i]
bikes[active_indices[i]].setCluster(clusters_t[i])
times[bikes[active_indices[i]].name] = times_t[i]
@@ -66,7 +72,9 @@ def getClusters(bikes, clues, endpoint):
# utility functions (internal)
-def cluster_and_optimize(clues: [Clue], bikes: [Bike], end: Point, time_diff=0.25, max_time=24, n=2):
+def cluster_and_optimize(
+ clues: [Clue], bikes: [Bike], end: Point, time_diff=0.25, max_time=24, n=2
+):
"""
Takes a dataframe of gps coordinates, a list of centroids, and an end point and returns a dataframe with a cluster
:param clues: a list of clues
@@ -79,8 +87,10 @@ def cluster_and_optimize(clues: [Clue], bikes: [Bike], end: Point, time_diff=0.2
"""
# OVERRIDE MAX TIME
max_time = datetime.datetime.now() - endtime
- max_time = max_time.seconds/3600
- routes = [clues] # one bike = one set of routes. only need to remove the faraway waypoints
+ max_time = max_time.seconds / 3600
+ routes = [
+ clues
+ ] # one bike = one set of routes. only need to remove the faraway waypoints
if len(bikes) > 1:
# Create a new column with normalized gps coordinates and centroids
normalized_points, norm_centroids = __normalize_points(clues, bikes)
@@ -94,29 +104,32 @@ def cluster_and_optimize(clues: [Clue], bikes: [Bike], end: Point, time_diff=0.2
routes[label].append(clues[i])
routes = __minimize_route_time_diff(routes, bikes, end, time_diff, n)
-
+
# Remove waypoints from the longest route until the trip time is less than the max time
for i in range(len(routes)):
routes[i] = __remove_longest_waypoints(routes[i], bikes[i], end, max_time)
-
# Get the json of the routes
route_waypoints = []
geometries = []
times = []
for i, route in enumerate(routes):
- route_json = __get_json(__clues_to_string(route), __clues_to_string([bikes[i]]), __clues_to_string([end])[:-1])
- geometries.append(route_json['trips'][0]['geometry']['coordinates'])
- route_waypoints.append(route_json['waypoints'])
- eta = time.time() + route_json['trips'][0]['duration'] + 90 * len(route)
+ route_json = __get_json(
+ __clues_to_string(route),
+ __clues_to_string([bikes[i]]),
+ __clues_to_string([end])[:-1],
+ )
+ geometries.append(route_json["trips"][0]["geometry"]["coordinates"])
+ route_waypoints.append(route_json["waypoints"])
+ eta = time.time() + route_json["trips"][0]["duration"] + 90 * len(route)
eta_str = datetime.datetime.fromtimestamp(eta).strftime("%I:%M:%S%p")
times.append(eta_str)
# Use the waypoint_index to reorder each route
for i, route in enumerate(routes):
route2 = ["" for x in route]
- for j,k in enumerate(route_waypoints[i][1:-1]):
- route2[ k['waypoint_index']-1 ] = route[j]
+ for j, k in enumerate(route_waypoints[i][1:-1]):
+ route2[k["waypoint_index"] - 1] = route[j]
routes[i] = route2
return routes, geometries, times
@@ -128,9 +141,9 @@ def __clues_to_string(points: [Clue]):
:param points: a list of points
:return: a string of the list of points
"""
- string = ''
+ string = ""
for i in points:
- string += str(i.longitude) + ',' + str(i.latitude) + ';'
+ string += str(i.longitude) + "," + str(i.latitude) + ";"
return string
@@ -144,13 +157,20 @@ def __get_json(coordinate_string, start, end):
:return: the json of the route
"""
coordinates = requests.get(
- 'http://acetyl.net:5000/trip/v1/bike/' + start + coordinate_string + end + '?roundtrip=false&source=first&destination=last&geometries=geojson&overview=full')
+ "http://acetyl.net:5000/trip/v1/bike/"
+ + start
+ + coordinate_string
+ + end
+ + "?roundtrip=false&source=first&destination=last&geometries=geojson&overview=full"
+ )
coordinates = coordinates.json()
return coordinates
-def __get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoint=90, seconds=False):
+def __get_trip_time(
+ coordinate_string, num_waypoints, start, end, time_per_waypoint=90, seconds=False
+):
"""
Takes a string of coordinates and returns the trip time in hours
:param coordinate_string: a string of coordinates
@@ -161,19 +181,26 @@ def __get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypo
:return: the trip time in hours
"""
coordinates = requests.get(
- 'http://acetyl.net:5000/trip/v1/bike/' + start + coordinate_string + end + '?roundtrip=false&source=first&destination=last')
+ "http://acetyl.net:5000/trip/v1/bike/"
+ + start
+ + coordinate_string
+ + end
+ + "?roundtrip=false&source=first&destination=last"
+ )
coordinates = coordinates.json()
- travel_time_seconds = int(coordinates['trips'][0]['duration'])
+ travel_time_seconds = int(coordinates["trips"][0]["duration"])
waypoint_time_seconds = num_waypoints * time_per_waypoint
if seconds:
- return (travel_time_seconds + waypoint_time_seconds)
+ return travel_time_seconds + waypoint_time_seconds
total_time_hours = (travel_time_seconds + waypoint_time_seconds) / 3600
return total_time_hours
-def __minimize_route_time_diff(routes: [Clue], starts: [Point], end: Point, time_diff, n):
+def __minimize_route_time_diff(
+ routes: [Clue], starts: [Point], end: Point, time_diff, n
+):
"""
Takes a list of lists of coordinates, a list of start points, an end point, a time difference, and a number of routes
:param routes: the list of lists of coordinates
@@ -186,8 +213,14 @@ def __minimize_route_time_diff(routes: [Clue], starts: [Point], end: Point, time
times = []
for i, route in enumerate(routes):
- times.append(__get_trip_time(__clues_to_string(route), len(route), __clues_to_string([starts[i]]),
- __clues_to_string([end])[:-1]))
+ times.append(
+ __get_trip_time(
+ __clues_to_string(route),
+ len(route),
+ __clues_to_string([starts[i]]),
+ __clues_to_string([end])[:-1],
+ )
+ )
# Find the average trip time
average_time = np.mean(times)
@@ -201,8 +234,9 @@ def __minimize_route_time_diff(routes: [Clue], starts: [Point], end: Point, time
# If the difference is greater than the time difference, move a coordinate from the longest route to the shortest route
if time_difference > time_diff:
# Move a coordinate from the longest route to the shortest route
- closest_coordinate = __find_closest_coordinate(routes[sorted_indices[-1]],
- __mean_center(routes[sorted_indices[0]]))
+ closest_coordinate = __find_closest_coordinate(
+ routes[sorted_indices[-1]], __mean_center(routes[sorted_indices[0]])
+ )
routes[sorted_indices[0]].append(closest_coordinate)
routes[sorted_indices[-1]].remove(closest_coordinate)
@@ -213,7 +247,9 @@ def __minimize_route_time_diff(routes: [Clue], starts: [Point], end: Point, time
return routes
-def __remove_longest_waypoints(route_coordinates: [Clue], start: Bike, end: Point, max_time):
+def __remove_longest_waypoints(
+ route_coordinates: [Clue], start: Bike, end: Point, max_time
+):
"""
Takes a list of coordinates, a start point, an end point, and a maximum time and returns a list of coordinates
:param route_coordinates: the list of coordinates
@@ -223,8 +259,12 @@ def __remove_longest_waypoints(route_coordinates: [Clue], start: Bike, end: Poin
:return: a list of coordinates
"""
# Find the trip time for the route
- route_time = __get_trip_time(__clues_to_string(route_coordinates), len(route_coordinates),
- __clues_to_string([start]), __clues_to_string([end])[:-1])
+ route_time = __get_trip_time(
+ __clues_to_string(route_coordinates),
+ len(route_coordinates),
+ __clues_to_string([start]),
+ __clues_to_string([end])[:-1],
+ )
# If the trip time is greater than the max time, remove the waypoint with the longest distance from the mean
if route_time > max_time:
@@ -262,10 +302,18 @@ def __normalize_points(clues: [Clue], bikes: [Bike]):
for i in clues:
normalized_coordinates.append(
- [__min_max_normalize(i.latitude, min_lat, max_lat), __min_max_normalize(i.longitude, min_lon, max_lon)])
+ [
+ __min_max_normalize(i.latitude, min_lat, max_lat),
+ __min_max_normalize(i.longitude, min_lon, max_lon),
+ ]
+ )
for i in bikes:
normalized_centroids.append(
- [__min_max_normalize(i.latitude, min_lat, max_lat), __min_max_normalize(i.longitude, min_lon, max_lon)])
+ [
+ __min_max_normalize(i.latitude, min_lat, max_lat),
+ __min_max_normalize(i.longitude, min_lon, max_lon),
+ ]
+ )
return normalized_coordinates, normalized_centroids
@@ -324,8 +372,10 @@ def __mean_center(clues: [Clue]):
:param clues: the list of coordinates
:return: the mean center of the coordinates
"""
- return Point(np.mean([coordinate.latitude for coordinate in clues]),
- np.mean([coordinate.longitude for coordinate in clues]))
+ return Point(
+ np.mean([coordinate.latitude for coordinate in clues]),
+ np.mean([coordinate.longitude for coordinate in clues]),
+ )
def __distance(coordinate1: Clue, coordinate2: Point):
@@ -335,5 +385,7 @@ def __distance(coordinate1: Clue, coordinate2: Point):
:param coordinate2: the second coordinate
:return: the distance between the two coordinates
"""
- return ((coordinate1.latitude - coordinate2.latitude) ** 2 + (
- coordinate1.longitude - coordinate2.longitude) ** 2) ** 0.5
+ return (
+ (coordinate1.latitude - coordinate2.latitude) ** 2
+ + (coordinate1.longitude - coordinate2.longitude) ** 2
+ ) ** 0.5