summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoritsGarrin <garrin.shieh@gmail.com>2023-11-08 18:08:06 -0500
committeritsGarrin <garrin.shieh@gmail.com>2023-11-08 18:08:06 -0500
commitcb075ec78f3d816f9688cfd7d3cb7f8d960832e7 (patch)
treecc0732ae7e24eecf71facfc354ba2feee9552db5
parent7a64a92c18e6512b6e6afcb52291e75c140b42fd (diff)
Changed types for router.py
-rw-r--r--dashboard_website/router.py117
1 files changed, 52 insertions, 65 deletions
diff --git a/dashboard_website/router.py b/dashboard_website/router.py
index 658c112..709c8d1 100644
--- a/dashboard_website/router.py
+++ b/dashboard_website/router.py
@@ -3,7 +3,10 @@ import pandas as pd
import requests
from sklearn.cluster import KMeans
-host = "http://acetyl.net:5000" # queries acetyl.net:5000, the OSRM engine
+from dashboard_website import db
+
+host = "http://acetyl.net:5000" # queries acetyl.net:5000, the OSRM engine
+
# external facing functions
@@ -14,113 +17,94 @@ def getRouteFullJSON(bike, clue):
r = response.get(url)
return r.json()
+
def getRouteHDPolyline(bike, clue):
url = f"{host}/route/v1/bike/{bike['longitude']},{bike['latitude']};{clue['longitude']},{clue['latitude']}?overview=full&geometries=geojson"
r = response.get(url)
p = r.json()['trips'][0]['geometry']['coordinates']
return p
+
def getRouteFastPolyline(bike, clue):
url = f"{host}/route/v1/bike/{bike['longitude']},{bike['latitude']};{clue['longitude']},{clue['latitude']}?geometries=geojson"
r = response.get(url)
p = r.json()['trips'][0]['geometry']['coordinates']
return p
+
def getZSP(bike, home, clue_cluster):
pass
+
# determines clusters based on current bikes and clues
def getClusters(bikes, clues, endpoint):
- clusters = [ [] for bike in bikes ]
+ clusters = [[] for bike in bikes]
active_bikes = [bike for bike in bikes if bike.status == "ACTIVE"]
active_clues = [clue for clue in clues if clue.status == "UNVISITED"]
# select only active bikes
# select only unvisited clues
- clusters_t, route_geo = cluster_and_optimize( active_clues, active_bikes,endpoint)
+ clusters_t, route_geo = cluster_and_optimize(active_clues, active_bikes, endpoint)
for cluster in clusters_t:
clusters[i] = cluster
- #return list of clue clusters corresponding to bikes
+ # return list of clue clusters corresponding to bikes
pass
+
# utility functions (internal)
-def cluster_and_optimize(df, centroids, end, time_diff=0.25, max_time=24, n=2):
+def cluster_and_optimize(clues: [db.Clue], bikes: [db.Bike], end: db.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 df: a dataframe of gps coordinates
- :param centroids: a list of centroids
+ :param clues: a list of clues
+ :param bikes: a list of centroids
:param end: the end point of the trip
:param time_diff: the maximum time difference between the longest trip and the average trip
:param max_time: the maximum time of the trip
:param n: the number of routes to create
:return: a dataframe with a cluster column
"""
+ regular_points = []
+ for clue in clues:
+ regular_points.append(db.Point(clue.latitude, clue.longitude))
+
# Create a new column with normalized gps coordinates and centroids
- df['normalized_gps'], norm_centroids = __normalize_gps(df['gps'].values.tolist(), centroids)
+ normalized_points, norm_centroids = __normalize_points([db.Point(clue.latitude, clue.longitude) for clue in clues],
+ [db.Point(bike.latitude, bike.longitude) for bike in bikes])
# Cluster the coordinates
kmeans = KMeans(n_clusters=len(norm_centroids), init=norm_centroids)
- kmeans.fit(df['normalized_gps'].values.tolist())
+ kmeans.fit(normalized_points)
- df['cluster'] = kmeans.labels_
+ # Create a dataframe with the gps coordinates, the cluster, and the list of coordinates
+ df = pd.DataFrame({'gps': regular_points, 'cluster': kmeans.labels_})
+ # Create the coordinate list from the bikes (the centroids) and the routes (the clues)
routes = []
- starts = []
- for i in range(len(centroids)):
- routes.append(df[df['cluster'] == i]['gps'].values.tolist())
- starts.append(list_to_string([centroids[i]]))
+ for i in range(len(bikes)):
+ routes.append(df[df['cluster'] == i]['gps'].tolist())
- routes = __minimize_route_time_diff(routes, starts, end, time_diff, n)
+ 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], starts[i], end, max_time)
+ routes[i] = __remove_longest_waypoints(routes[i], bikes[i], end, max_time)
df.loc[df['gps'].astype(str).isin(map(str, routes[i])), 'cluster'] = i
- return df, routes
-
-def list_to_string(list_of_lists):
+def __points_to_string(point: [db.Point]):
"""
- Takes a list of lists and returns a string of the list of lists
- :param list_of_lists: a list of lists
- :return: a string of the list of lists
+ Takes a list of points and returns a string of the list of points
+ :param point: a list of points
+ :return: a string of the list of points
"""
string = ''
- for i in list_of_lists:
- string += str(i[1]) + ',' + str(i[0]) + ';'
+ for i in point:
+ string += str(i.longitude) + ',' + str(i.latitude) + ';'
return string
-def create_json_df(coordinate_string, start, end):
- """
- Takes a string of coordinates and returns a dataframe of the coordinates in order of the waypoint index
- :param coordinate_string: a string of coordinates
- :param start: the start point of the trip
- :param end: the end point of the trip
- :return: a dataframe of the coordinates in order of the waypoint index
- """
- coordinates = requests.get(
- 'http://acetyl.net:5000/trip/v1/bike/' + start + coordinate_string + end + '?roundtrip=false&source=first&destination=last')
- coordinates = coordinates.json()
-
- # Create a dataframe from the JSON
- df = pd.DataFrame(coordinates['waypoints'])
-
- # Separate the location column into lon and lat columns
- df['lat'] = df['location'].apply(lambda x: x[0])
- df['lon'] = df['location'].apply(lambda x: x[1])
-
- df['waypoint_index'] = df['waypoint_index'].astype(int)
-
- # Map out the waypoints in order of the waypoint index
- df = df.sort_values(by=['waypoint_index'])
-
- return df
-
-
-def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoint=90):
+def __get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoint=90):
"""
Takes a string of coordinates and returns the trip time in hours
:param coordinate_string: a string of coordinates
@@ -142,7 +126,7 @@ def get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypoin
return total_time_hours
-def __minimize_route_time_diff(routes, starts, end, time_diff, n):
+def __minimize_route_time_diff(routes: [db.Point], starts: [db.Point], end: db.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
@@ -155,7 +139,8 @@ def __minimize_route_time_diff(routes, starts, end, time_diff, n):
times = []
for i, route in enumerate(routes):
- times.append(get_trip_time(list_to_string(route), len(route), starts[i], end))
+ times.append(__get_trip_time(__points_to_string(route), len(route), __points_to_string([starts[i]]),
+ __points_to_string([end])))
# Find the average trip time
average_time = np.mean(times)
@@ -181,7 +166,7 @@ def __minimize_route_time_diff(routes, starts, end, time_diff, n):
return routes
-def __remove_longest_waypoints(route_coordinates, start, end, max_time):
+def __remove_longest_waypoints(route_coordinates: [db.Point], start: db.Point, end: db.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
@@ -191,7 +176,8 @@ def __remove_longest_waypoints(route_coordinates, start, end, max_time):
:return: a list of coordinates
"""
# Find the trip time for the route
- route_time = get_trip_time(list_to_string(route_coordinates), len(route_coordinates), start, end)
+ route_time = __get_trip_time(__points_to_string(route_coordinates), len(route_coordinates),
+ __points_to_string([start]), __points_to_string([end]))
# 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:
@@ -204,7 +190,7 @@ def __remove_longest_waypoints(route_coordinates, start, end, max_time):
return route_coordinates
-def __normalize_gps(coordinates, centroids):
+def __normalize_points(coordinates: [db.Point], centroids: [db.Point]):
"""
Takes a list of coordinates and a list of centroids and returns a list of normalized coordinates and a list of
normalized centroids
@@ -214,8 +200,8 @@ def __normalize_gps(coordinates, centroids):
"""
# Create a list of latitudes and longitudes
- latitudes = [i[0] for i in coordinates]
- longitudes = [i[1] for i in coordinates]
+ latitudes = [i.latitude for i in coordinates]
+ longitudes = [i.longitude for i in coordinates]
# Find the minimum and maximum latitudes and longitudes
min_lat = min(latitudes)
@@ -248,7 +234,7 @@ def __min_max_normalize(value, min_value, max_value):
return (value - min_value) / (max_value - min_value)
-def __find_closest_coordinate(coordinates, centroid):
+def __find_closest_coordinate(coordinates: [db.Point], centroid: db.Point):
"""
Takes a list of coordinates and a centroid and returns the coordinate in the list that is closest to the centroid
:param coordinates: the list of coordinates
@@ -266,7 +252,7 @@ def __find_closest_coordinate(coordinates, centroid):
return closest_coordinate
-def __find_farthest_coordinate(coordinates, centroid):
+def __find_farthest_coordinate(coordinates: [db.Point], centroid: db.Point):
"""
Takes a list of coordinates and a centroid and returns the coordinate in the list that is farthest from the centroid
:param coordinates: the list of coordinates
@@ -284,20 +270,21 @@ def __find_farthest_coordinate(coordinates, centroid):
return farthest_coordinate
-def __mean_center(coordinates):
+def __mean_center(coordinates: [db.Point]):
"""
Takes a list of coordinates and returns the mean center of the coordinates
:param coordinates: the list of coordinates
:return: the mean center of the coordinates
"""
- return [sum([i[0] for i in coordinates]) / len(coordinates), sum([i[1] for i in coordinates]) / len(coordinates)]
+ return db.Point(np.mean([i.latitude for i in coordinates]), np.mean([i.longitude for i in coordinates]))
-def __distance(coordinate1, coordinate2):
+def __distance(coordinate1: db.Point, coordinate2: db.Point):
"""
Takes two coordinates and returns the distance between them
:param coordinate1: the first coordinate
:param coordinate2: the second coordinate
:return: the distance between the two coordinates
"""
- return ((coordinate1[0] - coordinate2[0]) ** 2 + (coordinate1[1] - coordinate2[1]) ** 2) ** 0.5 \ No newline at end of file
+ return ((coordinate1.latitude - coordinate2.latitude) ** 2 + (
+ coordinate1.longitude - coordinate2.longitude) ** 2) ** 0.5