summaryrefslogtreecommitdiff
path: root/dashboard_website/router.py
diff options
context:
space:
mode:
authorAnson Bridges <bridges.anson@gmail.com>2023-11-10 16:46:09 -0500
committerAnson Bridges <bridges.anson@gmail.com>2023-11-10 16:46:09 -0500
commita3db30e2a06685aa2976ac8062040b4657109523 (patch)
tree0611c4ea4d36403969051799b69af5ef8a4a31e0 /dashboard_website/router.py
parent0e5d5ea7b26e55a6b83a10c53eada788d87428c2 (diff)
ROUGH DRAFT
Diffstat (limited to 'dashboard_website/router.py')
-rw-r--r--dashboard_website/router.py79
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