def create_graph(response_jsons, name='unnamed', retain_all=True, bidirectional=False): """ Create a networkx graph from Overpass API HTTP response objects. Parameters ---------- response_jsons : list list of dicts of JSON responses from from the Overpass API name : string the name of the graph retain_all : bool if True, return the entire graph even if it is not connected bidirectional : bool if True, create bidirectional edges for one-way streets Returns ------- networkx multidigraph """ # make sure we got data back from the server requests elements = [] elements.extend(response_jsons['elements']) if len(elements) < 1: raise ox.EmptyOverpassResponse( 'There are no data elements in the response JSON objects') # create the graph as a MultiDiGraph and set the original CRS to default_crs G = nx.MultiDiGraph(name=name, crs=ox.settings.default_crs) # extract nodes and paths from the downloaded osm data nodes = {} paths = {} nodes_temp, paths_temp = parse_osm_nodes_paths(response_jsons) for key, value in nodes_temp.items(): nodes[key] = value for key, value in paths_temp.items(): paths[key] = value # add each osm node to the graph for node, data in nodes.items(): G.add_node(node, **data) # add each osm way (aka, path) to the graph G = ox.add_paths(G, paths, bidirectional=bidirectional) # retain only the largest connected component, if caller did not # set retain_all=True if not retain_all: G = ox.get_largest_component(G) # add length (great circle distance between nodes) attribute to each edge to # use as weight if len(G.edges) > 0: G = ox.add_edge_lengths(G) return G
def route_from_relation(relation, nodes, paths): """ Construct a route given the OSM relation. :param dict relation: OSM relation corresponding to the route. :param dict nodes: a lookup dictionary of the graph nodes. :param dict paths: a lookup dictionary of the graph edges. :returns: a tuple of line name and a multigraph. """ route_nodes = {} route_paths = {} rel_tags = relation["tags"] line = rel_tags.get("line") or rel_tags.get("ref") tags = { "line": line, "name": rel_tags.get("name"), "type": rel_tags.get("route") } route = networkx.MultiDiGraph(name=line, crs=osmnx.settings.default_crs) for member in relation["members"]: key = member["ref"] if member["type"] == "node": route_nodes[key] = nodes[key] if member["type"] == "way": path = paths[key].copy() path.update(**tags) if "nodes" not in path: continue route_paths[key] = path for node_key in path["nodes"]: route_nodes[node_key] = nodes[node_key] if not route_paths: return for key, data in route_nodes.items(): route.add_node(key, **data) route = osmnx.add_paths(route, route_paths) route = osmnx.add_edge_lengths(route) return line, route