def simple_link_mapper(graph, strict=True): """ CREDIT: https://github.com/gboeing/osmnx/blob/master/osmnx/simplify.py ------- modified for different functionality ------- The default graph extracted has lots of links due to every bend in the road being classified as a link. Due to graph having lots of links (and the map matcher requiring it to do so), we need a way to map these smaller links to their simplified ones so we can model the longer roads as desired. Helper function. Returns a dictionary unsimplified edges to their corresponding simplified links as well as the proportion (lengths) of those simplified links they represent. Parameters: ---------- graph (networkx multidigraph) strict (bool): if False, allow nodes to be end points even if they fail all other rules but have edges with different OSM IDs Returns: ------- link_mapper (dictionary): Dictionary that maps unsimplified edges to their corresponding simplified links as well as the proportion (lengths) of those simplified links they represent. """ # first identify all the nodes that are endpoints endpoints = set([ node for node in graph.nodes() if ox.is_endpoint(graph, node, strict=strict) ]) paths_to_simplify = [] # for each endpoint node, look at each of its successor nodes for node in endpoints: for successor in graph.successors(node): if successor not in endpoints: # if the successor is not an endpoint, build a path from the # endpoint node to the next endpoint node try: path = ox.build_path(graph, successor, endpoints, path=[node, successor]) paths_to_simplify.append(path) except RuntimeError: continue else: # just add node, successor into paths to simplify anyways (so it get's added to link_mapper later) paths_to_simplify.append([node, successor]) # Now we have a list of paths to simplify # we will now use the edges of a pre-simplified graph for comparison simplified_graph = ox.simplify_graph(graph, strict=True) simple_edge_data = return_edge_data(simplified_graph) #also get the edge data for normal graph edge_data = return_edge_data(graph) link_mapper = {} # now iterate through the paths to simplify for path in paths_to_simplify: # simplified edge corresponds to first and last of path simple_edge = get_edge_name(path[0], path[-1]) simple_edge_length = simple_edge_data[simple_edge]['length'] # now iterate through interstitial nodes for u, v in zip(path[:-1], path[1:]): edge_name_1 = get_edge_name(u, v) # now take into account other direction too edge_name_2 = get_edge_name(v, u) # now find what proportion of simple link length this link is proportion = edge_data[edge_name_1]['length'] / simple_edge_length link_mapper[edge_name_1] = { 'simple_link': simple_edge, 'proportion': proportion } link_mapper[edge_name_2] = { 'simple_link': simple_edge, 'proportion': proportion } return link_mapper
import matplotlib.pyplot as plt import numpy as np import osmnx as ox import pandas as pd import geopandas as gpd import collections ox.config(log_console=True, use_cache=True) weight_by_length = False print(ox.__version__) # create a network around some (lat, lon) point but do not simplify it yet location_point = (39.9057386, 116.3682035) G = ox.graph_from_point(location_point, network_type='drive_service', distance=500, simplify=False) # turn off strict mode and see what nodes we'd remove, in red nc = ['b' if ox.is_endpoint(G, node) else 'r' for node in G.nodes()] fig, ax = ox.plot_graph(G, node_color=nc, node_zorder=3) # simplify the network SG = ox.simplify_graph(G) fig, ax = ox.plot_graph(SG, node_color='b', node_zorder=3)
G = ox.graph_from_place('Khan Prampi Makara, Cambodia', network_type='drive', buffer_dist=200) ec = [ 'r' if data['oneway'] else 'blue' for u, v, key, data in G.edges(keys=True, data=True) ] ox.plot_graph(G, node_size=0, edge_color=ec) # In[18]: #visualize all the cul-de-sacs (or intersections of any other type) in a city to get a sense of these points of low network connectivity # We can visualize all the cul-de-sacs for all networks place = "Dangkao" G = ox.graph_from_place(place, network_type='drive', simplify=False) nc = ['r' if ox.is_endpoint(G, node) else 'grey' for node in G.nodes()] fig, ax = ox.plot_graph(G, node_color=nc, node_zorder=3) # In[19]: # highlight one-way streets ec = [ 'r' if data['oneway'] else 'blue' for u, v, key, data in G.edges(keys=True, data=True) ] fig, ax = ox.plot_graph(G, node_color='w', node_edgecolor='k', node_size=4, node_zorder=3, edge_color=ec,
def get_important_node_ids(G): # get rid of some mid-way shaping nodes nds = [] for nid in G.nodes(): if ox.is_endpoint(G, nid, strict=True): nds.append(nid) return nds