def simple_G(): ''' 删除长度为0 的边 ''' current_dir = os.path.dirname(os.path.abspath(__file__)) G_proj = ox.load_graphml(current_dir + '\\data\\chengdu_proj.graphml') nodes, edges = ox.graph_to_gdfs(G_proj, fill_edge_geometry=True) edges = edges[edges['u'] != edges['v']] edges = edges[edges['key'] == 0] edges = edges[edges['length'] > 0] nodes['osmid'] = [int(i) for i in nodes['osmid']] nodes['node_id'] = range(nodes.shape[0]) edges['road_id'] = range(edges.shape[0]) ''' nodes_replace_id_dict 已经保存 ''' # 读取 f = open(current_dir + '\\data\\nodes_replace_id_dict.txt', 'r') a = f.read() nodes_replace_id_dict = eval(a) f.close() edges['u_replace'] = [nodes_replace_id_dict[i] for i in edges['u']] edges['v_replace'] = [nodes_replace_id_dict[i] for i in edges['v']] G = ox.gdfs_to_graph(nodes, edges) return G, edges
def ox_graph(nodes_df, links_df): """ create an osmnx-flavored network graph osmnx doesn't like values that are arrays, so remove the variables that have arrays. osmnx also requires that certain variables be filled in, so do that too. Parameters ---------- nodes_df : GeoDataFrame link_df : GeoDataFrame Returns ------- networkx multidigraph """ try: graph_nodes = nodes_df.drop( ["inboundReferenceId", "outboundReferenceId"], axis=1) except: graph_nodes = nodes_df graph_nodes.gdf_name = "network_nodes" G = ox.gdfs_to_graph(graph_nodes, links_df) return G
def test_network_saving_loading(): # save/load graph as shapefile and graphml file G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) ox.save_graphml(G_projected, filename='gephi.graphml', gephi=True) G2 = ox.load_graphml('graph.graphml') # convert graph to node/edge GeoDataFrames and back again gdf_edges = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=False) gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G3 = ox.gdfs_to_graph(gdf_nodes, gdf_edges) # find graph nodes nearest to some set of points 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')
def bikin_rute(lat_input,long_input,lat_center,long_center,lat_output,long_output): titik_awal = [lat_input, long_input] titik_tujuan = [lat_output, long_output] bandung = (lat_center, long_center) G = ox.graph_from_point(bandung, distance=600) nodes, _ = ox.graph_to_gdfs(G) #ambil attribut edges pada G edges = ox.graph_to_gdfs(G, nodes=False, edges=True, node_geometry=False, fill_edge_geometry=False) #kasi nilai random antara 1-10 pada G['weight'] edges['weight'] = np.random.randint(1,10, size=len(edges)) #campur ke G G = ox.gdfs_to_graph(nodes,edges) #deklarasi tree untuk mendeteksi closest nodes pada titik awal dan tujuan tree = KDTree(nodes[['y', 'x']], metric='euclidean') awal = tree.query([titik_awal], k=1, return_distance=False)[0] tujuan = tree.query([titik_tujuan], k=1, return_distance=False)[0] #dapat nodes terdekat closest_node_to_awal = nodes.iloc[awal].index.values[0] closest_node_to_tujuan = nodes.iloc[tujuan].index.values[0] route = nx.dijkstra_path(G, closest_node_to_awal,closest_node_to_tujuan,weight='weight') basemap = ox.plot_route_folium(G, route, route_color='green') folium.Marker(location=titik_awal,icon=folium.Icon(color='red')).add_to(basemap) folium.Marker(location=titik_tujuan,icon=folium.Icon(color='green')).add_to(basemap) basemap.save(outfile= "C:/xampp/htdocs/js/flask2/templates/djikstra.html")
def test_network_saving_loading(): # save/load graph as shapefile and graphml file G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) ox.save_graphml(G_projected, filename='gephi.graphml', gephi=True) G2 = ox.load_graphml('graph.graphml') G3 = ox.load_graphml('graph.graphml', node_type=str) # convert graph to node/edge GeoDataFrames and back again gdf_edges = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=False) gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G4 = ox.gdfs_to_graph(gdf_nodes, gdf_edges) # find graph nodes nearest to some set of points 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') # find graph edges nearest to some set of points 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='kdtree', dist=50)
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.nodes()) assert len(gdf_edges) == len(G.edges(keys=True)) G = ox.gdfs_to_graph(gdf_nodes, gdf_edges) assert len(gdf_nodes) == len(G.nodes()) 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 test_network_saving_loading(): G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) G2 = ox.load_graphml('graph.graphml') gdf_edges = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=False) gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G3 = ox.gdfs_to_graph(gdf_nodes, gdf_edges)
def test_network_saving_loading(): with httmock.HTTMock(get_mock_response_content('overpass-response-7.json.gz')): G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) G2 = ox.load_graphml('graph.graphml') gdf_edges = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=False) gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G3 = ox.gdfs_to_graph(gdf_nodes, gdf_edges)
def road_kill(dis, ndf, edf): """ Removes edges from city and returns graph object of remaining city roads """ city = ox.gdfs_to_graph(ndf, edf) #This below code is a little sloppy, but I am going to live with it for now live = [] for i in city.edges(): if i not in dis.edges(): live.append(i[0]) live = edf[edf["u"].isin(live)] #This above code is a little sloppy, but I am going to live with it for now print("{} roads remain of {} total roads".format(live.size, edf.size)) city_live = ox.gdfs_to_graph(ndf, live) nc = ['red' if i in dis.nodes() else 'blue' for i in city.nodes()] ox.plot_graph(city_live, node_size=15, node_color=nc, edge_color="g") return city_live
def major_map(nodes_df, edges_df): m_nodes_df = nodes_df[nodes_df.major != "minor"].copy() m_edges_df = edges_df[edges_df.ref != "minor"].copy() minor_nodes = nodes_df[nodes_df.major == "minor"] kill = np.asarray(minor_nodes.osmid.values) major_roads = ox.gdfs_to_graph(nodes_df, m_edges_df) for i in kill: major_roads.remove_node(i) ox.plot_graph(major_roads) return [intersection(major_roads), major_roads]
def bikin_rute_multiple(lat_center,long_center,lat_in1,lng_in1,lat_in2,lng_in2,lat_in3,lng_in3): titik_1 = [lat_in1, lng_in1] titik_2 = [lat_in2, lng_in2] titik_3 = [lat_in3, lng_in3] #titik_1 = [-6.921169, 107.601442] #titik_2 = [-6.928275, 107.604579] #titik_3 = [-6.922519, 107.607146] bandung = (lat_center, long_center) G = ox.graph_from_point(bandung, distance=600) nodes, _ = ox.graph_to_gdfs(G) #ambil attribut edges pada G edges = ox.graph_to_gdfs(G, nodes=False, edges=True, node_geometry=False, fill_edge_geometry=False) #kasi nilai random antara 1-10 pada G['weight'] edges['weight'] = np.random.randint(1,10, size=len(edges)) #campur ke G G = ox.gdfs_to_graph(nodes,edges) #deklarasi tree untuk mendeteksi closest nodes pada titik awal dan tujuan tree = KDTree(nodes[['y', 'x']], metric='euclidean') point1 = tree.query([titik_1], k=1, return_distance=False)[0] point2 = tree.query([titik_2], k=1, return_distance=False)[0] point3 = tree.query([titik_3], k=1, return_distance=False)[0] #dapat nodes terdekat closest_node_to_1 = nodes.iloc[point1].index.values[0] closest_node_to_2 = nodes.iloc[point2].index.values[0] closest_node_to_3 = nodes.iloc[point3].index.values[0] route1 = nx.dijkstra_path(G, closest_node_to_1,closest_node_to_2,weight='weight') route2 = nx.dijkstra_path(G, closest_node_to_2,closest_node_to_3,weight='weight') tooltip = 'Click me!' basemap = ox.plot_route_folium(G, route1, route_color='red') basemap2 = ox.plot_route_folium(G, route2, route_color='orange',route_map = basemap) folium.Marker(location=titik_1,popup='<i>titik 1 </i>', icon=folium.Icon(color='red')).add_to(basemap2) folium.Marker(location=titik_2,popup='<i>titik 2 </i>',icon=folium.Icon(color='orange')).add_to(basemap2) folium.Marker(location=titik_3,popup='<i>titik 3 </i>',icon=folium.Icon(color='blue')).add_to(basemap2) basemap2.save(outfile= "C:/xampp/htdocs/js/flask2/templates/multiple_djikstra.html")
def get_town_data(town_params): """Query OSM and process its traffic graph.""" ox.config(use_cache=True, log_console=True) G_town = ox.graph_from_place(town_params.town_name, network_type="drive", simplify=False) G_town = ox.simplify.simplify_graph(G_town, strict=False) nodes, edges = ox.graph_to_gdfs(G_town) town_node_ids = set(nodes) node_ids = nodes[["osmid"]].values processed_nodes = [] for node_id in node_ids: if node_id == town_params.dest: processed_nodes.append("T") if node_id == town_params.source: processed_nodes.append("S") processed_nodes.append(node_id[0]) # change from meters to miles edges["length"] = edges["length"].apply(meters_to_miles) edges["speed_limit"] = edges.apply( lambda x: _set_speed(x.highway, x.length), axis=1) processed_edges = {} for u, v, length, speed in edges[["u", "v", "length", "speed_limit"]].values: u = int(u) v = int(v) if u == town_params.source: u = "S" if v == town_params.source: v = "S" if u == town_params.dest: u = "T" if v == town_params.dest: v = "T" if u in processed_nodes and v in processed_nodes: e = EdgeData(speed_lim=speed, length=length) processed_edges[u, v] = e G = ox.gdfs_to_graph(nodes, edges) return (G, town_params.source, town_params.dest), (processed_nodes, processed_edges)
if u[i] == node_1: node_1_inx.append(i) #find index of node_2 node_2_inx = [] for i in range(0, len(v)): if v[i] == node_2: node_2_inx.append(i) #find the row index of node_1 & node 2 inx = list(set(node_1_inx) & set(node_2_inx)) edge_string = edges.geometry[inx[0]] print(edge_string) # edge_sep = redistribute_vertices(edge_string, 0.004) # print(edge_sep) #transform edges into evenly spaced points edges['points'] = edges.apply( lambda edge_string: redistribute_vertices(edge_string.geometry, 0.004), axis=1) print(edges['points']) #develop edges data for each created points extended = edges['points'].apply([pd.Series]).stack().reset_index( level=1, drop=True).join(edges).reset_index() graph = ox.gdfs_to_graph(nodes, edges) ox.plot_graph(graph)
def clean_intersections_graph(G, tolerance=15, dead_ends=False): """ Clean-up intersections comprising clusters of nodes by merging them and returning a modified graph. Divided roads are represented by separate centerline edges. The intersection of two divided roads thus creates 4 nodes, representing where each edge intersects a perpendicular edge. These 4 nodes represent a single intersection in the real world. This function cleans them up by buffering their points to an arbitrary distance, merging overlapping buffers, and taking their centroid. For best results, the tolerance argument should be adjusted to approximately match street design standards in the specific street network. Parameters ---------- G : networkx multidigraph tolerance : float nodes within this distance (in graph's geometry's units) will be dissolved into a single intersection dead_ends : bool if False, discard dead-end nodes to return only street-intersection points Returns ---------- Networkx graph with the new aggregated vertices and induced edges """ # if dead_ends is False, discard dead-end nodes to only work with edge # intersections if not dead_ends: if 'streets_per_node' in G.graph: streets_per_node = G.graph['streets_per_node'] else: streets_per_node = count_streets_per_node(G) dead_end_nodes = [ node for node, count in streets_per_node.items() if count <= 1 ] G = G.copy() G.remove_nodes_from(dead_end_nodes) # create a GeoDataFrame of nodes, buffer to passed-in distance, merge # overlaps gdf_nodes, gdf_edges = graph_to_gdfs(G) buffered_nodes = gdf_nodes.buffer(tolerance).unary_union if isinstance(buffered_nodes, Polygon): # if only a single node results, make it iterable so we can turn it into # a GeoSeries buffered_nodes = [buffered_nodes] # Buffer points by tolerance and union the overlapping ones gdf_nodes, gdf_edges = graph_to_gdfs(G) buffered_nodes = gdf_nodes.buffer(15).unary_union unified_intersections = gpd.GeoSeries(list(buffered_nodes)) unified_gdf = gpd.GeoDataFrame(unified_intersections).rename(columns={ 0: 'geometry' }).set_geometry('geometry') unified_gdf.crs = gdf_nodes.crs ### Merge original nodes with the aggregated shapes intersections = gpd.sjoin(gdf_nodes, unified_gdf, how="right", op='intersects') intersections['geometry_str'] = intersections['geometry'].map( lambda x: str(x)) intersections['new_osmid'] = intersections.groupby( 'geometry_str')['index_left'].transform('min').astype(str) intersections['num_osmid_agg'] = intersections.groupby( 'geometry_str')['index_left'].transform('count') ### Create temporary lookup with the agg osmid and the new one lookup = intersections[intersections['num_osmid_agg'] > 1][[ 'osmid', 'new_osmid', 'num_osmid_agg' ]] lookup = lookup.rename(columns={'osmid': 'old_osmid'}) intersections = intersections[intersections['osmid'].astype(str) == intersections['new_osmid']] intersections = intersections.set_index('index_left') ### Make everything else similar to original node df intersections = intersections[gdf_nodes.columns] intersections['geometry'] = intersections.geometry.centroid intersections['x'] = intersections.geometry.x intersections['y'] = intersections.geometry.y del intersections.index.name intersections.gdf_name = gdf_nodes.gdf_name # Replace aggregated osimid with the new ones # 3 cases - 1) none in lookup, 2) either u or v in lookup, 3) u and v in lookup # Ignore case 1. Append case 3 to case 2. ignore distance but append linestring. # removed .astype(str) from merger after u a nd v agg_gdf_edges = pd.merge( gdf_edges.assign(u=gdf_edges.u), lookup.rename(columns={ 'new_osmid': 'new_osmid_u', 'old_osmid': 'old_osmid_u' }), left_on='u', right_on='old_osmid_u', how='left') agg_gdf_edges = pd.merge( agg_gdf_edges.assign(v=agg_gdf_edges.v), lookup.rename(columns={ 'new_osmid': 'new_osmid_v', 'old_osmid': 'old_osmid_v' }), left_on='v', right_on='old_osmid_v', how='left') # Remove all u-v edges that are between the nodes that are aggregated together (case 3) agg_gdf_edges_c3 = agg_gdf_edges[( (agg_gdf_edges['new_osmid_v'].notnull()) & (agg_gdf_edges['new_osmid_u'].notnull()) & (agg_gdf_edges['new_osmid_u'] == agg_gdf_edges['new_osmid_v']))] agg_gdf_edges = agg_gdf_edges[~agg_gdf_edges.index.isin(agg_gdf_edges_c3. index)] # Create a self loop containing all the joint geometries of the aggregated nodes where both u and v are agg # Set onway to false to prevent duplication if someone were to create bidrectional edges agg_gdf_edges_int = agg_gdf_edges_c3[~( (agg_gdf_edges_c3['new_osmid_u'] == agg_gdf_edges_c3['u']) | (agg_gdf_edges_c3['new_osmid_v'] == agg_gdf_edges_c3['v']))] agg_gdf_edges_int = agg_gdf_edges_int.dissolve( by=['new_osmid_u', 'new_osmid_v']).reset_index() agg_gdf_edges_int['u'] = agg_gdf_edges_int['new_osmid_u'] agg_gdf_edges_int['v'] = agg_gdf_edges_int['new_osmid_v'] agg_gdf_edges_int = agg_gdf_edges_int[gdf_edges.columns] agg_gdf_edges_int['oneway'] = False # Simplify by removing edges that do not involve the chosen agg point # at least one of them must contain the new u or new v agg_gdf_edges_c3 = agg_gdf_edges_c3[ (agg_gdf_edges_c3['new_osmid_u'] == agg_gdf_edges_c3['u']) | (agg_gdf_edges_c3['new_osmid_v'] == agg_gdf_edges_c3['v'])] agg_gdf_edges_c3 = agg_gdf_edges_c3[[ 'geometry', 'u', 'v', 'new_osmid_u', 'new_osmid_v' ]] agg_gdf_edges_c3.columns = [ 'old_geometry', 'old_u', 'old_v', 'new_osmid_u', 'new_osmid_v' ] # Merge back the linestring for case 2 # Ignore u and v if they are on the merging / agg node # Copy over the linestring only on the old node subset_gdf = agg_gdf_edges_c3[ agg_gdf_edges_c3['new_osmid_v'] != agg_gdf_edges_c3['old_v']] agg_gdf_edges = pd.merge(agg_gdf_edges, subset_gdf[['old_geometry', 'old_v']], how='left', left_on='u', right_on='old_v') geom = agg_gdf_edges[['geometry', 'old_geometry']].values.tolist() agg_gdf_edges['geometry'] = [ linemerge([r[0], r[1]]) if isinstance(r[1], (LineString, MultiLineString)) else r[0] for r in geom ] agg_gdf_edges.drop(['old_geometry', 'old_v'], axis=1, inplace=True) # If new osmid matches on u, merge in the existing u-v string # where u is the aggregated vertex and v is the old one to be removed subset_gdf = agg_gdf_edges_c3[ agg_gdf_edges_c3['new_osmid_u'] != agg_gdf_edges_c3['old_u']] agg_gdf_edges = pd.merge(agg_gdf_edges, subset_gdf[['old_geometry', 'old_u']], how='left', left_on='v', right_on='old_u') geom = agg_gdf_edges[['geometry', 'old_geometry']].values.tolist() agg_gdf_edges['geometry'] = [ linemerge([r[0], r[1]]) if isinstance(r[1], (LineString, MultiLineString)) else r[0] for r in geom ] agg_gdf_edges.drop(['old_geometry', 'old_u'], axis=1, inplace=True) agg_gdf_edges['u'] = np.where(agg_gdf_edges['new_osmid_u'].notnull(), agg_gdf_edges['new_osmid_u'], agg_gdf_edges['u']) agg_gdf_edges['v'] = np.where(agg_gdf_edges['new_osmid_v'].notnull(), agg_gdf_edges['new_osmid_v'], agg_gdf_edges['v']) agg_gdf_edges = agg_gdf_edges[gdf_edges.columns] agg_gdf_edges = gpd.GeoDataFrame(pd.concat( [agg_gdf_edges, agg_gdf_edges_int], ignore_index=True), crs=agg_gdf_edges.crs) agg_gdf_edges['u'] = agg_gdf_edges['u'].astype(np.int64) agg_gdf_edges['v'] = agg_gdf_edges['v'].astype(np.int64) return gdfs_to_graph(intersections, agg_gdf_edges)
def generate_graph_from_bbox(north, south, east, west, **kwargs): custom_filter = kwargs.get( "custom_filter", "['highway'~'primary|trunk|motorway|secondary|tertiary']") crs = kwargs.get("crs", {"init": "epsg:32651"}) streets = extract_streets(bbox, crs=crs, custom_filter=custom_filter) n, e = ox.save_load.graph_to_gdfs(streets) node_id_map = dict(zip(n.index, range(len(n.index)))) n = n.reset_index() n.gdf_name = "whatever" e.u = e.u.apply(lambda x: node_id_map[x]) e.v = e.v.apply(lambda x: node_id_map[x]) e['subnetwork_id'] = 1 ## hardcode only one subnetwork e["link_id"] = list(range(e.shape[0])) graph = ox.gdfs_to_graph(n, e) graph = add_speed_capacity(graph) ## Inject road connection data rc_id = 0 for node in graph.nodes: in_set = graph.in_edges(node) out_set = graph.out_edges(node) rc_set = [] if (len(in_set) > 0) and (len(out_set) > 0): # Perform link product across nodes but remove u-turns, # i.e. links that map to the reverse direction node_rcs = [ lkpair for lkpair in list(product(in_set, out_set)) if ((lkpair[0] != lkpair[1][::-1]) and (lkpair[0] != lkpair[1]) ) ] for i in node_rcs: rc_set += [{ 'rc_id': rc_id, 'link_id_pair': [ graph.get_edge_data(*i[0], 0)['link_id'], graph.get_edge_data(*i[1], 0)['link_id'] ], 'in_lanes': graph.get_edge_data(*i[0], 0)['lanes'], 'out_lanes': graph.get_edge_data(*i[1], 0)['lanes'] }] rc_id += 1 graph.nodes[node]['node_rcs'] = rc_set ## Inject split data for node in graph.nodes: in_set = graph.in_edges(node) out_set = graph.out_edges(node) splits_set = [] if (len(in_set) > 0) and (len(out_set) > 0): for enter_pair in in_set: enter_link_id = graph.get_edge_data(*enter_pair)[0]['link_id'] exit_link_ids = set([ graph.get_edge_data(*i)[0]['link_id'] for i in out_set if ((enter_pair != i[::-1]) and (enter_pair != i)) ]) # Exclude guaranteed flow RCs if len(exit_link_ids) >= 1: splits_set.append({ "link_in": enter_link_id, "link_out": exit_link_ids, # Default: uniform probability per exit link. # Adjust manually on XML if necessary. "split_ratio": (np.ones(len(exit_link_ids)) / np.ones(len(exit_link_ids)).sum()).tolist() }) graph.nodes[node]['splits_set'] = splits_set return graph
def add_speed_capacity(streets): nodes, edges = ox.graph_to_gdfs(streets) edges['highway'] = edges['highway'].map(collapse_multiple_hwy_values) edges['highway'].fillna(value="unclassified", inplace=True) edges['highway'].value_counts(dropna=False).sort_index() edges['lanes'] = edges['lanes'].map(convert_lists) edges['lanes'] = edges['lanes'].map( lambda x: int(x) if type(x) == str else x) ## assure integer values edges['lanes'] = edges['lanes'].map(collapse_multiple_lane_values) edges['lanes'].value_counts().sort_index() # calculate "typical" number of lanes per hwy type edges['lanes'] = edges['lanes'].astype(float) lane_defaults = edges.groupby('highway')['lanes'].median() lane_defaults = lane_defaults.fillna( value=2).to_dict() #'road' type is null # impute number of lanes when data is missing# impute def impute_lanes(row): if pd.notnull(row['lanes']): return row['lanes'] else: return lane_defaults[row['highway']] edges['lanes'] = edges.apply(impute_lanes, axis=1).astype(int) edges['lanes'] = edges.apply(allocate_lanes, axis=1) # make 1 lanes the min (in case some edge says zero lanes)# make 1 edges.loc[edges['lanes'] < 1, 'lanes'] = 1 # make 4 lanes the capped value (for 4+ lanes dict lookup), but retain true lanes value in lanes column# make 4 edges['lanes_capped'] = edges['lanes'] edges.loc[edges['lanes_capped'] > 4, 'lanes_capped'] = 4 edges['lanes_capped'].value_counts().sort_index() # convert string representation of multiple maxspeed values to a list# conver edges['maxspeed'] = edges['maxspeed'].map(convert_lists) edges['maxspeed'] = edges['maxspeed'].map( collapse_multiple_maxspeed_values) edges['maxspeed'] = edges['maxspeed'].map(parse_speed_strings) edges['maxspeed'].value_counts(dropna=False).sort_index() # extract maxspeed from OSM data when it already exists known_speeds = edges[pd.notnull(edges['maxspeed'])]['maxspeed'] known_speeds = known_speeds.astype(int) # infer speed on all other edges that lack maxspeed data# infer inferred_speeds = edges[pd.isnull(edges['maxspeed'])].apply(infer_speed, axis=1) # merge known speeds with inferred speeds to get a free-flow speed for each edge edges['speed'] = known_speeds.append(inferred_speeds, ignore_index=False, verify_integrity=True) # infer per-lane capacity for each edge using capacity defaults# infer edges['capacity_lane_hour'] = edges.apply(infer_capacity, axis=1) edges['jam_density'] = 5 * edges['capacity_lane_hour'] / edges['speed'] return ox.gdfs_to_graph(nodes, edges)
# http://geopandas.org/reference.html?highlight=wkb#geopandas.GeoDataFrame.from_postgis nodes = gpd.GeoDataFrame.from_postgis(sql = node_query, con = engine, geom_col = 'geom', crs= 27700) edges = gpd.GeoDataFrame.from_postgis(sql = edge_query, con = engine, geom_col = 'geom', crs= 27700) # gdfs_to_graph needs a gdf_name key set nodes.gdf_name = 'nodes' edges.gdf_name = 'edges' # ox.basic_stats needs the geometry column to be named geometry not geom nodes.rename(columns={'geom':'geometry'}, inplace=True) edges.rename(columns={'geom':'geometry'}, inplace=True) # ox.graph_to_gdfs() returns gdf with structure: # highway osmid x y geometry # 3398008838 NaN 3398008838 -0.139214 51.491624 POINT (-0.1392139 51.4916235) # convert WKB into geoalchemy geometry column # postgis handles this # turn gdf's into network net = ox.gdfs_to_graph(gdf_nodes = nodes, gdf_edges = edges) graph_area_m = nodes.unary_union.convex_hull.area # 377,743,665.1522919 for drive net_stats = ox.basic_stats(net, area = graph_area_m, clean_intersects=True, circuity_dist='euclidean') # gives multiple KeyErrors and a ValueError #
def network_dfs(self, print_info=False): G = self.graph_latlon new_graph = ox.add_edge_bearings(G) edge_bus_lanes_left = list( new_graph.edges.data('busway:left', default=False)) edge_bus_lanes_right = list( new_graph.edges.data('busway:right', default=False)) left = [j[2] for i, j in enumerate(edge_bus_lanes_left)] right = [j[2] for i, j in enumerate(edge_bus_lanes_right)] n, e = ox.graph_to_gdfs(new_graph) e = e.assign(dbl_left=left) e = e.assign(dbl_right=right) e = e.drop(['busway:left', 'busway:right'], axis=1) dbl_bool = np.logical_and(e['dbl_left'].values, e['oneway'].values) gdf_val = e[['u', 'v', 'bearing']].values new_rows = [] new_index = len(e) for row, val in e.iterrows(): if dbl_bool[row]: if print_info: print(row) new_row = val.copy() new_row['u'] = int(gdf_val[row][1]) new_row['v'] = int(gdf_val[row][0]) new_row['lanes'] = 1 new_row['bearing'] = gdf_val[row][2] - 180 new_row['osmid'] = 'new_edge' new_row['geometry'] = [ LineString([ n['geometry'][gdf_val[row][1]], n['geometry'][gdf_val[row][0]] ]) ] # print(dict(new_row), dict(val)) new_row = gpd.GeoDataFrame(dict(new_row), index=[new_index]) new_index += 1 new_rows.append(new_row) if new_rows: new_rows = pd.concat(new_rows, axis=0) if print_info: print(new_rows) e = pd.concat([e, new_rows], axis=0) new_graph = ox.gdfs_to_graph(n, e) n, e = ox.graph_to_gdfs(new_graph) network_matrix = e.loc[:, [ 'u', 'v', 'oneway', 'osmid', 'highway', 'length', 'bearing', 'geometry', 'lanes', 'dbl_left', 'dbl_right' ]] network_nodes_small = n.loc[:, ['y', 'x']] else: network_matrix = e.loc[:, [ 'u', 'v', 'oneway', 'osmid', 'highway', 'length', 'bearing', 'geometry', 'lanes', 'dbl_left', 'dbl_right' ]] network_nodes_small = n.loc[:, ['y', 'x']] network_matrix = network_matrix.join(network_nodes_small, on='u') network_matrix = network_matrix.rename(columns={ 'u': 'N1', 'y': 'Lat1', 'x': 'Long1' }) network_matrix = network_matrix.join(network_nodes_small, on='v') network_matrix = network_matrix.rename(columns={ 'v': 'N2', 'y': 'Lat2', 'x': 'Long2' }) cols = [ 'osmid', 'N1', 'Lat1', 'Long1', 'N2', 'Lat2', 'Long2', 'length', 'lanes', 'oneway', 'bearing', 'highway', 'dbl_left', 'dbl_right', 'geometry' ] network_matrix = network_matrix[ cols] # rearranging columns (reader's convenience) network_matrix.reset_index( inplace=True ) # From hereon the unique index of an edge is just its position in df self.graph_latlon = new_graph self.graph = ox.project_graph(self.graph_latlon) self.network_matrix = network_matrix return network_matrix, new_graph, new_rows
gdf_edges = gdf_edges.append(d5, ignore_index=True) d6 = {'geometry': LineString((p4, p5)), 'u': 3586727939, 'v': 3586727940, 'length': 450} gdf_edges = gdf_edges.append(d6, ignore_index=True) d7 = {'geometry': LineString((p5, p6)), 'u': 3586727940, 'v': 3586727941, 'length': 450} gdf_edges = gdf_edges.append(d7, ignore_index=True) d8 = {'geometry': LineString((p6, Point(G.node[node_4]['x'], G.node[node_4]['y']))), 'u': 3586727941, 'v': node_4, 'length': 300.9} gdf_edges = gdf_edges.append(d8, ignore_index=True) G = ox.gdfs_to_graph(gdf_nodes, gdf_edges) # ox.plot_graph(G) ## give some demand locations D = 5 # r_node =[] d_node =[0 for y in range(D)] # r_node =[0 for x in range(R)] d_node[0] = ox.get_nearest_node(G, (37.2525, -80.4199)) print(d_node[0]) # nodes_gps.append((37.2525, -80.4199)) # pos_node.append(d_node[0]) d_node[1] = ox.get_nearest_node(G, (37.229, -80.439)) # nodes_gps.append((37.229, -80.439)) # pos_node.append(d_node[1])
def FramesToGraph(edges, nodes): return ox.gdfs_to_graph(nodes, edges)