def test_find_nearest(): # get graph and x/y coords to search G = ox.graph_from_point(location_point, dist=500, network_type="drive") Gp = ox.project_graph(G) points = ox.utils_geo.sample_points(ox.get_undirected(Gp), 5) X = points.x Y = points.y # get nearest node nn, d = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=True) nn = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=False) # get nearest nodes nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True) nn2, dist2 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree", return_dist=True) nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True) nn4 = ox.get_nearest_nodes(G, X, Y) nn5 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree") nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(Gp, location_point, return_geom=True, return_dist=True) u, v, k, g = ox.get_nearest_edge(Gp, location_point, return_geom=True) u, v, k, d = ox.get_nearest_edge(Gp, location_point, return_dist=True) u, v, k = ox.get_nearest_edge(Gp, location_point) # get nearest edges ne0 = ox.distance.nearest_edges(Gp, X, Y, interpolate=50) ne1 = ox.get_nearest_edges(Gp, X, Y) ne2 = ox.get_nearest_edges(Gp, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def findPath(paths): startTime = time.time() punggol = (1.4041070, 103.9025242) # Punggol Interchange as mid point distance = 3000 G = ox.graph_from_point(punggol, distance=distance, network_type='drive_service') listOfNodes = [] # Stored as [ (lat, lon, BusStopCode) ] format listOfTuplesStartEndLatLon = [ ] # Stored as [ ((Start1 lat, Start1 lon) , (End2 lat, End2 lon)) ] format route = [] # Routes to travel from [Route Start1 to End 2]format with open('../../bus_data/Punggol_Bus_Stops.json') as bus_stop: data = json.load(bus_stop) for i in paths: for x in data['punggolBusStops']: if i == int(x['BusStopCode']): tempTuple = (x['Latitude'], x['Longitude'], x['BusStopCode']) listOfNodes.append(tempTuple) break # Retriving the long and lat of the nodes for i in range(len(listOfNodes)): if i != (len(listOfNodes) - 1): listOfTuplesStartEndLatLon.append( ((float(listOfNodes[i][0]), float(listOfNodes[i][1])), (float(listOfNodes[i + 1][0]), float(listOfNodes[i + 1][1])))) # Retriving of all routes(edges) to plot route for i in range(len(listOfTuplesStartEndLatLon)): route.extend( nx.shortest_path(G, (ox.get_nearest_edge( G, (listOfTuplesStartEndLatLon[i][0][0], listOfTuplesStartEndLatLon[i][0][1])))[2], (ox.get_nearest_edge( G, (listOfTuplesStartEndLatLon[i][1][0], listOfTuplesStartEndLatLon[i][1][1])))[2])) route = removeDupes(route) endTime = time.time() print("Bus Route Retrieval Takes: ", round((endTime - startTime), 2)) return route, listOfTuplesStartEndLatLon
def osmnx_response(coordinates, type): dict = {} dict["type"] = "edges" edges = [] touple = [] if type == "loop": for i in range(0, len(coordinates), 2): nr_edge = ox.get_nearest_edge( G, (float(coordinates[i]), float(coordinates[i + 1]))) touple.append([nr_edge[1], nr_edge[2]]) for i in range(len(G[nr_edge[1]][nr_edge[2]])): if str(G[nr_edge[1]][nr_edge[2]][i]['geometry']) == str( nr_edge[0]): key = i touple[-1].append(key) if len(touple) == 2: print("touple ", touple) edges.append(touple) touple = [] polyline_string.update_polyline(nr_edge[0]) else: for i in range(0, len(coordinates), 2): nr_edge = ox.get_nearest_edge( G, (float(coordinates[i]), float(coordinates[i + 1]))) touple = [nr_edge[1], nr_edge[2]] for i in range(len(G[nr_edge[1]][nr_edge[2]])): if str(G[nr_edge[1]][nr_edge[2]][i]['geometry']) == str( nr_edge[0]): key = i touple.insert(len(touple), key) edges.append(touple) G.remove_edge(nr_edge[1], nr_edge[2], key) touple = [] dict["data"] = edges print(edges) return dict
def get_nearestedge_node(osm_id, a, G): """ Find the nearest node available in Open street map Parameters ---------- osm_id : node ID a : plotting graph g : bus graph Returns ------- temp_nearest_edge[1]/temp_nearest_edge[2] : nearest node to a way ID """ temp_y = G.nodes.get(osm_id).get('y') temp_x = G.nodes.get(osm_id).get('x') temp_nearest_edge = ox.get_nearest_edge(a, (temp_y, temp_x)) temp_1 = temp_nearest_edge[0].coords[0] temp_2 = temp_nearest_edge[0].coords[1] temp1_x = temp_1[0] temp1_y = temp_1[1] temp_1_distance = calculate_H(temp1_y, temp1_x, temp_y, temp_x) temp2_x = temp_2[0] temp2_y = temp_2[1] temp_2_distance = calculate_H(temp2_y, temp2_x, temp_y, temp_x) if temp_1_distance < temp_2_distance: return temp_nearest_edge[1] else: return temp_nearest_edge[2]
def LRTPathFinder(G, StartPt, EndStation): """To path find the StartStation to the Endstation, this will return a path or array of node to node edge function. In order for the Function to return the path, the path will find until the node is 50 metres from the endStation This Function uses Breadth-First Search but of queue, it utilises 2 arrays as there is only 2 direction that LRT can go""" firstLoop = False StartNode = ox.get_nearest_edge(G, StartPt) StartNode = StartNode[1] LRTRoute1 = [] LRTRoute1.append(StartNode) LRTRoute2 = [] LRTRoute2.append(StartNode) while True: if (firstLoop == False): for i in G[StartNode]: if (len(LRTRoute1) == 1): LRTRoute1.append(i) elif (len(LRTRoute2) == 1): LRTRoute2.append(i) firstLoop = True else: for nei, etc in G[LRTRoute1[-1]].items(): if (nei not in LRTRoute1): LRTRoute1.append(nei) if (getDirectDistance(G, EndStation, nei) < 0.05): return LRTRoute1 for i in G[LRTRoute2[-1]]: if (i not in LRTRoute2): LRTRoute2.append(i) if (getDirectDistance(G, EndStation, i) < 0.05): return LRTRoute2
def test_find_nearest(): # get graph G = ox.graph_from_point(location_point, dist=500, network_type="drive") # get nearest node nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True) # get nearest nodes: haversine, kdtree, balltree gdf_nodes = ox.graph_to_gdfs(G, edges=False) X = gdf_nodes["x"].head() Y = gdf_nodes["y"].head() nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True) nn2, dist2 = ox.get_nearest_nodes(G, X, Y, method="kdtree", return_dist=True) nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True) nn4 = ox.get_nearest_nodes(G, X, Y) nn5 = ox.get_nearest_nodes(G, X, Y, method="kdtree") nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True) # get nearest edges: haversine, kdtree, balltree ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def test_nearest_edge(): # test in closest edge section sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11] location_coordinates = (25.071764, 55.138978) G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive') geometry, u, v = ox.get_nearest_edge(G, location_coordinates)
def test_nearest_edge(): # test in closest edge section sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11] location_coordinates = (25.071764, 55.138978) G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive') geometry, u, v = ox.get_nearest_edge(G, location_coordinates)
def nearest_edge(G, i): """ :param G: NetworkX graph. Geographic scenario :param i: tuple collect point coordinates :param keys: list list with id of adjacent nodes :return: tuple, list tuple with coordinates of adjacent nodes list with id of adjacent nodes """ keys = [0, 0] keys[0], keys[1], key, shapely, distance_ = ox.get_nearest_edge( G, i, return_geom=True, return_dist=True) # edges_array = ox.get_nearest_nodes(G, np.array([i[1]]), np.array([i[0]]), method='kdtree') attribute_x = nx.get_node_attributes(G, 'x') attribute_y = nx.get_node_attributes(G, 'y') lon_node1 = attribute_x.get(keys[0]) lat_node1 = attribute_y.get(keys[0]) lon_node2 = attribute_x.get(keys[1]) lat_node2 = attribute_y.get(keys[1]) coordinates = [(lat_node1, lon_node1), (lat_node2, lon_node2)] return coordinates, keys
def test_find_nearest(): # get graph G = ox.graph_from_point(location_point, dist=500, network_type="drive") # convert graph to node/edge GeoDataFrames and back again gdf_nodes, gdf_edges = ox.graph_to_gdfs( G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True ) assert len(gdf_nodes) == len(G) assert len(gdf_edges) == len(G.edges(keys=True)) G = ox.graph_from_gdfs(gdf_nodes, gdf_edges) assert len(gdf_nodes) == len(G) assert len(gdf_edges) == len(G.edges(keys=True)) # get nearest node nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True) # get nearest nodes: haversine, kdtree, balltree X = gdf_nodes["x"].head() Y = gdf_nodes["y"].head() nn1 = ox.get_nearest_nodes(G, X, Y) nn2 = ox.get_nearest_nodes(G, X, Y, method="kdtree") nn3 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True) # get nearest edges: haversine, kdtree, balltree ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def get_closest_node(self,G ): nodes, _ = ox.graph_to_gdfs(G) geom, u, v, marosca = ox.get_nearest_edge(G, (self.lat, self.lng)) nn = min((u, v), key=lambda n: ox.great_circle_vec(self.lat, self.lng, G.nodes[n]['y'], G.nodes[n]['x'])) return G.nodes[nn]['x'], G.nodes[nn]['y']
def remove_edge(self, coords, time): nr_edge = ox.get_nearest_edge(self.graph, (coords[0], coords[1])) u, v = nr_edge[1], nr_edge[2] key_del = max(self.graph[u][v], key=int) edge_attributes = self.graph[u][v][key_del] self.graph.remove_edge(u, v, key=key_del) self.damaged_edges.append([(u, v, edge_attributes), time])
def update_camera(self, name: str, latlon: Tuple[float, float], metadata: Dict = {}, max_intersection_dist: float = 5, max_lane_dist: float = 5) -> Tuple[bool, bool]: """ return Tuple(a: bool, b: bool): a indicates whether the camera is successfully added to the road network. b indicates whether the topology has changed. """ # We simply remove the existing camera and calculate the new # position. And topology_change is always true if success. # TODO: decide whether the topology actually changes. if name in self.cameraInfo: self.remove_camera(name) success = False nearest_node, dist = ox.get_nearest_node(self.G, latlon, return_dist=True) if dist < max_intersection_dist: self.node_camera.add_camera(nearest_node, name) success = True else: u, v, key, dist = ox.get_nearest_edge(self.G, latlon, return_dist=True) if dist < max_lane_dist: self.edge_camera.add_camera((u, v, key), name, latlon) success = True if success: self.cameraInfo[name] = {'latlon': latlon, 'meta': metadata} return success, success
def line_to_nodes_precise(graph, tram_line): """ Method uses line_to_nodes and adds not covered stops It turned out that line_to_nodes does not cover all the line This method fix this issue :param graph: MultiDiGraph :param tram_line: TramLine object :return: list of nodes """ nodes = GraphConverter.line_to_nodes(graph, tram_line.default_route) sub_graph = graph.subgraph(nodes) # Make MultiLineString or LineString object (if MultiLineString can be merged) current_route = GraphConverter.route_to_line_string(sub_graph) stops = tram_line.stops # Check if current route contains stop for stop in stops: # If it does omit the rest if current_route.contains(stop): continue # If not get the nearest edge nr_edge = ox.get_nearest_edge(graph, (stop.y, stop.x)) # If nearest edge from stops contains stop we can add nodes of this edge to the list # Note: If route is connected graph it is obvious that each stop is contained in one of the edges # but If route is not connected then nearest edge of the stop could return some unwanted edge if nr_edge[0].contains(stop): if nr_edge[1] not in nodes: nodes.append(nr_edge[1]) if nr_edge[2] not in nodes: nodes.append(nr_edge[2]) return nodes
def get_nearestedge_node(self, osm_id, rG, bG): """ Using OMSNX data, get the coordinates from bus stop, get the nearest edge on the road, return the node of either end which is nearer to bus stop """ # with the use of osmid get the nearest node to the start and end coordinates temp_y = bG.nodes.get(osm_id).get('y') temp_x = bG.nodes.get(osm_id).get('x') temp_nearest_edge = ox.get_nearest_edge(rG, (temp_y, temp_x)) temp_1 = temp_nearest_edge[0].coords[0] temp_2 = temp_nearest_edge[0].coords[1] temp1_x = temp_1[0] temp1_y = temp_1[1] # calculate the distance by calling the haversine function with the haversine formula temp_1_distance = self.haversine(temp1_y, temp1_x, temp_y, temp_x) temp2_x = temp_2[0] temp2_y = temp_2[1] # calculate the distance by calling the haversine function with the haversine formula temp_2_distance = self.haversine(temp2_y, temp2_x, temp_y, temp_x) if temp_1_distance < temp_2_distance: return temp_nearest_edge[1] else: return temp_nearest_edge[2]
def findPath(G, paths): startTime = time.time() listOfNodes = [] # Stored as [ (lat, lon, BusStopCode) ] format listOfTuplesStartEndLatLon = [ ] # Stored as [ ((Start1 lat, Start1 lon) , (End2 lat, End2 lon)) ] format route = [] # Routes to travel from [Route Start1 to End 2]format with open('data/Punggol_Bus_Stops.json') as bus_stop: data = json.load(bus_stop) # Complexity of O(n^2) n number of paths, n number of busstops in .json for i in paths: for x in data['punggolBusStops']: if i == int(x['BusStopCode']): tempTuple = (x['Latitude'], x['Longitude'], x['BusStopCode']) listOfNodes.append(tempTuple) break # Retriving the long and lat of the nodes # Complexity of O(n) n number of nodes for i in range(len(listOfNodes)): if i != (len(listOfNodes) - 1): listOfTuplesStartEndLatLon.append( ((float(listOfNodes[i][0]), float(listOfNodes[i][1])), (float(listOfNodes[i + 1][0]), float(listOfNodes[i + 1][1])))) # Retriving of all routes(edges) to plot route # Complexity of O(n) n number of tuples of StartEnds for i in range(len(listOfTuplesStartEndLatLon)): route.extend( nx.shortest_path(G, (ox.get_nearest_edge( G, (listOfTuplesStartEndLatLon[i][0][0], listOfTuplesStartEndLatLon[i][0][1])))[2], (ox.get_nearest_edge( G, (listOfTuplesStartEndLatLon[i][1][0], listOfTuplesStartEndLatLon[i][1][1])))[2])) route = removeDupes(route) endTime = time.time() print("Bus Route Retrieval Takes: ", round((endTime - startTime), 2)) return route
def get_closest_node(self, lng, lat): geom, u, v, marosca = ox.get_nearest_edge(self.G, (lat, lng)) nn = min((u, v), key=lambda n: ox.great_circle_vec(lat, lng, self.G.nodes[n][ 'y'], self.G.nodes[n]['x'])) #print("random_point: "+lat+" , "+lng) return self.G.nodes[nn]['osmid']
def add_split_edge_to_graph(G, point): n_edge = ox.get_nearest_edge(G, (point.y, point.x)) n_node = get_closest_point_on_line(n_edge[0], point) split_line = get_split_lines(n_edge[0], n_node) if (split_line[0].coords[0] == n_edge[0].coords[0]): G.add_edge(n_edge[1], 1, key=n_edge[3], geometry=split_line[0]) G.add_edge(1, n_edge[2], key=n_edge[3], geometry=split_line[1]) else: G.add_edge(n_edge[1], 1, key=n_edge[3], geometry=split_line[1]) G.add_edge(1, n_edge[2], key=n_edge[3], geometry=split_line[0]) return G, n_edge
def _find_nearest_edges_ride(self, lats, lons): edge_prev = -2 edge_list = [] for lat, lon in zip(lats, lons): if edge_prev == -2: edge_prev = -1 edge = osmnx.get_nearest_edge(self.graph, (lat, lon))[1:] else: if edge != edge_prev: # get nodes of edge and its neighbors to induce relevant subgraph nodes_list = [[node, *list(self.graph.neighbors(node))] for node in edge] # flatten list nodes_list = set( [node for sublist in nodes_list for node in sublist]) # find point on subgraph of neighbors of last point# subgraph = self.graph.subgraph(nodes_list) edge_prev = edge edge = osmnx.get_nearest_edge(subgraph, (lat, lon))[1:] edge_list.append(edge) return pd.Series(edge_list)
def get_random_node(self): nodes, _ = ox.graph_to_gdfs(self.G) lng = random.uniform(nodes['x'].min(), nodes['x'].max()) lat = random.uniform(nodes['y'].min(), nodes['y'].max()) geom, u, v, marosca = ox.get_nearest_edge(self.G, (lat, lng)) nn = min((u, v), key=lambda n: ox.great_circle_vec(lat, lng, self.G.nodes[n][ 'y'], self.G.nodes[n]['x'])) #print("random_point: "+lat+" , "+lng) return self.G.nodes[nn]['x'], self.G.nodes[nn]['y']
def get_nearestedge_node(osm_id, y, x): temp_nearest_edge = ox.get_nearest_edge(G, (y, x)) temp_1 = temp_nearest_edge[0].coords[0] temp_2 = temp_nearest_edge[0].coords[1] temp1_x = temp_1[0] temp1_y = temp_1[1] temp_1_distance = calculate_H(temp1_y, temp1_x, y, x) temp2_x = temp_2[0] temp2_y = temp_2[1] temp_2_distance = calculate_H(temp2_y, temp2_x, y, x) if temp_1_distance < temp_2_distance: return [temp_nearest_edge[1], temp_1_distance, temp1_x, temp1_y] else: return [temp_nearest_edge[2], temp_2_distance, temp2_x, temp2_y]
def test_calculate_bypass(self): """ Do: - Foreach route delete at least one edge (could be random) - calculate bypas for this route on modified graph Expected: - New route is displayed - User manualy verifies whether new route is correct or not """ dl = DataLoader() G = dl.graph lines_table = dl.load_all_lines() for line in lines_table: # Create TramLine object tram_line = TramLine(str(line[0]), line[1], dl) tram_line.show() # Convert line to nodes in order to verify graph before edges deletion nodes = GraphConverter.line_to_nodes_precise(G, tram_line) sub_graph = G.subgraph(nodes) ox.plot_graph(sub_graph) # Get stops on this line stops = dl.load_tram_stops( tram_line.default_route) # List of shapely objects # Get random stops # change range to increase or decrease number of deleted edges r_stops = [stops[randint(0, len(stops) - 1)] for i in range(3)] # Get nearest edges and delete them deleted_edges = list() for stop in r_stops: nr_edge = ox.get_nearest_edge(G, (stop.y, stop.x)) G.remove_edge(nr_edge[1], nr_edge[2]) deleted_edges.append(nr_edge) # Show route without edges sub_graph = G.subgraph(nodes) ox.plot_graph(sub_graph) # Now calculate bypas tram_line.current_route = SubstituteRoute.calculate_bypass( G, tram_line) print(type(tram_line.current_route)) tram_line.show() for e in deleted_edges: G.add_edge(e[1], e[2], geometry=e[0]) ox.plot_graph(G) self.assertTrue(True)
def get_path_data(): # Define polyline lists train_polyline = [] new_polyline = [] walk_polyline = [] bus_polyline = [] info = "" transfer = "" # Get user input source and destination, mode of transport input_src = request.args.get('source', 0, type=str) input_dest = request.args.get('dest', 0, type=str) transport_mode = request.args.get('transport_mode', type=str) # Geocode source and destination to lat lon src = do_geocode(input_src) dest = do_geocode(input_dest) # Set start as list of source lat lon start = [src.latitude, src.longitude] end = [dest.latitude, dest.longitude] # Get nearest nodes for start and end for bus, train and walk start_walk = ox.get_nearest_node(G_walk, (src.latitude, src.longitude)) end_walk = ox.get_nearest_node(G_walk, (dest.latitude, dest.longitude)) start_train = ox.get_nearest_node(G_train, (src.latitude, src.longitude), return_dist=True) end_train = ox.get_nearest_node(G_train, (dest.latitude, dest.longitude), return_dist=True) start_bus = ox.get_nearest_node(G_bus, (src.latitude, src.longitude), return_dist=True) end_bus = ox.get_nearest_node(G_bus, (dest.latitude, dest.longitude), return_dist=True) # Find nearest start and end train stations start_station_det = findingStation((src.latitude, src.longitude)) end_station_det = findingStation((dest.latitude, dest.longitude)) # Check if train in same or different loops east_bound = 0 west_bound = 0 diff_loop = 0 for n in mrt_nodes: mrt_id = n[2] # If start station in east loop if mrt_id == start_station_det[1] and start_station_det[1] in east: east_bound += 1 # If start station in west loop elif mrt_id == start_station_det[1] and start_station_det[1] in west: west_bound += 1 # If end station in east loop elif mrt_id == end_station_det[1] and end_station_det[1] in east: east_bound += 1 # If end station in west loop elif mrt_id == end_station_det[1] and end_station_det[1] in west: west_bound += 1 elif west_bound == 2 or east_bound == 2: # both lrt station in the same lrt loop print("same loop") break elif west_bound == 1 and east_bound == 1: # both lrt station in different lrt loop diff_loop = 1 break # =========================================== ALL =========================================== # if transport_mode == "all": # Check that the nearest train station for both locations is not the same if start_station_det[1] != end_station_det[1]: # Check if start and end is Punggol (Still same station) -> only do bus or walk if (start_station_det[1] == 6587709456 and end_station_det[1] == 6587709457) or (end_station_det[1] == 6587709456 and start_station_det[1] == 6587709457): # ====================================== PURELY WALKING ====================================== # walk_polyline.append( create_polyline(G_walk, start_walk, end_walk)) else: # Will return heuristic, OSMid, y, x. E.g. (253.48788074253008, 1840734598, 1.4118877, 103.9003304) # Starting node always use start_u, for ending node always use end_v start_geom, start_u, start_v = ox.get_nearest_edge( G_train, (start_station_det[2], start_station_det[3])) end_geom, end_u, end_v = ox.get_nearest_edge( G_train, (end_station_det[2], end_station_det[3])) # =========================================== TRAIN =========================================== # # if both lrt station found in different loops if diff_loop == 1: # retrieving path after running algo path1 = dijkstra(train_edges, start_u, 6587709457)[1] path2 = dijkstra(train_edges, 6587709457, end_v)[1] # convert nodes to coords and appending the coordinate path into new_polyline array swapOrder(ox.node_list_to_coordinate_lines(G_train, path1), new_polyline) swapOrder(ox.node_list_to_coordinate_lines(G_train, path2), new_polyline) # if both lrt station found in same loop else: # retrieving path after running algo path = dijkstra(train_edges, start_u, end_v)[1] # convert nodes to coords and appending the coordinate path into new_polyline array swapOrder(ox.node_list_to_coordinate_lines(G_train, path), new_polyline) # checking if start point is more than 200m from start lrt station if start_train[1] > 400: # finding nearest bus stop at lrt start station slrt_busstop = ox.get_nearest_node( G_bus, (start_station_det[2], start_station_det[3])) # run bus algo to take bus from start point to lrt start station start_line, sbus_info, sbus_path = bus_route( start_bus[0], slrt_busstop, 10) for x in start_line: for y in x: list(y) bus_polyline.append(start_line) # check if start point to start point bus stop is more than 2m. if start_bus[1] > 2: startbuscoord = () # retrieving the nearest walk node to the bus stop for n in bus_nodes: if n[2] == start_bus[0]: startbuscoord = (n[0], n[1]) swalkto_busstop = ox.get_nearest_node( G_walk, startbuscoord) # calculating and plotting walk from end point to bus stop walk_polyline.append( create_polyline(G_walk, start_walk, swalkto_busstop)) # start point is less than 200m from start lrt station else: # finding nearest walk node to start lrt station slrt_walknode = ox.get_nearest_node( G_walk, (start_station_det[2], start_station_det[3])) walk_polyline.append( create_polyline(G_walk, start_walk, slrt_walknode)) # checking if end point is more than 200m from end lrt station if end_train[1] > 400: # finding nearest bus stop at lrt end station elrt_busstop = ox.get_nearest_node( G_bus, (end_station_det[2], end_station_det[3])) # run bus algo to take bus from end point to lrt end station end_line, ebus_info, ebus_path = bus_route( elrt_busstop, end_bus[0], 10) for x in end_line: for y in x: list(y) bus_polyline.append(end_line) # check if end point to end point bus stop is more than 2m. if end_bus[1] > 2: endbuscoord = () # retrieving the nearest walk node to the bus stop for n in bus_nodes: if n[2] == end_bus[0]: endbuscoord = (n[0], n[1]) ewalkto_busstop = ox.get_nearest_node( G_walk, endbuscoord) # calculating and plotting walk from end point to bus stop walk_polyline.append( create_polyline(G_walk, ewalkto_busstop, end_walk)) # end point is less than 200m from start lrt station else: # finding nearest walk node to end lrt station elrt_walknode = ox.get_nearest_node( G_walk, (end_station_det[2], end_station_det[3])) walk_polyline.append( create_polyline(G_walk, elrt_walknode, end_walk)) # appending train plot train_polyline.append(new_polyline) # nearest start and end lrt station is the same, hence walk. else: walk_polyline.append(create_polyline(G_walk, start_walk, end_walk)) # =========================================== WALK =========================================== # elif transport_mode == "walk": walk_polyline.append(create_polyline(G_walk, start_walk, end_walk)) # =========================================== MRT =========================================== # elif transport_mode == "mrt": # Check that the nearest train station for both locations is not the same if start_station_det[1] != end_station_det[1]: # Check if start and end is Punggol (Still same station) -> only do bus or walk if (start_station_det[1] == 6587709456 and end_station_det[1] == 6587709457) or (end_station_det[1] == 6587709456 and start_station_det[1] == 6587709457): # ====================================== PURELY WALKING ====================================== # walk_polyline.append( create_polyline(G_walk, start_walk, end_walk)) else: start_geom, start_u, start_v = ox.get_nearest_edge( G_train, (start_station_det[2], start_station_det[3])) end_geom, end_u, end_v = ox.get_nearest_edge( G_train, (end_station_det[2], end_station_det[3])) # =========================================== TRAIN =========================================== # if diff_loop == 1: path1 = dijkstra(train_edges, start_u, 6587709457)[1] path2 = dijkstra(train_edges, 6587709457, end_v)[1] train_coords1 = ox.node_list_to_coordinate_lines( G_train, path1) swapOrder(train_coords1, new_polyline) train_coords2 = ox.node_list_to_coordinate_lines( G_train, path2) swapOrder(train_coords2, new_polyline) else: path = dijkstra(train_edges, start_u, end_v)[1] train_coords = ox.node_list_to_coordinate_lines( G_train, path) swapOrder(train_coords, new_polyline) # =========================================== WALK + MRT =========================================== # if start_train[1] > 10: to_mrt = ox.get_nearest_node( G_walk, (start_station_det[2], start_station_det[3])) walk_polyline.append( create_polyline(G_walk, start_walk, to_mrt)) if end_train[1] > 10: from_mrt = ox.get_nearest_node( G_walk, (end_station_det[2], end_station_det[3])) walk_polyline.append( create_polyline(G_walk, from_mrt, end_walk)) train_polyline.append(new_polyline) else: # ====================================== PURELY WALKING ====================================== # walk_polyline.append(create_polyline(G_walk, start_walk, end_walk)) # =========================================== BUS =========================================== # elif transport_mode == "bus": # Get user input cost option for bus cost_option = request.args.get('cost_option', 0, type=str) # If user chooses to plot shortest path for bus if cost_option == "sp": cost = 0 # User choose to plot bus with least transfers else: cost = 10 # Check that the nearest bus stop for both locations is not the same if start_bus[0] != end_bus[0]: line_string, bus_info, bus_path = bus_route( start_bus[0], end_bus[0], cost) for x in line_string: for y in x: list(y) bus_polyline.append(line_string) # =========================================== WALK + BUS =========================================== # if start_bus[1] > 5: for n in bus_nodes: if n[2] == start_bus[0]: to_bus = ox.get_nearest_node(G_walk, (n[0], n[1])) walk_polyline.append( create_polyline(G_walk, start_walk, to_bus)) if end_bus[1] > 5: for n in bus_nodes: if n[2] == end_bus[0]: from_bus = ox.get_nearest_node(G_walk, (n[0], n[1])) walk_polyline.append( create_polyline(G_walk, from_bus, end_walk)) info = "Number of transfers: " + str( bus_info[0][2] - 1) + "<br>Total Distance: " + str( round((bus_info[0][1]), 2)) + "km" transfer = "<br>Bus Route:<br>" for x in bus_path: transfer += "Bus No.: " + x[0] + " " + x[1] + " " + x[ 2] + "<br>" else: # ====================================== PURELY WALKING ====================================== # walk_polyline.append(create_polyline(G_walk, start_walk, end_walk)) # Return coordinates, address and polyline for plotting return jsonify(start=start, start_road=input_src, end=end, end_road=input_dest, train_path=train_polyline, walk_path=walk_polyline, bus_path=[bus_polyline], bus_info=info, bus_transfer=transfer)
def get_cr_from_osm(coordinates): """ Get rolling coefficient (cr) from osm surface attribute 1) Determine nearest osm edge for each coordinate 2) Determine surface attribute for each osm edge 3) Get rolling coefficient (cr) for the corresponding surface type from literature Hint: function will take some time when coordinates have a large spatial extent. Parameters ---------- coordinates: list of tuples (latitude, longitude) coordinates Returns ------- [cr, surface]: list of numpy arrays first array are rolling coefficient (cr) values and second array are surface attributes """ # TODO: Improve performance # TODO: Check scientific literature for rolling coefficient values lats = [coordinate[0] for coordinate in coordinates] lngs = [coordinate[1] for coordinate in coordinates] min_y = np.min(lats) max_y = np.max(lats) min_x = np.min(lngs) max_x = np.max(lngs) ox.settings.useful_tags_way = ["surface"] print( 'Get graph from bounding box: min_y={}, max_y={}, min_x={}, max_x={}'. format(min_y, max_y, min_x, max_x)) graph = ox.graph_from_bbox(max_y, min_y, max_x, min_x, network_type='drive') surface = [] cr = [] i = 0 print( 'Find nearest osm edge and set rolling coefficient according to the surface type of the edge.' ) for lat, lng in coordinates: x = ox.get_nearest_edge(graph, (lat, lng)) p = [x[0], x[1]] a = ox.utils_graph.get_route_edge_attributes(graph, p) dic = a[0] if "surface" in dic: surface.append(dic["surface"]) else: surface.append(None) # Get the rolling resistance coefficient # Sources # https://www.engineeringtoolbox.com/rolling-friction-resistance-d_1303.html # The Automotive Chassis book if surface[i] == "asphalt": cr.append(0.02) elif surface[i] == "cobblestone": cr.append(0.015) elif surface[i] == "paving_stones": cr.append(0.033) else: cr.append(0.02) i = i + 1 return [np.array(cr), np.array(surface)]
import osmnx as ox G = ox.graph_from_bbox(12.867853, 12.842623, 77.803543, 77.775726, network_type='drive') geom, u, v = ox.get_nearest_edge(G, (12.855777, 77.783582)) G_projected = ox.project_graph(G) print(geom, u, v) print(G_projected.edges()) ox.plot_graph(G_projected)
return closest_point def get_split_lines(line: LineString, point: Point) -> List[LineString]: """Splits a line at nearest intersecting point. Returns: A list containing two LineString objects. """ snap_line = snap(line, point, 0.01) result = split(snap_line, point) if (len(result) < 2): print('Error in splitting line at point: only one line in the result') return result n_edge = ox.get_nearest_edge(graph_proj, (point.y, point.x)) #get nearest edge to poi n_node = get_closest_point_on_line(n_edge[0], point) #get nearest node on that edge split_line = get_split_lines(n_edge[0], n_node) #split the edge at that node into 2 lines fig, ax = ox.plot_graph(graph_proj, node_color='#999999', show=False, close=False) ax.scatter(point.x, point.y, c='r', marker='x') ax.scatter(nn.x, nn.y, c='g', marker='x') #un-comment any 1 of the 3 below to visualize that line #x, y = n_edge[0].xy
def fuel_consumption(car:car, osmbox:BboxSelector, track_df = gpd.GeoDataFrame()): # Request elevation values from an open source (opentopodata.org) url = 'https://api.opentopodata.org/v1/eudem25m?locations=' tracks = pd.DataFrame(columns=track_df.columns) # Add surface in get attribute method ox.settings.useful_tags_way = ['bridge', 'tunnel', 'oneway', 'lanes', 'ref', 'name','highway', 'maxspeed', 'service', 'access', 'area','landuse', 'width', 'est_width', 'junction', 'surface'] # get the osm graph for the same area G = ox.graph_from_bbox(osmbox.max_y, osmbox.min_y, osmbox.max_x, osmbox.min_x, network_type='drive') # get the number of routes in the dataframe n = 0 a = track_df['track.id'].value_counts() for i in a: n+=1 # loop through the dataframe and get the elevation from open source for each record in each routes for i in range (0,n): one_track_id = track_df['track.id'].unique()[i] one_track = track_df[track_df['track.id'] == one_track_id] # estimate the len of data batch = [int(len(one_track)/100),len(one_track)%100] elevation=[] # get elevation for i in range(batch[0]+1): #create requeest 100 parameter s = i*100 e = (i+1)*100 if i<batch[0]+1: --e else: e= e+batch[1] #check the parameters (s) not excced the lenght of the track if s >= len(one_track): break #creat the request parms= generate_parms(one_track,s,e) #send the request and get the results access= url+parms part = request(access) if part==None: part=[np.nan]*(e+1-s) #put the results in a list elevation.extend(part) time.sleep(1) one_track['elevation']=elevation # Filterout the null value and use GPS altitude to fill them temp=one_track[one_track['elevation'].isnull()==True] if len(temp)> 0: for i in temp.index: one_track.loc[i,'elevation']=one_track.loc[i,'GPS Altitude.value'] # Match the graph with osm and get maxspeed & surface attriubutes ox.settings.useful_tags_way = ["maxspeed","surface"] for i in one_track.index: lat= one_track.loc[i,'geometry'].y lng= one_track.loc[i,'geometry'].x x = (ox.get_nearest_edge(G, (lat, lng))) p = [x[0],x[1]] a = ox.utils_graph.get_route_edge_attributes(G, p) dic = a[0] # check if the edge has maximum speed value if not then use the value of previous point if "maxspeed" in dic: one_track.loc[i,"maxspeed"] = dic["maxspeed"] else: if i > 0: m = one_track.loc[i-1,"maxspeed"] one_track.loc[i,"maxspeed"] = m # check if the edge has a surface value, if not then use the value of previous point if "surface" in dic: one_track.loc[i,"surface"] = dic["surface"] else: if i > 0: s = one_track.loc[i-1,"surface"] one_track.loc[i,"surface"] = s # get the rolling resistance cofficient if one_track.loc[i, 'surface'] == "asphalt": one_track.loc[i, 'rolling_resistance'] = 0.02 # source: engineeringtoolbox.com elif one_track.loc[i, 'surface'] == "cobblestone": one_track.loc[i, 'rolling_resistance'] = 0.015 # source: engineeringtoolbox.com elif one_track.loc[i, 'surface'] == "paving_stones": one_track.loc[i, 'rolling_resistance'] = 0.033 # source: The Automotive Chassis book else: one_track.loc[i, 'rolling_resistance'] = 0.02 #loop through the dataframe and calculate the gradient for i in one_track.index: if (i == len(one_track)-1): break # Get the coordinates of each point lat1= one_track.loc[i,'geometry'].y lat2= one_track.loc[i+1,'geometry'].y lon1= one_track.loc[i,'geometry'].x lon2= one_track.loc[i+1,'geometry'].x #calculate the elevation difference between the two points heightdiff = one_track.loc[i+1,'elevation'] - one_track.loc[i,'elevation'] #calculate the distance between the two points/ and the accumulated distance one_track.loc[i+1,'seg_distance']= distance(lon1,lon2,lat1,lat2) if i == 0: one_track.loc[i,'total_distance'] = 0 one_track.loc[i+1,'total_distance'] = one_track.loc[i+1,'seg_distance'] else: one_track.loc[i+1,'total_distance']= one_track.loc[i+1,'seg_distance'] + one_track.loc[i,'total_distance'] grade = gradient(heightdiff,one_track.loc[i+1,'seg_distance']) one_track.loc[i,'gradient']= grade ## Add interval time #get the timestamp column from the track track_time = one_track[['time']] #convert the timestamp column to sereis time_track = track_time.iloc[:,0] #convert the timestamp to data time x = pd.to_datetime(time_track) x_list = x.tolist() #calculate the time difference in second, and put it in a list time_interval = [] for i in range(len(x_list)): if i == 0 : time_in_second = 0 one_track.loc[i,'accumulate_time_interval'] = time_in_second else: time_in_second = ((x_list[i] - x_list[i-1]).total_seconds()) one_track.loc[i,'accumulate_time_interval'] = time_in_second + one_track.loc[i-1,'accumulate_time_interval'] time_interval.append(time_in_second) # add the time interval list to the track one_track['time_interval']=time_interval # Convert the speed unit to m/s for i in one_track.index: one_track.loc[i, 'speed'] = one_track.loc[i, 'GPS Speed.value'] / 3.6 # calculate the acceleration for i in one_track.index: if (i == len(one_track)-1): break else: one_track.loc[i, 'Acceleration'] = (one_track.loc[i+1, 'speed'] - one_track.loc[i, 'speed'])/one_track.loc[i,'time_interval'] ## Calculates Engine Power for general car for i in one_track.index: ep = engine_power(car,one_track.rolling_resistance[i],one_track.gradient[i],one_track.speed[i],one_track.Acceleration[i]) if ep[0] < 0: one_track.loc[i, 'engine_power'] = car.P_idle one_track.loc[i, 'driving_resistance'] = ep[1] else: one_track.loc[i, 'engine_power'] = ep[0] one_track.loc[i, 'driving_resistance'] = ep[1] ## Driving resistance for i in one_track.index: res = one_track.loc[i, 'driving_resistance'] if (res >= 2000 or res <= -2000): one_track.loc[i,'efficiency'] = 0.3 else: one_track.loc[i, 'efficiency'] = interpolation(res) ## Fuel consumption/CO2 emissions for General car (gasoline) for i in one_track.index: car_cons = fuel_consumptions(one_track.engine_power[i],car, one_track.loc[i,'efficiency']) one_track.loc[i, 'Consumption_Gasoline'] = car_cons ## liters / hour one_track.loc[i, 'CO2_Gasoline'] = car_cons * car.H_g ## kg Co2 / hour tracks = pd.concat([tracks, one_track]) tracks = tracks[['elevation','accumulate_time_interval','maxspeed','Acceleration','surface','rolling_resistance','gradient','efficiency','Consumption_Gasoline','CO2_Gasoline']] return tracks
def get_nearest_edge(self, coord): return ox.get_nearest_edge(self.graph, coord[::-1])
def lrt_bus_walk(graph, initial, dest, lrt_graph): # DISCLAIMER: function deprecated, leaving here for history's sake """ :param graph: NetworkX multigraph for walking. :param initial: Starting node in X Y tuple. Pretty much is always punggol mrt. :param dest: Destination node in X Y tuple. :param lrt_graph: NetworkX multigraph consisting of only LRT nodes and edges. :return: returns finalRoues[] which consists of multiple (just 2) routes in an array """ """ essentially a redo of lrt movement, but with bus adds a bus route should the an additional taking of bus from the LRT is required movement pseudo: Start > LRT_start > LRT_end if distance to destination > some_distance LRT_end > bus_start > bus_end > walk to destination else LRT_end > walk to destination """ finalRoutes = [] # will return this. # CURRENT LAYER: foot # now, we are at Punggol MRT. # We want to look for the closest LRT to the destination. endLRT = 0 endLRTXY = 0 lowest_dist = 5000 # dummy value. # loop through the LRT map and find the node that is closest to the destination with distance() for stn, d in lrt_graph.nodes(data=True): if 'ref' in d: # look at only valid stops - i.e nodes with a 'ref' stnXY = (lrt_graph.nodes[stn]['x'], lrt_graph.nodes[stn]['y']) print("|TEST| - Right now at Station ", stn, " coordinates: ", stnXY) curr_dist = distance(stnXY, dest) if curr_dist < lowest_dist: endLRT = stn endLRTXY = stnXY lowest_dist = curr_dist # CURRENT LAYER: lrt stations (real) # we know what LRT we want to go to # but real lrt stations are not actually connected together (in the graph) # so instead, we go to the closest connected node to it print("|TEST| - Closest real station to destination: ", endLRT, "at ", endLRTXY) closestEndLrt = ox.get_nearest_edge(lrt_graph, (endLRTXY[1], endLRTXY[0])) print("|TEST| - Connected ending node is : ", closestEndLrt[1]) # this is the node that's actually in the network # if using 103.9064504, 1.3988214 as end node, this should be Cove LRT # if using 103.9164448, 1.399601, this should be Kadaloor LRT wayID = 0 # get id of the LRT route we are in for (u, v, d) in lrt_graph.edges(data=True): if u == closestEndLrt[1]: wayID = d['osmid'] break print("|TEST| - OSM-ID of the proper LRT route is : ", wayID) # way ID of the LRT route we want to take has been acquired. # CURRENT LAYER: lrt stations (fake) # we now have a good connected dest. we now want to travel to that node. # but we need to figure out which connected node to start from (in Punggol) # that node must be in the same graph as the dest node # Punggol station is NOT a connected node. there are multiple nodes in Punggol station itself closestStartLrt = 0 lowest_dist = 5000 for (u, v, d) in lrt_graph.edges(data=True): if d['osmid'] == wayID: # get XY of the node in the lrt route stnXY = (lrt_graph.nodes[u]['x'], lrt_graph.nodes[u]['y']) curr_dist = distance(stnXY, initial) if curr_dist < lowest_dist: closestStartLrt = u # closestStartLrtXY = stnXY lowest_dist = curr_dist print("|TEST| - Connected starting node is: ", closestStartLrt) # traverse to that node from startLRT to endLRT lrt_g = Graph() for i in lrt_graph.edges.data(): length = i[2].get('length') lrt_g.add_edge(*(i[0], i[1], length)) # node1, node2, length lrtRoute = dijsktra(lrt_g, closestStartLrt, closestEndLrt[1])[0] # to do - figure out how to make sure correct LRT route is taken for dijkstra print("|TEST| - Now taking LRT from ", closestStartLrt, " to ", closestEndLrt[1]) print("|TEST| - LRT route: ", lrtRoute) lrtRouteYX = getRouteInYX(lrt_graph, lrtRoute) print("|TEST| - LRT route in YX (returns this): ", lrtRouteYX) finalRoutes.append(lrtRouteYX) # CURRENT LAYER: lrt stations (fake) # user has now ARRIVED at the connected lrt node. # we still have the real LRT destination node in endLRT (and endLRTXY for coord) # pop the user to the closest foot node. # start dijkstra from that foot node. # but if destination is still a good distance away (3200m, 400m, etc) # have the user take a bus instead if (distance(endLRTXY, dest) > 100): # if dest is far enough # endLRTXY = (endLRTXY[1], endLRTXY[0]) busRoute = [] #busRoute = walk_bus_algor(endLRTXY, dest) # DEPRECATED, no longer used, this code exists in walk_bus.py print("Bus route: ", busRoute) for x in busRoute: finalRoutes.append(x) return finalRoutes else: walkingStart = ox.get_nearest_node(graph, (endLRTXY[1], endLRTXY[0])) print("|TEST| - Now walking from: ", walkingStart, "(LRT) to destination ", dest) cGraph = Graph() for i in graph.edges.data(): length = i[2].get('length') cGraph.add_edge(*(i[0], i[1], length)) destID = ox.get_nearest_node(graph, (dest[1], dest[0])) walkingRoute = dijsktra(cGraph, walkingStart, destID)[0] print("|TEST| - Walking route: ", walkingRoute) print("|TEST| - End: ", destID, dest) finalRoutes.append(walkingRoute) return finalRoutes
def get_lrt_route(graph, initial, dest, lrt_graph, lrt_exits): """ :param graph: NetworkX multigraph for walking. :param initial: Starting node in X Y tuple. Pretty much is always punggol mrt. :param dest: Destination node in X Y tuple. :param lrt_graph: NetworkX multigraph consisting of only LRT nodes and edges. :return: returns finalRoues[] which consists of multiple (just 2) routes in an array """ """ essentially a redo of lrt movement, but with bus by right supposed to check for bus if node is far enough, but most nodes aren't far enough lol """ # CURRENT LAYER: foot # now, we are at Punggol MRT. # We want to look for the closest LRT to the destination. endLRT = 0 endLRTXY = 0 lowest_dist = 5000 # dummy value. # loop through the LRT map and find the node that is closest to the destination with distance() for stn, d in lrt_graph.nodes(data=True): if 'ref' in d: # look at only valid stops - i.e nodes with a 'ref' stnXY = (lrt_graph.nodes[stn]['x'], lrt_graph.nodes[stn]['y']) print("|TEST| - Right now at Station ", stn, " coordinates: ", stnXY) curr_dist = distance(stnXY, dest) if curr_dist < lowest_dist: endLRT = stn endLRTXY = stnXY lowest_dist = curr_dist # CURRENT LAYER: lrt stations (real) # we know what LRT we want to go to # but real lrt stations are not actually connected together (in the graph) # so instead, we go to the closest connected node to it print("|TEST| - Closest real station to destination: ", endLRT, "at ", endLRTXY) closestEndLrt = ox.get_nearest_edge(lrt_graph, (endLRTXY[1], endLRTXY[0])) print("|TEST| - Connected ending node is : ", closestEndLrt[1]) # this is the node that's actually in the network # if using 103.9064504, 1.3988214 as end node, this should be Cove LRT # if using 103.9164448, 1.399601, this should be Kadaloor LRT wayID = 0 # get id of the LRT route we are in for (u, v, d) in lrt_graph.edges(data=True): if u == closestEndLrt[1]: wayID = d['osmid'] break print("|TEST| - OSM-ID of the proper LRT route is : ", wayID) # way ID of the LRT route we want to take has been acquired. # CURRENT LAYER: lrt stations # we now have a good connected dest. we now want to travel to that node. # but we need to figure out which connected node to start from (in Punggol) # that node must be in the same graph as the dest node closestStartLrt = 0 lowest_dist = 5000 for (u, v, d) in lrt_graph.edges(data=True): if d['osmid'] == wayID: # get XY of the node in the lrt route stnXY = (lrt_graph.nodes[u]['x'], lrt_graph.nodes[u]['y']) curr_dist = distance(stnXY, initial) if curr_dist < lowest_dist: closestStartLrt = u # closestStartLrtXY = stnXY lowest_dist = curr_dist print("|TEST| - Connected starting node is: ", closestStartLrt) # traverse to that node from startLRT to endLRT lrt_g = Graph() for i in lrt_graph.edges.data(): length = i[2].get('length') lrt_g.add_edge(*(i[0], i[1], length)) # node1, node2, length # use dijkstra to acquire the best # graph is simple so dijkstra is not immediately the most useful lrtRoute = dijsktra(lrt_g, closestStartLrt, closestEndLrt[1])[0] # time complexity of dijkstra is O(n^2), where n is the amount of nodes. # the amount of LRT stations in punggol is negligible, so performance isn't a big issue. # to do - figure out how to make sure correct LRT route is taken for dijkstra print("|TEST| - Now taking LRT from ", closestStartLrt, " to ", closestEndLrt[1]) print("|TEST| - LRT route: ", lrtRoute) lrtRouteYX = getRouteInYX(lrt_graph, lrtRoute) print("|TEST| - LRT route in XY (returns this): ", lrtRouteYX) # CURRENT LAYER: lrt stations # user has now ARRIVED at the lrt node. # we want to now bring the user to the closest foot path # most LRTs have a 'bridge' that connects to ground level via stairs/bridges # greedily find the closest bridge-end/stairs to the LRT # if distance() shows that the bridge is too far, (e.g Sam Kee station has no bridges) # it's not considered to be an immediately linked bridge. # but if it is, # then add XY to the paths array. exit = ox.get_nearest_node(lrt_exits, (endLRTXY[1], endLRTXY[0])) exitXY = (lrt_exits.nodes[exit]['x'], lrt_exits.nodes[exit]['y']) # after this, the user will be ready to start walking towards their destination if distance(exitXY, (endLRTXY)) > 100: # too far. just use current XY as last stop. print("|TEST| - Exit of ", exitXY, " is too far ,", distance(exitXY, (endLRTXY)), " disregarding exit.") return lrtRouteYX else: # use the exit as the last XY for routing purposes. flips exitXY to match the program. lrtRouteYX.append((exitXY[1], exitXY[0])) print("|TEST| - Adding X,Y of exit ", (exitXY[1], exitXY[0]), " to LRT route.") return lrtRouteYX
def load_PEMS(num_train=250, dtype=np.float64): #unzip daata with zipfile.ZipFile('data/PEMS.zip', 'r') as zip_ref: zip_ref.extractall('data') # Data reading with open('data/PEMS/adj_mx_bay.pkl', 'rb') as f: sensor_ids, sensor_id_to_ind, _ = pickle.load(f, encoding='latin1') all_signals = pd.read_hdf('data/PEMS/pems-bay.h5') coords = pd.read_csv('data/PEMS/graph_sensor_locations_bay.csv', header=None) # Loading real world graph of roads north, south, east, west = 37.450, 37.210, -121.80, -122.10 if not os.path.isfile('data/PEMS/bay_graph.pkl'): cf = '["highway"~"motorway|motorway_link"]' # Road filter, we don't use small ones. G = osmnx.graph_from_bbox(north=north, south=south, east=east, west=west, simplify=True, custom_filter=cf) with open( 'data/PEMS/bay_graph.pkl', 'wb') as f: # frequent loading of maps leads to a temporal ban pickle.dump(G, f) else: with open('data/PEMS/bay_graph.pkl', 'rb') as f: G = pickle.load(f) G = osmnx.get_undirected(G) # Matern GP supports only undirected graphs. # Graph cleaning up for _ in range(2): out_degree = G.degree to_remove = [node for node in G.nodes if out_degree[node] == 1] G.remove_nodes_from(to_remove) G = nx.convert_node_labels_to_integers(G) G.remove_nodes_from([372, 286]) G = nx.convert_node_labels_to_integers(G) num_points = len(sensor_ids) np_coords = np.zeros((num_points, 2)) # Vector of sensors coordinates. for i in range(num_points): sensor_id, x, y = coords.iloc[i] ind = sensor_id_to_ind[str(int(sensor_id))] np_coords[ind][0], np_coords[ind][1] = x, y coords = np_coords sensor_ind_to_node = {} # Inserting sensors into a graph. During insertion, the edge containing the sensor is cut for point_id in range(num_points): sensor_ind_to_node[point_id] = len(G) # adding new vertex at the end sensor_point = Point(coords[point_id, 1], coords[point_id, 0]) u, v, key, geom = osmnx.get_nearest_edge( G, (sensor_point.y, sensor_point.x), return_geom=True) edge = G.edges[(u, v, key)] G.remove_edge(u, v, key) edge_1_geom, edge_2_geom = cut(geom, geom.project(sensor_point)) l_ratio = geom.project(sensor_point, normalized=True) l_1, l_2 = l_ratio * edge['length'], (1 - l_ratio) * edge['length'] new_vertex = nearest_points(geom, sensor_point)[0] G.add_node(len(G), x=new_vertex.x, y=new_vertex.y) G.add_edge(u, len(G) - 1, length=l_1, geometry=edge_1_geom) G.add_edge(len(G) - 1, v, length=l_2, geometry=edge_2_geom) # Weights are inversely proportional to the length of the road lengths = nx.get_edge_attributes(G, 'length') lengths_list = [length for length in lengths.values()] mean_length = np.mean(lengths_list) weights = {} for edge, length in lengths.items(): weights[edge] = mean_length / length nx.set_edge_attributes(G, values=weights, name='weight') # Sorry for that, # sensor_ind - sensor id in California database, sensor_id - local numeration (from 1 to num of sensors) sensor_id_to_node = {} for sensor_ind, node in sensor_ind_to_node.items(): sensor_id = sensor_ids[sensor_ind] sensor_id_to_node[sensor_id] = node # Selecting signals at some moment signals = all_signals[(all_signals.index.weekday == 0) & (all_signals.index.hour == 17) & (all_signals.index.minute == 30)] # Dataset creation x, y = [], [] for i in range(len(signals)): for sensor_id in sensor_ids: if sensor_id_to_node.get(sensor_id) is not None: node = sensor_id_to_node[sensor_id] signal = signals.iloc[i][int(sensor_id)] x.append([i, node]) y.append([signal]) x, y = np.asarray(x, dtype=dtype), np.asarray(y, dtype=dtype) x, y = x[:num_points, 1:], y[:num_points] # Splitting data into train and test random_perm = np.random.permutation(np.arange(x.shape[0])) train_vertex, test_vertex = random_perm[:num_train], random_perm[ num_train:] x_train, x_test = x[train_vertex], x[test_vertex] y_train, y_test = y[train_vertex], y[test_vertex] return G, (x_train, y_train), (x_test, y_test), (x, y)