def get_map_data_with_elevation(self, city_name, key): # get model data from osmnx of 2d and elevation #city_name = 'Amherst' # 'Springfield' place_query = { 'city': city_name, 'state': 'Massachusetts', 'country': 'USA' } graph_orig = ox.graph_from_place(place_query, network_type='walk') #add Elevation data from GoogleMaps key = self.get_key() graph_orig = ox.add_node_elevations( graph_orig, api_key=key ) # 'AIzaSyDVqjj0iKq0eNNHlmslH4fjoFgRj7n-5gs') # from elevation graph_orig = ox.add_edge_grades(graph_orig) pkl.dump(graph_orig, open("data/" + city_name + "_city_graph.pkl", "wb")) #project map on to 2D space graph_project = ox.project_graph(graph_orig) pkl.dump(graph_project, open("data/" + city_name + "_city_graph_projected.pkl", "wb")) #print ("pkl: ", type(graph_orig)) return graph_project, graph_orig
def test_routing_folium(): 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_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 = nx.shortest_path(G, orig_node, dest_node, weight="travel_time") attributes = ox.utils_graph.get_route_edge_attributes( G, route, "travel_time") 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=orig_pt, destination_point=dest_pt, save=True, filename="route", file_format="png", ) # test multiple routes fig, ax = ox.plot_graph_routes(G, [route, route]) # test folium gm = ox.plot_graph_folium(G, popup_attribute="name") rm = ox.plot_route_folium(G, route) # 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_color="g", route_map=fg, tooltip="x") assert isinstance(rm, folium.FeatureGroup)
def _get_graph_not_memoized(latitude: float, longitude: float, radius: float, google_maps_api_key: str) -> igraph.Graph: # calculate extent of the graph radius_latlong = radius / 60 north_lat = latitude + radius_latlong south_lat = latitude - radius_latlong east_long = longitude + radius_latlong west_long = longitude - radius_latlong # download graph graph = osmnx.graph_from_bbox(north_lat, south_lat, east_long, west_long, network_type='walk') graph = osmnx.add_node_elevations(graph, api_key=google_maps_api_key) graph = osmnx.add_edge_grades(graph) # convert node labels graph = networkx.relabel.convert_node_labels_to_integers(graph) # populate igraph graph_ig = igraph.Graph(directed=True) graph_ig.add_vertices(list(graph.nodes())) graph_ig.add_edges(list(graph.edges())) for attr in ('osmid', 'x', 'y'): graph_ig.vs[attr] = list( networkx.get_node_attributes(graph, attr).values()) for attr in ('length', 'grade'): graph_ig.es[attr] = list( networkx.get_edge_attributes(graph, attr).values()) graph_ig.es['streetname'] = [ str(s) for s in networkx.get_edge_attributes(graph, 'name').values() ] return graph_ig
def render_graph(self): Graph = ox.graph_from_address(self.address, network_type='walk', distance=self.run_distance / 2) Graph = ox.add_node_elevations(Graph, api_key=self.api_key) Graph = ox.add_edge_grades(Graph) return Graph
def get_graph(): key = "<<put key here>>" place_query = ['Natick, Massachusetts, USA'] G = ox.graph_from_place(place_query, network_type='walk') G = ox.add_node_elevations(G, key) G = ox.add_edge_grades(G) # G_projected = ox.project_graph(G) ox.save_graphml(G, filename='natick.graphml') print("done")
def edge_grades(G): """ Adds the angle of the roads according to the elevation. :param G: NetworkX graph input graph :return: networkx.MultiDiGraph graph with edge grades attributes """ G = ox.add_edge_grades(G) return G
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 get_elevation(self,graph_orig, city_name, key): # get evelation data only key = self.get_key() graph_orig = ox.add_node_elevations(graph_orig, api_key=key) graph_orig = ox.add_edge_grades(graph_orig) pkl.dump(graph_orig, open("data/" + city_name+"_city_graph.pkl","wb")) #projecting map on to 2D space graph_project = ox.project_graph(graph_orig) pkl.dump(graph_project, open("data/" + city_name+"_city_graph_projected.pkl","wb")) return graph_project, graph_orig
def __init__(self): self.G = ox.graph_from_place( { 'city': 'Amherst', 'state': 'MA', 'country': 'USA' }, network_type='all_private') self.G = ox.elevation.add_node_elevations(self.G, settings.MAP_API_KEY, 350, 0.02, 3) self.G = ox.add_edge_grades(self.G) self.nodes = self.initiateGraph()
def get_edge_impedance(G, power=300, Ca=0.3, Cr=0.0032, speed_ceil=40, work_per_meter_floor=0): """ Alters the graph object adding work impedance for each of the graph's edges. Parameters ---------- G: networkx graph graph of the network power: float Constant power level in Watts. Ca: float Aerodynamical coefficient Cr: float Roller resistance coefficient speed_ceil: float the maximum speed for the cyclist work_per_meter_floor: float minimum work on the edge. Returns ------- None """ G = ox.add_edge_grades(G) for u, v, k, data in G.edges(keys=True, data=True): work, speed = impedance(data['length'], data['grade'], power=power, Ca=Ca, Cr=Cr, speed_ceil=speed_ceil, work_per_meter_floor=work_per_meter_floor) work_flat, speed_flat = impedance( data['length'], 0, power=power, Ca=Ca, Cr=.0032, speed_ceil=speed_ceil, work_per_meter_floor=work_per_meter_floor) data['time'] = data['length'] / speed data['work'] = work data['work_flat'] = work_flat data['time_flat'] = data['length'] / speed_flat data['work per meter'] = work / data['length']
def test_elevation(): G = ox.graph_from_address(address=address, dist=500, dist_type="bbox", network_type="bike") rasters = list(Path("tests/input_data").glob("elevation*.tif")) # add node elevations from a single raster file (some nodes will be null) G = ox.elevation.add_node_elevations_raster(G, rasters[0], cpus=1) # add node elevations from multiple raster files G = ox.elevation.add_node_elevations_raster(G, rasters) assert pd.notnull(pd.Series(dict(G.nodes(data="elevation")))).all() # add edge grades and their absolute values G = ox.add_edge_grades(G, add_absolute=True)
def get_map(place='Boston', key, new_place=False): if new_place == False: return pkl.load(open("graph_projected.pkl", "rb")), pkl.load(open("graph.pkl", "rb")) # Downloading Local map place_query = {'city': place, 'state': 'Massachusetts', 'country': 'USA'} graph_orig = ox.graph_from_place(place_query, network_type='drive') # Adding Elevation data from graph_origoogleMaps graph_orig = ox.add_node_elevations(graph_orig, api_key=key) graph_orig = ox.add_edge_grades(graph_orig) pkl.dump(graph_orig, open("graph.pkl", "wb")) # projecting map on to 2D space graph_projected = ox.project_graph(graph_orig) pkl.dump(graph_projected, open("graph_projected.pkl", "wb")) return graph_projected, graph_orig
def generateMap(self, city='Amherst', state='MA'): mapFileName = self.PklFileName % (city, state) mapFilePath = pathlib.Path(mapFileName) if mapFilePath.is_file(): return pkl.load(open(mapFileName, "rb")) else: params = dict() params['city'] = city params['state'] = state params['country'] = 'USA' # Osmnx to get the map graph = osmnx.graph_from_place(params, network_type='drive') graph = self.add_node_elevations_open(graph) graph = osmnx.add_edge_grades(graph) # Dump the file #self.generateGraphPlot(graph) pkl.dump(graph, open(mapFileName, "wb")) return graph
def get_map(place='San Francisco', newPlace=False): if newPlace == False: return pkl.load(open("graph_projected.pkl", "rb")), pkl.load(open("graph.pkl", "rb")) # Downloading Local map place_query = {'city': place, 'state': 'California', 'country': 'USA'} G = ox.graph_from_place(place_query, network_type='drive') # Adding Elevation data from GoogleMaps G = ox.add_node_elevations( G, api_key='AIzaSyDrIKxLj0P90vzCUJ_6huBSDxiq8wYo9LM') G = ox.add_edge_grades(G) pkl.dump(G, open("graph.pkl", "wb")) # projecting map on to 2D space G_proj = ox.project_graph(G) pkl.dump(G_proj, open("graph_projected.pkl", "wb")) return G_proj, G
def add_elevation_info(self, api_key=None): ''' update the elevation and grade information for nodes and edges Parameters: api_key (str): Google API key for the elevation information ''' if api_key is None: with open("api_key.txt", "r") as f: api_key = f.readline() self.G = ox.add_node_elevations(self.G, api_key=api_key) self.G = ox.add_edge_grades(self.G) for e in self.G.edges: # change grade from ratio to value self.G.edges[e]['grade_abs'] *= self.G.edges[e]['length'] # calculate inverse grade_abs for maximum elevation path self.G.edges[e]['inv_grade_abs'] = 1 / ( self.G.edges[e]['grade_abs'] + self._eps)
def get_map(city, state): file_name = "%s%s.pkl" % (city, state) projected_file_name = "%s%s_projected.pkl" % (city, state) projected_file_path = Path(projected_file_name) file_path = Path(file_name) if projected_file_path.is_file() and file_path.is_file(): return pkl.load(open(file_name, "rb")), pkl.load(open(projected_file_name, "rb")) else: query = {'city': city, 'state': state, 'country': 'USA'} graph = ox.graph_from_place(query, network_type='drive') graph = add_node_elevations_open(graph) graph = ox.add_edge_grades(graph) log(graph.nodes[5637885552]) pkl.dump(graph, open(file_name, "wb")) graph_proj = ox.project_graph(graph) pkl.dump(graph_proj, open(projected_file_name, "wb")) return graph, graph_proj
def get_map(city, state): file_name = "%s%s.pkl" % (city, state) projected_file_name = "%s%s_projected.pkl" % (city, state) projected_file_path = Path(projected_file_name) file_path = Path(file_name) if projected_file_path.is_file() and file_path.is_file(): graph = pkl.load(open(file_name, 'rb')) return pkl.load(open(file_name, "rb")), pkl.load(open(projected_file_name, "rb")) else: query = {'city': city, 'state': state, 'country': 'USA'} graph = ox.graph_from_place(query, network_type='bike') graph = ox.add_node_elevations(graph, "AIzaSyCPFbx7dhPoxlSRRN4okxhibuu0E_7DUWI") graph = ox.add_edge_grades(graph) pkl.dump(graph, open(file_name, "wb")) graph_proj = ox.project_graph(graph) pkl.dump(graph_proj, open(projected_file_name, "wb")) return graph, graph_proj
def populate_graph(location): """Returns a path from origin to destination taking elevation into account per the parameter 'weight' after generating model. Parameters ---------- origin : string String pertaining to location to render, such as "Boston, Massachusetts" Returns ------- graph: NetworkX graph Returns a graph of all nodes in the area, prefilled with location data. Notes ----- The api used to get locations can only run 50,000 locations/day. As such, be careful not to make this call too many times. """ graph = ox.graph_from_place(location, network_type='walk') graph = set_elevation(graph) print("Done getting elevation") graph = ox.add_edge_grades(graph) #proj = ox.project_graph(graph) #project graph to UTM to increase accuracy ox.save_graphml(graph, filename=location.split(" ")[0] + "-raw-elevation-graph") #here, we populate custom fields for our weighed inclines for u, v, k, data in graph.edges(keys=True, data=True): elevation_values = weight_function(data['grade_abs'], data['length']) data['elev0'] = elevation_values[0] data['elev25'] = elevation_values[1] data['elev50'] = elevation_values[2] data['elev75'] = elevation_values[3] data['elev100'] = elevation_values[4] ox.save_graphml(graph, filename=location.split(" ")[0] + "-elevation-graph")
def add_elevations(country_folder, graph_filename): # load graph graph_filepath = os.path.join(graphml_folder, country_folder, graph_filename) G = ox.load_graphml(filepath=graph_filepath) print(ox.ts(), 'load', len(G), 'nodes and', len(G.edges), 'edges from', graph_filepath) # get the elevation data for this graph's nodes graph_elevs = df_elevs.loc[set(G.nodes)].sort_index() # set nodes' elevation attributes nx.set_node_attributes(G, name='elevation', values=graph_elevs['elevation'].astype(int)) nx.set_node_attributes(G, name='elevation_aster', values=graph_elevs['elev_aster'].dropna().astype(int)) nx.set_node_attributes(G, name='elevation_srtm', values=graph_elevs['elev_srtm'].dropna().astype(int)) # confirm that no graph node is missing elevation assert set(G.nodes) == set(nx.get_node_attributes(G, 'elevation')) # then calculate edge grades G = ox.add_edge_grades(G, add_absolute=True) # resave graphml now that it has elevations/grades ox.save_graphml(G, filepath=graph_filepath) print(ox.ts(), 'save', graph_filepath) # save node/edge lists uc_name = graph_filename.replace('.graphml', '') nelist_output_folder = os.path.join(nelist_folder, country_folder, uc_name) save_node_edge_lists(G, nelist_output_folder) print(ox.ts(), 'save', nelist_output_folder) # save as geopackage gpkg_filename = uc_name + '.gpkg' gpkg_filepath = os.path.join(gpkg_folder, country_folder, gpkg_filename) ox.save_graph_geopackage(G, filepath=gpkg_filepath) print(ox.ts(), 'save', gpkg_filepath)
def get_map(self, place='Boston', new_place=False): # if new_place == False: # return pkl.load(open("graph_projected.pkl","rb")), pkl.load(open("graph.pkl","rb")) #downloading local map place = 'Boston' place_query = { 'city': 'Boston', 'state': 'Massachusetts', 'country': 'USA' } graph_orig = ox.graph_from_place(place_query, network_type='drive') #adding elevation data from GoogleMaps #Enter the API key here key = self.model.get_key() graph_orig = ox.add_node_elevations(graph_orig, api_key=key) graph_orig = ox.add_edge_grades(graph_orig) pkl.dump(graph_orig, open("graph.pkl", "wb")) #projecting map on to 2D space graph_projection = ox.project_graph(graph_orig) pkl.dump(graph_projection, open("graph_projected.pkl", "wb")) return graph_projection, graph_orig
def test_routing_folium(): # calculate shortest path and plot as static image and leaflet web map 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.nodes())) 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) 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 = nx.shortest_path(G, orig_node, dest_node) attributes = ox.utils_graph.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=orig_pt, destination_point=dest_pt, 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 enrich_network(network, clean_dead_ends=True, elevation_api_key=None, drop_keys=[ 'place_id', 'license', 'osm_type', 'osmid', ' lat', 'lon', 'display_name', 'country', 'country_code', 'state', 'state_district', 'county', 'city' ], email=None, postcode_delim=' '): """ Enrich a street network by adding further attributes to the edges in the network. These can then be used in clustering, compression, graph embeddings, shortest paths, etc. Depending on the size of the network, this method may incur a large number of requests and time to run. If anprx.settings['cache'] is set to True, as is by default, responses will be cached and subsequent calls to this method, for the same or intersecting networks, should be faster. Parameters ---------- network : nx.MultiDiGraph a street network clean_dead_ends : bool true if dead end nodes should be removed from the graph elevation_api_key : string Google API key necessary to access the Elevation API. If None, elevation. drop_keys: list keys to ignore from the nominatim response containing address details email : string Valid email address in case you are making a large number of requests. postcode_delim : string postcode delimiter used to split the main postcode into two parts: outer and inner. Use None to skip postcode splitting. Returns ------- network : nx.MultiDiGraph The same network, but with additional edge attributes """ start_time = time.time() log("Enriching network with {} nodes and {} edges. This may take a while.."\ .format(len(network), network.number_of_edges()), level = lg.INFO) if clean_dead_ends: remove_dead_end_nodes(network) # Add bearings network = ox.add_edge_bearings(network) # Elevation if elevation_api_key: start_time_local = time.time() # add elevation to each of the nodes,using the google elevation API network = ox.add_node_elevations(network, api_key=elevation_api_key) # then calculate edge grades network = ox.add_edge_grades(network) log("Added node elevations and edge grades in {:,.3f} seconds"\ .format(time.time() - start_time_local), level = lg.INFO) # lookup addresses network = add_address_details(network, drop_keys, email) # Split post code into outward and inward # assume that there is a space that can be used for string split for (u, v, k, postcode) in network.edges(keys=True, data='postcode'): if postcode: postcode_l = postcode.split(postcode_delim) if len(postcode_l) != 2: log("Could not split postcode {}".format(postcode), level=lg.WARNING) else: network[u][v][k]['out_postcode'] = postcode_l[0] network[u][v][k]['in_postcode'] = postcode_l[1] log("Enriched network in {:,.3f} seconds"\ .format(time.time() - start_time), level = lg.INFO) return network
(trips['End Latitude'].isnull()) | (trips['End Longitude'].isnull())].index) # '''Delete the rows with GPS out of range''' # trips = trips.drop(trips[(trips['Start Latitude'] > 46) | (trips['Start Latitude'] < 36)].index) '''Save the modified data''' trips.to_csv(cityname + '_modified.csv') # In[4]: ''' Extract the biking road network from OpenStreetMap ''' graph = ox.graph_from_place(place_query, network_type='all') ox.plot_graph(graph) # add elevation to each of the nodes, using the google elevation API, then calculate edge grades graph = ox.add_node_elevations(graph, api_key=apikey) graph = ox.add_edge_grades(graph) ''' Convert the network into nodes geodataframe and edges geodataframe respectively ''' nodes, edges = ox.graph_to_gdfs(graph, nodes=True, edges=True) # In[5]: ''' Convert into UTM format ''' graph_proj = ox.project_graph(graph) # get one color for each node, by elevation, then plot the network nc = ox.get_node_colors_by_attr(graph_proj, 'elevation', cmap='viridis', num_bins=20) fig, ax = ox.plot_graph(graph_proj, node_color=nc, node_zorder=2) plt.tight_layout() ''' Convert the projected network into nodes geodataframe and edges geodataframe respectively '''
google_elevation_api_key="AIzaSyCkCrJwj0gzVp1kGjo5lz6VKDyaFUEVbGk" # In[20]: place = 'Amherst' place_query = {'city':'Amherst', 'state':'Massachusetts', 'country':'USA'} G = ox.graph_from_place(place_query, network_type='drive') # In[21]: G = ox.add_node_elevations(G, api_key=google_elevation_api_key) G = ox.add_edge_grades(G) # In[22]: edge_grades = [data['grade_abs'] for u, v, k, data in ox.get_undirected(G).edges(keys=True, data=True)] # In[23]: avg_grade = np.mean(edge_grades) print('Average street grade in {} is {:.1f}%'.format(place, avg_grade*100)) med_grade = np.median(edge_grades)
def collect_data(center_point, dist, known_trail=None): filter_ = '["highway"]["area"!~"yes"]["highway"!~"service|motor|proposed|construction|abandoned|platform|raceway"]["foot"!~"no"]["service"!~"private"]' G = ox.graph_from_point(center_point=center_point, dist=dist, dist_type='bbox', custom_filter=filter_) G = G.to_undirected() # Add marked paths, cycleways, and user-specified trails edge_colors = [] trail_color = '#F1C232' #'#674EA7' for edge in G.edges(data=True): try: name = edge[2]['name'] if name in known_trail or (isinstance( name, list) and len(known_trail.intesection(name)) != 0): edge_colors.append(trail_color) continue except: pass highway = edge[2]['highway'] if highway == 'path' or (isinstance(highway, list) and 'path' in highway): edge_colors.append(trail_color) elif highway == 'cycleway' or (isinstance(highway, list) and 'cycleway' in highway): edge_colors.append(trail_color) else: edge_colors.append('#999999') # Get water features tags = {'natural': 'water'} pois_water = ox.pois_from_point(center_point, tags, dist=dist) pois_water_list = list(pois_water['name'][pd.notna(pois_water['name'])]) pois_water_list.sort() pois_water_list = [el for el in pois_water_list if 'Lake' in el] # Get park features tags = {'leisure': 'park'} park_pois = ox.pois_from_point(center_point, tags, dist=dist) # Add elevation data google_maps_api_key = os.environ.get( 'GOOGLEAPIKEY') # You'll need your own API key :) G = ox.add_node_elevations(G, api_key=google_maps_api_key) G = ox.add_edge_grades(G) grade_data = [] for u, v, data in G.edges(keys=False, data=True): u_lat = G.nodes[u]['y'] u_lng = G.nodes[u]['x'] u_el = G.nodes[u]['elevation'] v_lat = G.nodes[v]['y'] v_lng = G.nodes[v]['x'] v_el = G.nodes[v]['elevation'] elevation_change = G.nodes[v]["elevation"] - G.nodes[u]["elevation"] center_lat = 0.5 * (u_lat + v_lat) center_lng = 0.5 * (u_lng + v_lng) grade_datum = np.array([ data['length'], data['grade_abs'], data['length'] * data['grade_abs'] ]) grade_data.append(grade_datum) grade_data = np.vstack(grade_data) # Build edge data # https://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters import math def lat_lon_to_dist(lat1, lon1, lat2, lon2): # pt[0] = long, pt[1] = lat R = 6378.137 dLat = lat2 * math.pi / 180 - lat1 * math.pi / 180 dLon = lon2 * math.pi / 180 - lon1 * math.pi / 180 a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos( lat1 * math.pi / 180) * math.cos(lat2 * math.pi / 180) * math.sin( dLon / 2) * math.sin(dLon / 2) c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) d = R * c return d * 1000 # meters def get_min_dist(pt, pois_geom): pt_np = np.array(pt) min_ = float('inf') for obj in pois_geom: if isinstance(obj, Point) or isinstance(obj, tuple): obj_np = np.array(obj) dist = lat_lon_to_dist(pt_np[1], pt_np[0], obj_np[1], obj_np[0]) if dist < min_: min_ = dist min_poi_pt = obj_np if isinstance(obj, Polygon): if obj.contains(pt) == True: min_ = 0 return min_, None coords = list(obj.exterior.coords) dist, poi_pt = get_min_dist(pt, coords) if dist < min_: min_ = dist min_poi_pt = poi_pt if isinstance(obj, MultiPolygon): for poly in obj: if poly.contains(pt) == True: min_ = 0 return min_, None coords = list(poly.exterior.coords) dist, poi_pt = get_min_dist(pt, coords) if dist < min_: min_ = dist min_poi_pt = poi_pt return min_, min_poi_pt # Get edge data for parks print('Getting park edge data') nature_dist_edge = [] for edge in G.edges(data=True): edge_nodes = [edge[0], edge[1]] center = np.array([ sum([G.nodes[node_id]['x'] for node_id in edge_nodes]) / 2, sum([G.nodes[node_id]['y'] for node_id in edge_nodes]) / 2 ]) pt = Point(center[0], center[1]) dist, min_pt = get_min_dist(pt, park_pois['geometry']) nature_dist_edge.append((dist, np.array(pt), min_pt)) # Get edge data for water print('Getting water edge data') water_dist_edge = [] for edge in G.edges(data=True): edge_nodes = [edge[0], edge[1]] center = np.array([ sum([G.nodes[node_id]['x'] for node_id in edge_nodes]) / 2, sum([G.nodes[node_id]['y'] for node_id in edge_nodes]) / 2 ]) pt = Point(center[0], center[1]) dist, min_pt = get_min_dist(pt, pois_water['geometry']) water_dist_edge.append((dist, np.array(pt), min_pt)) # Rescale edge data based on statistical analysis def sigma(x): return 1. / (1 + np.exp(-(x - 200) / 30)) # - sigma(0) lengths = grade_data[:, 0] impedence = 10 * grade_data[:, 2] water_dist_rescaled = map(lambda x: sigma(x[0]), water_dist_edge) water_dist_impedence = [ x * y for x, y in zip(water_dist_rescaled, lengths) ] nature_dist_rescaled = map(lambda x: sigma(x[0]), nature_dist_edge) nature_dist_impedence = [ x * y for x, y in zip(nature_dist_rescaled, lengths) ] is_not_trail_penalty = [ length * float(color != trail_color) for color, length in zip(edge_colors, lengths) ] lengths = list(lengths) impedence = list(impedence) data = list( zip(lengths, impedence, water_dist_impedence, nature_dist_impedence, is_not_trail_penalty)) edge_nodes = [(u, v) for u, v, data in list(G.edges(keys=False, data=True))] all_data = [(a[0], a[1], b[0], b[1], b[2], b[3], b[4]) for a, b in zip(edge_nodes, data)] return G, all_data
def populate_graph(self, G, speeds = False): G = ox.add_edge_speeds(G) if speeds else G G = ox.add_node_elevations(G, api_key= api_key) G = ox.add_edge_grades(G) return G
def populate_graph(G, speeds = False): G = ox.add_edge_speeds(G) if speeds else G G = ox.add_edge_travel_times(G) G = ox.add_node_elevations(G, api_key= api_key) G = ox.add_edge_grades(G, None, None)
def get_map(self, start_lat, start_long, end_lat, end_long, chosen_weight): print( "Coordinates", start_lat, start_long, end_lat, end_long, ) print("weight", chosen_weight) place = 'Amherst' place_query = { 'city': 'Amherst', 'state': 'Massachusetts', 'country': 'USA' } G = ox.graph_from_place(place_query, network_type='drive') G = ox.add_node_elevations( G, api_key='AIzaSyB9DBYn2sdIznFbmBg4DHOTl54soDBkx2E') G = ox.add_edge_grades(G) edge_grades = [ data['grade_abs'] for u, v, k, data in ox.get_undirected(G).edges(keys=True, data=True) ] avg_grade = np.mean(edge_grades) #print('Average street grade in {} is {:.1f}%'.format(place, avg_grade*100)) if chosen_weight == 0: choice = 'length' elif chosen_weight == 1: choice = 'minimum' elif chosen_weight == 2: choice = 'impedence' med_grade = np.median(edge_grades) #print('Median street grade in {} is {:.1f}%'.format(place, med_grade*100)) # project the street network to UTM G_proj = ox.project_graph(G) # get one color for each node, by elevation, then plot the network #nc = ox.get_node_colors_by_attr(G_proj, 'elevation', cmap='plasma', num_bins=20) #fig, ax = ox.plot_graph(G_proj, fig_height=6, node_color=nc, node_size=12, node_zorder=2, edge_color='#dddddd') # get a color for each edge, by grade, then plot the network #ec = ox.get_edge_colors_by_attr(G_proj, 'grade_abs', cmap='plasma', num_bins=10) #fig, ax = ox.plot_graph(G_proj, fig_height=6, edge_color=ec, edge_linewidth=0.8, node_size=0) # select an origin and destination node and a bounding box around them origin = ox.get_nearest_node(G, (start_lat, start_long)) destination = ox.get_nearest_node(G, (end_lat, end_long)) bbox = ox.bbox_from_point( ((start_lat + end_lat) / 2, (start_long + end_long) / 2), distance=5000, project_utm=True) for u, v, k, data in G_proj.edges(keys=True, data=True): data['impedance'] = self.impedance(data['length'], data['grade_abs']) data['rise'] = data['length'] * data['grade'] #weight_choice = {'easy' : 'length', 'median' : 'minimum', 'hard' : 'impedance'} routef = nx.shortest_path(G_proj, source=origin, target=destination, weight=choice) route_map = ox.plot_route_folium(G, routef) p1 = [start_lat, start_long] p2 = [end_lat, end_long] folium.Marker(location=p1, icon=folium.Icon(color='green')).add_to(route_map) folium.Marker(location=p2, icon=folium.Icon(color='red')).add_to(route_map) print("------------------4321") result = self.print_route_stats(routef, G_proj) filepath = 'routeff.html' route_map.save(filepath) IFrame(filepath, width=600, height=500) return result