def generate_k_routes_from_clicks(self, k): G = self._map fig, ax = ox.plot_graph(G, figsize=(8, 8), bgcolor='white', edge_color='black', edge_linewidth=0.5, show=False) fig.suptitle( "Press X while hovering desired nodes in order of (orig, dest).") self._temp_nodes = [] def append_two_nodes_onclick(event): nodes = self._temp_nodes if event.key == "x" or event.key == "X": x, y = (event.ydata, event.xdata) node = ox.nearest_nodes(G, y, x) nodes.append(node) elif event.key != "q" and event.key != "Q": raise Exception("Press X when selecting nodes. Try again") if len(nodes) == 2: plt.close() cid = fig.canvas.mpl_connect('key_press_event', append_two_nodes_onclick) plt.show() try: routes = list(ox.k_shortest_paths(G, *self._temp_nodes, k)) except: routes = None raise Exception("No valid routes between two nodes") if routes and len(routes) > 1: return routes elif routes and len(routes) == 1: return routes[0]
def get_path(self, G, start, end, limit_ratio, weight='length', inverse=False): ''' Return the path with certain constraint Parameters: G : map graph object start (float tuple): coordinate for the start point end (float tuple): coordinate for the end point limit_ratio (float): the length restriction weight (str): path type inverse (bool): switch between maximum and minimum ''' # transfer node coordinates to node ids if type(start) is not np.int64: start = ox.get_nearest_node(G, start) end = ox.get_nearest_node(G, end) # calculate shortest path sp = ox.shortest_path(G, start, end, weight='length') sp_len = self.get_weight_sum(G, sp, 'length') sp_grad = self.get_weight_sum(G, sp, 'grade_abs') # print('shortest path: ') # print(" length: ", sp_len) # print(" height: ", sp_grad) path = None if weight == 'length' and inverse is False: path = sp else: if weight == 'height': weight = 'grade_abs' if not inverse else 'inv_grade_abs' path_gen = ox.k_shortest_paths(G, start, end, self._timeout, weight=weight) cnt = 0 for pth in path_gen: cnt += 1 if self.get_weight_sum(G, pth, 'length') > limit_ratio * sp_len: continue path = pth # print(cnt) # print("limit_ratio:", limit_ratio) # print("sp_len", sp_len) # print("sp_len * limit_ratio", limit_ratio * sp_len) # print("now length", self.get_weight_sum(G, pth, 'length')) # print('find path under constraint:') # print(" length: ", self.get_weight_sum(G, path, 'length')) # print(" height: ", self.get_weight_sum(G, path, 'grade_abs')) break path_length = self.get_weight_sum(G, path, 'length') path_elevation_gain = self.get_weight_sum(G, path, 'grade_abs') coords = [] for node in path: coords.append((G.nodes[node]['x'], G.nodes[node]['y'])) return path, coords, int(path_length), int(path_elevation_gain), int(sp_len), int(sp_grad)
def test_routing(): G = ox.graph_from_address(address=address, dist=500, dist_type="bbox", network_type="bike") # give each edge speed and travel time attributes G = ox.add_edge_speeds(G) G = ox.add_edge_speeds(G, hwy_speeds={"motorway": 100}) G = ox.add_edge_travel_times(G) orig_x = np.array([-122.404771]) dest_x = np.array([-122.401429]) orig_y = np.array([37.794302]) dest_y = np.array([37.794987]) orig_node = ox.distance.nearest_nodes(G, orig_x, orig_y)[0] dest_node = ox.distance.nearest_nodes(G, dest_x, dest_y)[0] route = ox.shortest_path(G, orig_node, dest_node, weight="travel_time") attributes = ox.utils_graph.get_route_edge_attributes(G, route) attributes = ox.utils_graph.get_route_edge_attributes( G, route, "travel_time") fig, ax = ox.plot_graph_route(G, route, save=True) # test multiple origins-destinations n = 5 nodes = np.array(G.nodes) origs = np.random.choice(nodes, size=n, replace=True) dests = np.random.choice(nodes, size=n, replace=True) paths1 = ox.shortest_path(G, origs, dests, weight="length", cpus=1) paths2 = ox.shortest_path(G, origs, dests, weight="length", cpus=2) paths3 = ox.shortest_path(G, origs, dests, weight="length", cpus=None) assert paths1 == paths2 == paths3 # test k shortest paths routes = ox.k_shortest_paths(G, orig_node, dest_node, k=2, weight="travel_time") fig, ax = ox.plot_graph_routes(G, list(routes)) # test folium with keyword arguments to pass to folium.PolyLine gm = ox.plot_graph_folium(G, popup_attribute="name", color="#333333", weight=5, opacity=0.7) rm = ox.plot_route_folium(G, route, color="#cc0000", weight=5, opacity=0.7) # test calling folium plotters with FeatureGroup instead of Map, and extra kwargs fg = folium.FeatureGroup(name="legend name", show=True) gm = ox.plot_graph_folium(G, graph_map=fg) assert isinstance(gm, folium.FeatureGroup) rm = ox.plot_route_folium(G, route, route_map=fg, tooltip="x") assert isinstance(rm, folium.FeatureGroup)
def test_routing(): G = ox.graph_from_address(address=address, dist=500, dist_type="bbox", network_type="bike") # give each node a random elevation then calculate edge grades randm = np.random.random(size=len(G)) elevs = {n: e for n, e in zip(G.nodes(), randm)} nx.set_node_attributes(G, name="elevation", values=elevs) G = ox.add_edge_grades(G, add_absolute=True) # give each edge speed and travel time attributes G = ox.add_edge_speeds(G) G = ox.add_edge_speeds(G, hwy_speeds={"motorway": 100}) G = ox.add_edge_travel_times(G) orig_node = list(G.nodes())[5] dest_node = list(G.nodes())[-5] orig_pt = (G.nodes[orig_node]["y"], G.nodes[orig_node]["x"]) dest_pt = (G.nodes[dest_node]["y"], G.nodes[dest_node]["x"]) route = ox.shortest_path(G, orig_node, dest_node, weight="travel_time") attributes = ox.utils_graph.get_route_edge_attributes(G, route) attributes = ox.utils_graph.get_route_edge_attributes( G, route, "travel_time") fig, ax = ox.plot_graph_route(G, route, save=True) fig, ax = ox.plot_graph_route(G, route, save=True) # test multiple routes routes = ox.k_shortest_paths(G, orig_node, dest_node, k=2, weight="travel_time") fig, ax = ox.plot_graph_routes(G, list(routes)) # test folium with keyword arguments to pass to folium.PolyLine gm = ox.plot_graph_folium(G, popup_attribute="name", color="#333333", weight=5, opacity=0.7) rm = ox.plot_route_folium(G, route, color="#cc0000", weight=5, opacity=0.7) # test calling folium plotters with FeatureGroup instead of Map, and extra kwargs fg = folium.FeatureGroup(name="legend name", show=True) gm = ox.plot_graph_folium(G, graph_map=fg) assert isinstance(gm, folium.FeatureGroup) rm = ox.plot_route_folium(G, route, route_map=fg, tooltip="x") assert isinstance(rm, folium.FeatureGroup)
def generate_k_routes_from_origin_to_dest(self, k, origin, dest): G = self._map try: routes = list(ox.k_shortest_paths(G, origin, dest, k)) except: routes = None raise Exception("No valid routes between two nodes") if routes and len(routes) > 1: return routes elif routes and len(routes) == 1: return routes[0]
def generate_k_routes_from_random_nodes(self, k, seed=123): rng = np.random.default_rng(seed=seed) G = self._map high = len(G.nodes()) #max index for node start_idx, dest_idx = rng.integers(low=0, high=high, size=2) start, dest = (list(G.nodes())[start_idx], list(G.nodes())[dest_idx]) try: routes = list(ox.k_shortest_paths(G, start, dest, k)) except: routes = None raise Exception("No valid routes between two nodes") if routes and len(routes) > 1: return routes elif routes and len(routes) == 1: return routes[0]
def generate_routes(G, origin_destination, no_routes): """Generate "no_routes" number of routes from origin, destiniation node of G Args: G (NetworkX Graph): the NetworkX graph of the map of the traffic routings origin_destination (tuple): (origin node, destination node) [Both nodes must be in G.nodes()] no_routes (int): number of routes to generate from origin to destination node Returns: [type]: [description] """ orig, dest = origin_destination try: routes = list( ox.k_shortest_paths(G, orig, dest, k=no_routes * 3, weight="length")) routes = [routes[3 * k] for k in range(no_routes)] return routes except Exception: # for unsolvable routes (due to directed graph perimeter effects) return None