diff options
| author | Anson Bridges <bridges.anson@gmail.com> | 2023-11-10 16:46:09 -0500 |
|---|---|---|
| committer | Anson Bridges <bridges.anson@gmail.com> | 2023-11-10 16:46:09 -0500 |
| commit | a3db30e2a06685aa2976ac8062040b4657109523 (patch) | |
| tree | 0611c4ea4d36403969051799b69af5ef8a4a31e0 /dashboard_website/router.py | |
| parent | 0e5d5ea7b26e55a6b83a10c53eada788d87428c2 (diff) | |
ROUGH DRAFT
Diffstat (limited to 'dashboard_website/router.py')
| -rw-r--r-- | dashboard_website/router.py | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/dashboard_website/router.py b/dashboard_website/router.py index 5bafd1e..5d5a909 100644 --- a/dashboard_website/router.py +++ b/dashboard_website/router.py @@ -1,9 +1,12 @@ import numpy as np import requests from sklearn.cluster import KMeans +import time +from datetime import datetime from datastructs import * + host = "http://acetyl.net:5000" # queries acetyl.net:5000, the OSRM engine @@ -12,22 +15,26 @@ host = "http://acetyl.net:5000" # queries acetyl.net:5000, the OSRM engine # gets single leg route between bike and clue # should be HD and GeoJSON def getRouteFullJSON(bike, clue): + 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 = response.get(url) + r = requests.get(url) return r.json() def getRouteHDPolyline(bike, clue): + 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 = response.get(url) - p = r.json()['trips'][0]['geometry']['coordinates'] + r = requests.get(url) + + p = r.json()['routes'][0]['geometry']['coordinates'] return p def getRouteFastPolyline(bike, clue): + bike = bike.toJSON(); clue = clue.toJSON() 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'] + r = requests.get(url) + p = r.json()['routes'][0]['geometry']['coordinates'] return p @@ -37,23 +44,25 @@ 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 ] + 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"] if len(active_bikes) == 0: - return clusters, route_geos + return clusters, route_geos, times active_clues = [clue for clue in clues if clue.status == "UNVISITED"] # select only active bikes # select only unvisited clues - clusters_t, route_geos_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] # return list of clue clusters corresponding to bikes - return clusters, route_geos + return clusters, route_geos, times # utility functions (internal) @@ -68,39 +77,46 @@ def cluster_and_optimize(clues: [Clue], bikes: [Bike], end: Point, time_diff=0.2 :param n: the number of routes to create :return: a list of lists of clues (ordered by position on route), and a list of json route geojsons """ - - # Create a new column with normalized gps coordinates and centroids - normalized_points, norm_centroids = __normalize_points(clues, bikes) - print(norm_centroids) - # Cluster the coordinates - kmeans = KMeans(n_clusters=len(norm_centroids), init=norm_centroids) - kmeans.fit(normalized_points) - - # Split the clues into clusters based on the cluster labels - routes = [[] for i in range(len(norm_centroids))] - for i, label in enumerate(kmeans.labels_): - routes[label].append(clues[i]) - - routes = __minimize_route_time_diff(routes, bikes, end, time_diff, n) - + 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) + # Cluster the coordinates + kmeans = KMeans(n_clusters=len(norm_centroids), init=norm_centroids) + kmeans.fit(normalized_points) + + # Split the clues into clusters based on the cluster labels + routes = [[] for i in range(len(norm_centroids))] + for i, label in enumerate(kmeans.labels_): + 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) + eta_str = 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): - route = [ route[ j['waypoint_index']-1 ] for j in route_waypoints[i] if route_waypoints[i].index(j) < (len(route_waypoints[i])-1) ] - routes[i] = route + route2 = ["" for x in route] + for j,k in enumerate(route_waypoints[i][1:-1]): + route2[ k['waypoint_index']-1 ] = route[j] + routes[i] = route2 - return routes, geometries + return routes, geometries, times def __clues_to_string(points: [Clue]): @@ -125,13 +141,13 @@ 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') + '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): +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 @@ -147,7 +163,8 @@ def __get_trip_time(coordinate_string, num_waypoints, start, end, time_per_waypo 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) total_time_hours = (travel_time_seconds + waypoint_time_seconds) / 3600 return total_time_hours |
