def print_route_stats(route): route_grades = ox.get_route_edge_attributes(G_proj, route, 'grade_abs') msg = 'The average grade is {:.1f}% and the max is {:.1f}%' print(msg.format(np.mean(route_grades)*100, np.max(route_grades)*100)) route_rises = ox.get_route_edge_attributes(G_proj, route, 'rise') ascent = np.sum([rise for rise in route_rises if rise >= 0]) descent = np.sum([rise for rise in route_rises if rise < 0]) msg = 'Total elevation change is {:.0f} meters: a {:.0f} meter ascent and a {:.0f} meter descent' print(msg.format(np.sum(route_rises), ascent, abs(descent))) route_lengths = ox.get_route_edge_attributes(G_proj, route, 'length') print('Total trip distance: {:,.0f} meters'.format(np.sum(route_lengths)))
def test_routing_folium(): # calculate shortest path and plot as static image and leaflet web map import networkx as nx G = ox.graph_from_address('398 N. Sicily Pl., Chandler, Arizona', distance=800, network_type='drive') origin = (33.307792, -111.894940) destination = (33.312994, -111.894998) origin_node = ox.get_nearest_node(G, origin) destination_node = ox.get_nearest_node(G, destination, method='euclidean') route = nx.shortest_path(G, origin_node, destination_node) attributes = ox.get_route_edge_attributes(G, route, 'length') fig, ax = ox.plot_graph_route(G, route, save=True, filename='route', file_format='png') fig, ax = ox.plot_graph_route(G, route, origin_point=origin, destination_point=destination, save=True, filename='route', file_format='png') graph_map = ox.plot_graph_folium(G, popup_attribute='name') route_map = ox.plot_route_folium(G, route)
def test_routing_folium(): import networkx as nx with httmock.HTTMock( get_mock_response_content('overpass-response-3.json.gz')): G = ox.graph_from_address('398 N. Sicily Pl., Chandler, Arizona', distance=800, network_type='drive') origin = (33.307792, -111.894940) destination = (33.312994, -111.894998) origin_node = ox.get_nearest_node(G, origin) destination_node = ox.get_nearest_node(G, destination) route = nx.shortest_path(G, origin_node, destination_node) attributes = ox.get_route_edge_attributes(G, route, 'length') fig, ax = ox.plot_graph_route(G, route, save=True, filename='route', file_format='png') fig, ax = ox.plot_graph_route(G, route, origin_point=origin, destination_point=destination, save=True, filename='route', file_format='png') graph_map = ox.plot_graph_folium(G, popup_attribute='name') route_map = ox.plot_route_folium(G, route)
def show_stats(self, graph_projection, route): route_lengths = ox.get_route_edge_attributes(graph_projection, route, 'length') print('Total trip distance: {:,.0f} meters'.format( self.controller.get_total_length(graph_projection, route))) print('Total elevation change: {:,.0f}'.format( self.controller.get_total_elevation(graph_projection, route)))
def getRouteLength(self, route): return round( sum( ox.get_route_edge_attributes(self.G, route, attribute='length', minimize_key='length', retrieve_default=None)), 3)
def geometry_distance(gdf1, gdf2): # get_name s_name = gdf1['addr:housenumber'][gdf1.index[0]] + " " + gdf1['addr:street'][gdf1.index[0]]\ + ", " + gdf1['addr:city'][gdf1.index[0]] + ", " + gdf1['addr:state'][gdf1.index[0]] t_name = gdf2['addr:housenumber'][gdf2.index[0]] + " " + gdf2['addr:street'][gdf2.index[0]]\ + ", " + gdf2['addr:city'][gdf2.index[0]] + ", " + gdf2['addr:state'][gdf2.index[0]] #s = ox.core.graph_from_address(s_name, distance = 100,return_coords=True)[1] # return (lat,log) #t = ox.core.graph_from_address(t_name, distance = 100,return_coords=True)[1] # return (lat,log) s = ox.utils.geocode(s_name) # return (lat,log) t = ox.utils.geocode(t_name) # return (lat,log) s_node, s_dis = find_nearest_point(s) # distance in meters t_node, t_dis = find_nearest_point(t) # distance in meters if s_node == t_node: print min(s_dis + t_dis, distance_OSMNX(s, t)) return min(s_dis + t_dis, distance_OSMNX(s, t)) else: # ini route_by_length = \ nx.shortest_path(G_proj, source=s_node, target=t_node, weight='length') # nodes set #fig, ax = ox.plot_graph_route(G_proj, route_by_length, node_size=0) route_lengths = ox.get_route_edge_attributes(G_proj, route_by_length, 'length') # meters set distance = sum(route_lengths) # meter if distance - s_dis - t_dis > 150: return 150 # s else: if G[route_by_length[0]][route_by_length[1]][0].get('name') != None and \ G[route_by_length[0]][route_by_length[1]][0]['name'] != gdf1['addr:street'][gdf1.index[0]]: distance = distance + s_dis elif distance_OSMNX( s, (nodes['y'][route_by_length[1]], nodes['x'][route_by_length[1]])) <= route_lengths[0]: distance = distance - s_dis else: distance = distance + s_dis # t if G[route_by_length[-1]][route_by_length[-2]][0].get('name') != None and \ G[route_by_length[-2]][route_by_length[-1]][0]['name'] != gdf2['addr:street'][gdf2.index[0]]: distance = distance + t_dis elif distance_OSMNX( t, (nodes['y'][route_by_length[-2]], nodes['x'][route_by_length[1]])) <= route_lengths[-1]: distance = distance - t_dis else: distance = distance + t_dis print distance return distance #, fig, ax
def shortest_path(self, start_location, end_location, x, algo="dijkstra", mode="maximize"): G = self.G self.x = x / 100.0 self.mode = mode self.start_node, self.end_node = None, None #[path, totalDist, totalElevGain, totalElevDrop] self.best = [[], 0.0, float('-inf'), float('-inf')] #get shortest path self.start_node, d1 = ox.get_nearest_node(G, point=start_location, return_dist=True) self.end_node, d2 = ox.get_nearest_node(G, point=end_location, return_dist=True) if d1 > 100 or d2 > 100: print("Nodes too far") return None, None self.shortest_route = nx.shortest_path(G, source=self.start_node, target=self.end_node, weight='length') self.shortest_dist = sum( ox.get_route_edge_attributes(G, self.shortest_route, 'length')) if algo == "dfs": print("dfs") self.dfs(self.start_node, self.end_node) elif algo == "astar": print("astar") self.a_star() print("dijkstra") self.all_dijkstra() shortest_route_latlong = [[ G.node[route_node]['x'], G.node[route_node]['y'] ] for route_node in self.shortest_route] shortestPathStats = [shortest_route_latlong, self.shortest_dist, \ self.computeElevs(self.shortest_route, "gain-only"), self.computeElevs(self.shortest_route, "drop-only")] if (self.mode == "maximize" and self.best[2] == float('-inf')) or ( self.mode == "minimize" and self.best[3] == float('-inf')): return shortestPathStats, [[], 0.0, 0, 0] self.create_elevation_profile() # print(self.best) self.best[0] = [[G.node[route_node]['x'], G.node[route_node]['y']] for route_node in self.best[0]] # print("===>end", self.best[1:]) return shortestPathStats, self.best
def _get_all_leg_lengths(self, route): """This function all the individual leg lengths of the route Args: route (dict): Data of route Returns: all_leg_lengths (list): Lengths of the legs of the route """ all_leg_lengths = ox.get_route_edge_attributes(self.graph, route, 'length') return all_leg_lengths
def _get_route_elevation_information(self, route): """This function gets the elevation information (rise, ascent, descent) of the route Args: route (dict): Data of route Returns: route_elevation (dict): Elevation of the route """ route_elevation = dict() route_rises = ox.get_route_edge_attributes(self.graph, route, 'rise') ascent = np.sum([rise for rise in route_rises if rise >= 0]) descent = np.sum([rise for rise in route_rises if rise < 0]) route_elevation['rises'] = np.sum(route_rises) route_elevation['ascent'] = ascent route_elevation['descent'] = abs(descent) return route_elevation
def _get_route_grade_information(self, route): """This function gets the grade information of the route Args: route (dict): Data of route Returns: route_grades (dict): Grades of the route """ route_grades = dict() grades = ox.get_route_edge_attributes(self.graph, route, 'grade') grades = [float(i) for i in grades] grades_mean = np.mean(grades) * 100 grades_max = np.max(grades) * 100 grades_total = np.sum(grades) route_grades['grades_list'] = grades route_grades['grades_mean'] = grades_mean route_grades['grades_max'] = grades_max route_grades['grades_total'] = grades_total return route_grades
def test_routing_folium(): # calculate shortest path and plot as static image and leaflet web map import networkx as nx G = ox.graph_from_address('398 N. Sicily Pl., Chandler, Arizona', distance=800, network_type='drive') origin = (33.307792, -111.894940) destination = (33.312994, -111.894998) origin_node = ox.get_nearest_node(G, origin) destination_node = ox.get_nearest_node(G, destination, method='euclidean') route = nx.shortest_path(G, origin_node, destination_node) attributes = ox.get_route_edge_attributes(G, route, 'length') fig, ax = ox.plot_graph_route(G, route, save=True, filename='route', file_format='png') fig, ax = ox.plot_graph_route(G, route, origin_point=origin, destination_point=destination, save=True, filename='route', file_format='png') # test multiple routes fig, ax = ox.plot_graph_routes(G, [route, route]) graph_map = ox.plot_graph_folium(G, popup_attribute='name') route_map = ox.plot_route_folium(G, route)
def a_star(self, start_location, end_location): """ Returns the route(list of nodes) that minimize change in elevation between start and end using the A* node, with the heuristic being the distance from the end node. Params: start_location: tuple (lat,long) end_location: tuple (lat,long) Returns: lat_longs: List of [lon,lat] in the route """ if not self.init: # bbox=self.get_bounding_box(start_location,end_location) # self.G = ox.graph_from_bbox(bbox[0],bbox[1],bbox[2],bbox[3],network_type='walk', simplify=False) self.G = ox.graph_from_point(start_location, distance=10000, simplify=False, network_type='walk') p.dump(self.G, open("graph.p", "wb")) self.init = True print("Saved Graph") G = self.G #Graph initialization bbox = self.get_bounding_box(start_location, end_location) G = self.get_graph_with_elevation(bbox) G = self.add_dist_from_dest(G, end_location) #Initialization of pre-reqs start_node = ox.get_nearest_node(G, point=start_location) end_node = ox.get_nearest_node(G, point=end_location) shortest_route = nx.shortest_path(G, source=start_node, target=end_node, weight='length') shortest_dist = sum( ox.get_route_edge_attributes(G, shortest_route, 'length')) def reconstruct_path(cameFrom, current): """ Function to retrace the path from end node to start node. Returns in the format required by Mapbox API(for plotting) """ total_path = [current] while current in cameFrom: current = cameFrom[current] total_path.append(current) ele_latlong = [[G.node[route_node]['x'], G.node[route_node]['y']] for route_node in total_path] shortest_latlong = [[ G.node[route_node]['x'], G.node[route_node]['y'] ] for route_node in shortest_route] return (ele_latlong, shortest_latlong) #The settotal_path of nodes already evaluated closedSet = set() # The set of currently discovered nodes that are not evaluated yet. # Initially, only the start node is known. openSet = set() openSet.add(start_node) # For each node, which node it can most efficiently be reached from. # If a node can be reached from many nodes, cameFrom will eventually contain the # most efficient previous step. cameFrom = {} #For each node, the cost of getting from the start node to that node. gScore = {} for node in G.nodes(): gScore[node] = float("inf") #The cost of going from start to start is zero. gScore[start_node] = 0 # For each node, the total cost of getting from the start node to the goal # by passing by that node. That value is partly known, partly heuristic. fScore = {} # For the first node, that value is completely heuristic. fScore[start_node] = 0 #G.nodes[start_node]['dist_from_dest'] while openSet != {}: current = min([(node, fScore[node]) for node in openSet], key=lambda t: t[1])[0] if current == end_node: return reconstruct_path(cameFrom, current) openSet.remove(current) closedSet.add(current) for neighbor in G.neighbors(current): if neighbor in closedSet: continue # Ignore the neighbor which is already evaluated. #The distance from start to a neighbor tentative_gScore = gScore[current] + 1 / abs( G.nodes[current]['elevation'] - G.nodes[neighbor]['elevation']) if neighbor not in openSet: # Discover a new node openSet.add(neighbor) else: if tentative_gScore >= gScore[ neighbor]: #Stop searching along this path if distance exceed 1.5 times shortest path continue # This is not a better path. cameFrom[neighbor] = current gScore[neighbor] = tentative_gScore fScore[neighbor] = gScore[ neighbor] # + G.nodes[neighbor]['dist_from_dest'] # r.get_shortest_path((42.377041, -72.519681),(42.350070, -72.528798)) # print(r.a_star((42.377041, -72.519681),(42.350070, -72.528798)))
def print_route_stats(route): route_lengths = ox.get_route_edge_attributes(G_proj, route, 'impedance') print('Total trip fuel consumption: {:,.0f} liters'.format( np.sum(route_lengths))) route_lengths = ox.get_route_edge_attributes(G_proj, route, 'length') print('Total trip distance: {:,.4f} meters'.format(np.sum(route_lengths)))
def get_shortest_path(self, startpt, endpt, x, elev_type="maximize", log=True): # Calculates shortest path G = self.G self.x = x / 100.0 self.elev_type = elev_type self.start_node, self.end_node = None, None #self.best = [path, totalDist, totalElevGain, totalElevDrop] if elev_type == "maximize": self.best = [[], 0.0, float('-inf'), float('-inf')] else: self.best = [[], 0.0, float('inf'), float('-inf')] #get shortest path self.start_node, d1 = ox.get_nearest_node(G, point=startpt, return_dist=True) self.end_node, d2 = ox.get_nearest_node(G, point=endpt, return_dist=True) # returns the shortest route from start to end based on distance self.shortest_route = nx.shortest_path(G, source=self.start_node, target=self.end_node, weight='length') # ox.get_route function returns list of edge length for above route self.shortest_dist = sum( ox.get_route_edge_attributes(G, self.shortest_route, 'length')) shortest_route_latlong = [[ G.nodes[route_node]['x'], G.nodes[route_node]['y'] ] for route_node in self.shortest_route] shortestPathStats = [shortest_route_latlong, self.shortest_dist, \ self.get_Elevation(self.shortest_route, "elevation_gain"), self.get_Elevation(self.shortest_route, "elevation_drop")] if (x == 0): return shortestPathStats, shortestPathStats start_time = time.time() self.dijkstra() end_time = time.time() dijkstra_route = self.best if log: print() print("Dijkstra route statistics") print(dijkstra_route[1]) print(dijkstra_route[2]) print(dijkstra_route[3]) print("--- Time taken = %s seconds ---" % (end_time - start_time)) if elev_type == "maximize": self.best = [[], 0.0, float('-inf'), float('-inf')] else: self.best = [[], 0.0, float('inf'), float('-inf')] start_time = time.time() self.a_star() end_time = time.time() a_star_route = self.best if log: print() print("A star route statistics") print(a_star_route[1]) print(a_star_route[2]) print(a_star_route[3]) print("--- Time taken = %s seconds ---" % (end_time - start_time)) print() if self.elev_type == "maximize": if (dijkstra_route[2] > a_star_route[2]) or ( dijkstra_route[2] == a_star_route[2] and dijkstra_route[1] < a_star_route[1]): self.best = dijkstra_route if log: print("Dijkstra chosen as best route") print() else: self.best = a_star_route if log: print("A star chosen as best route") print() else: if (dijkstra_route[2] < a_star_route[2]) or ( dijkstra_route[2] == a_star_route[2] and dijkstra_route[1] < a_star_route[1]): self.best = dijkstra_route if log: print("Dijkstra chosen as best route") print() else: self.best = a_star_route if log: print("A star chosen as best route") print() # If dijkstra or A-star doesn't return a shortest path based on elevation requirements if (self.elev_type == "maximize" and self.best[2] == float('-inf')) or (self.elev_type == "minimize" and self.best[3] == float('-inf')): return shortestPathStats, [[], 0.0, 0, 0] self.best[0] = [[G.nodes[route_node]['x'], G.nodes[route_node]['y']] for route_node in self.best[0]] # If the elevation path does not match the elevation requirements if ((self.elev_type == "maximize" and self.best[2] < shortestPathStats[2]) or (self.elev_type == "minimize" and self.best[2] > shortestPathStats[2])): self.best = shortestPathStats return shortestPathStats, self.best
def calculateWeight(self): weigetDict = {} for i in range(0, 2): for j in range(0, 2): for edge in self.G.edges(): u, v = edge d = ox.get_route_edge_attributes(self.G, [u, v], attribute=None, minimize_key='length', retrieve_default=None) length = d[0]['length'] a = d[0] if 'maxspeed' not in a: d[0]['maxspeed'] = '50 mph' ret = re.findall(r'[0-9]+\.?[0-9]*', d[0]['maxspeed']) if len(ret) == 0: maxspeedNum = 50 else: maxspeedNum = float(ret[0]) highway = 0 # default value if 'highway' in a: if isinstance(a['highway'], list): a['highway'] = a['highway'][0] if isinstance(a['highway'], str): if a['highway'] in self.highwayWeight[i]: highway = self.highwayWeight[i][a['highway']] maxspeed = self.maxspeedWeight[j] * maxspeedNum weight = length * (1 + maxspeed * 0.5 + highway * 0.5) if weight < 0: weight = 0 weigetDict[(u, v, 0)] = weight nx.set_edge_attributes(self.G, weigetDict, 'type%d' % (j * 2 + i)) if self.columsLen > 10: for edge in self.G.edges(): u, v = edge d = ox.get_route_edge_attributes(self.G, [u, v], attribute=None, minimize_key='length', retrieve_default=None) length = d[0]['length'] a = d[0] if 'maxspeed' not in a: d[0]['maxspeed'] = '50 mph' ret = re.findall(r'[0-9]+\.?[0-9]*', d[0]['maxspeed']) if len(ret) == 0: maxspeedNum = 50 else: maxspeedNum = float(ret[0]) highway = 0 # default value if 'highway' in a: if isinstance(a['highway'], list): a['highway'] = a['highway'][0] if isinstance(a['highway'], str): if a['highway'] in self.wayPreference: highway = self.wayPreference[a['highway']] maxspeed = self.speedPreference * maxspeedNum weight = length * (1 + maxspeed * 0.5 + highway * 0.5) if weight < 0: weight = 0 weigetDict[(u, v, 0)] = weight nx.set_edge_attributes(self.G, weigetDict, 'type10')
def print_route_stats(G_proj, route): route_lengths = ox.get_route_edge_attributes(G_proj, route, 'length') print('Total trip distance: {:,.0f} meters'.format( getTotalLength(G_proj, route))) print('Total elevation change: {:,.0f}'.format( getTotalElevation(G_proj, route)))
def shortest_path(self, start_location, end_location, x, algo="dijkstra", mode="maximize", log=True): """ Function to calculate the shortest path between the start_location and end_location. Params: start_location : tuple (lat, lng) end_location : tuple (lat, lng) x : how much more can we go above the shortest distance algo : the algorithm to use for finding the specific path (dfs/astar/dijkstra) mode : minimize/maximize elevation log : log the results as the function runs Returns: L1, L2 both list contain four items : [best route found, total distance between the start and ending nodes of the best route, total positive change in elevation, total negative change in elevation ] L1 returns the statistics for the shortest path while L2 returns the statistics for the path considering elevation If we are going from node "1" to node "2" : total positive change in elevation : (max(0, elev("2") - elev("1")) total negative change in elevation : (max(0, elev("1") - elev("2")) If the start_location, end_location are outside the defined graph, L1 and L2 will be None. L2 will be None incase no route is found by our custom algorithms. """ G = self.G self.x = x / 100.0 self.mode = mode self.start_node, self.end_node = None, None #[path, totalDist, totalElevGain, totalElevDrop] if mode == "maximize": self.best = [[], 0.0, float('-inf'), float('-inf')] else: self.best = [[], 0.0, float('inf'), float('-inf')] #get shortest path self.start_node, d1 = ox.get_nearest_node(G, point=start_location, return_dist=True) self.end_node, d2 = ox.get_nearest_node(G, point=end_location, return_dist=True) if d1 > 100 or d2 > 100: if log: print("Nodes too far") return None, None self.shortest_route = nx.shortest_path(G, source=self.start_node, target=self.end_node, weight='length') self.shortest_dist = sum( ox.get_route_edge_attributes(G, self.shortest_route, 'length')) if algo == "dfs": if log: print("dfs") self.dfs(self.start_node, self.end_node) elif algo == "astar" or mode == "minimize": if log: print("astar") self.a_star() if log: print("dijkstra") self.all_dijkstra() shortest_route_latlong = [[ G.node[route_node]['x'], G.node[route_node]['y'] ] for route_node in self.shortest_route] shortestPathStats = [shortest_route_latlong, self.shortest_dist, \ self.computeElevs(self.shortest_route, "gain-only"), self.computeElevs(self.shortest_route, "drop-only")] if (self.mode == "maximize" and self.best[2] == float('-inf')) or ( self.mode == "minimize" and self.best[3] == float('-inf')): return shortestPathStats, [[], 0.0, 0, 0] self.create_elevation_profile() # print(self.best) self.best[0] = [[G.node[route_node]['x'], G.node[route_node]['y']] for route_node in self.best[0]] # print("===>end", self.best[1:]) return shortestPathStats, self.best
def get_path_length(self, path): """Get length of each edge of path. (meters)""" return ox.get_route_edge_attributes(self.graph, path, 'length')
###now start calculating distances in a forloop! total_rows = treasure.shape[0] #total_rows = total_rows-1 total_columns = len(treasure.columns) #print(treasure) for tt in range(0,total_columns): xstart = result.iat[tt,1] ystart = result.iat[tt,2] origin = ox.get_nearest_node(B, (xstart, ystart)) xend = u.iat[0,1] yend = u.iat[0,2] destination = ox.get_nearest_node(B, (xend, yend)) route = nx.shortest_path(B_proj, source=origin, target=destination, weight='length') route_lengths = ox.get_route_edge_attributes(B_proj, route, 'length') gg = np.sum(route_lengths) treasure.iat[0,tt] = gg counter = 0 rowz = rows_in_park_IDs - 1 for jiber in range(1,rowz): if (u.iat[jiber,0] == u.iat[jiber-1,0]): for tt in range(0,total_columns): xstart = result.iat[tt,1] ystart = result.iat[tt,2] origin = ox.get_nearest_node(B, (xstart, ystart)) xend = u.iat[jiber,1]
# In[48]: ''' Create a geodataframe to store all the results''' ''' Including all the elevation information ''' route_geom = gpd.GeoDataFrame(crs=edges_proj.crs) route_geom['geometry'] = None route_geom['osmids'] = None for i in range(len(routes)): route_nodes = nodes_proj.loc[routes[i]] route_line = LineString(list(route_nodes.geometry.values)) route_geom.loc[i, 'geometry'] = route_line route_geom.loc[i, 'osmids'] = str(list(route_nodes['osmid'].values)) # Get the slope information try: route_grades = ox.get_route_edge_attributes(graph_proj, routes[i], 'grade_abs') route_geom.loc[i, 'avg_grade (%)'] = np.mean(route_grades) * 100 route_geom.loc[i, 'max_grade (%)'] = np.max(route_grades) * 100 route_geom.loc[i, 'min_grade (%)'] = np.min(route_grades) * 100 except: route_geom.loc[i, 'avg_grade (%)'] = np.NaN route_geom.loc[i, 'max_grade (%)'] = np.NaN route_geom.loc[i, 'min_grade (%)'] = np.NaN # Get the rises try: route_rises = ox.get_route_edge_attributes(graph_proj, routes[i], 'rise') ascent = np.sum([rise for rise in route_rises if rise >= 0]) descent = np.sum([rise for rise in route_rises if rise < 0]) route_geom.loc[i, 'tol_elevation change (m)'] = np.sum(route_rises)