def simplify_graph_remove_unimportant_roads(G_original: nx.MultiDiGraph): ''' Removes all unimportant roads. :param G_original: networkx graph object. :return: SImplified networkx graph object. ''' G = G_original.copy() to_remove = [] for e in list(G.edges(data=True, keys=True)): u, v, i, info = e highway_type = info['highway'] if check_highway_type_is_to_be_removed( highway_type) and info['length'] < 1000: to_remove.append((u, v, i)) G.remove_edges_from(to_remove) G = ox.remove_isolated_nodes(G) # print(get_all_types(G)) G_component = ox.get_largest_component(G, strongly=True) print_graph_info(G_original) print_graph_info(G) print_graph_info(G_component) return G_component
def prune_non_highways(graph): """ Removes all edges from graph that aren't for highways (cars) and subsequent isolated nodes. :param graph: Full graph with variety of edges :return: Graph with only highway type edges """ pruned_graph = graph.copy() road_types = load_road_types() for u, v, k in graph.edges: edge_data = graph.get_edge_data(u, v, k) if 'highway' not in edge_data.keys(): pruned_graph.remove_edge(u, v, k) else: highway = edge_data['highway'] if type(highway) == str: highway = [highway] remove = True for val in highway: if val in road_types: remove = False if remove: pruned_graph.remove_edge(u, v, k) pruned_graph = ox.remove_isolated_nodes(pruned_graph) return pruned_graph
def main(name): print('Starting with: {}'.format(name)) G = load_graph(name, 'bike') remove = filter_speed(G) G.remove_edges_from(remove) G = ox.remove_isolated_nodes(G) save_new(G, name)
def detect_drive_network_from_point(lat=13.14633, lon=77.514386, distance=2000, save=True, filename='icts2000'): G = ox.graph_from_point((lat, lon), distance=distance, network_type='drive', simplify=False) hwy_types = ['primary', 'motorway', 'trunk'] gdf = ox.graph_to_gdfs(G, nodes=False) mask = ~gdf['highway'].map(lambda x: isinstance(x, str) and x in hwy_types) edges = zip(gdf[mask]['u'], gdf[mask]['v'], gdf[mask]['key']) G.remove_edges_from(edges) G = ox.remove_isolated_nodes(G) G_projected = ox.project_graph(G) filename += '-' + str(distance) fig, ax = ox.plot_graph(G_projected, show=False, save=save, filename=filename, file_format='svg') plt.scatter(*utm.from_latlon(lat, lon)[:2]) plt.show() ox.save_graphml(G, filename=filename + '.graphml') return G
def GetNewGraph(net_type): point = (float(station.iloc[0]['LATITUDE']), float(station.iloc[0]['LONGITUDE'])) gph = ox.graph_from_point(point, 5000, distance_type='network', network_type=net_type, simplify=True, infrastructure='way["highway"]') gph = ox.remove_isolated_nodes(gph) return gph
def detect_drive_network_from_place(place, save=True, filename='icts2000'): G = ox.graph_from_place(place, network_type='drive', simplify=False) hwy_types = ['primary', 'motorway', 'trunk', 'secondary', 'tertiary'] gdf = ox.graph_to_gdfs(G, nodes=False) mask = ~gdf['highway'].map(lambda x: isinstance(x, str) and x in hwy_types) edges = zip(gdf[mask]['u'], gdf[mask]['v'], gdf[mask]['key']) G.remove_edges_from(edges) G = ox.remove_isolated_nodes(G) G_projected = ox.project_graph(G) fig, ax = ox.plot_graph(G_projected, show=False, save=save, filename=filename, file_format='svg') ox.save_graphml(G, filename=filename + '.graphml') return G
#start of the map, not super accurate, just for declaring punggol = (1.403948, 103.909048) #G = ox.graph_from_point(punggol, distance=1200, truncate_by_edge=True, network_type="walk") # ========================================================= # PLACE IN INIT # ========================================================= take_bus_distance = 150 # in meters. this value is for lrt+bus+walk # if destination falls within this distance, user wont take a bus punggol = (1.4053828, 103.9022239) # punggol MRT station, change according to whatever coordinates you are using G = ox.graph_from_point(punggol, distance=1200, truncate_by_edge=True, network_type="walk",infrastructure='way["highway"]') G = ox.remove_isolated_nodes(G) lrt_east = ox.graph_from_file(filename="data\lrt_pg_east.osm", retain_all="true") # retain all is essential lrt_west = ox.graph_from_file(filename="data\lrt_pg_west.osm", retain_all="true") lrt_exits = ox.graph_from_file(filename="data\lrt_bridges.osm", retain_all="true") lrt_stations = nx.compose(lrt_east, lrt_west) # ========================================================= # END OF "PLACE IN INIT" requirements # =========================================================
def get_ways_for_polygon(self, polygon, section_name, source='geofabrik', way_types=['highway'], use_cache=True): """Retrieve graph of OSM nodes and ways for given polygon I tested out downloading more than just ways tagged "highway"; to also include railroads, power lines, and waterways. However osmnx only gives you intersections where there's an intersection in the original OSM data, so power lines don't have intersections because they don't cross at trail-height, and many water intersections are just missing. Because of this, I think the best way forward is to download "highway" and "railway" at first, then separately download power lines and use the NHD directly for streams. Args: - polygon: shapely polygon. Usually a buffer around trail, used to filter OSM data. - section_name: Name of section, i.e. 'CA_A' or 'OR_C' - source: either 'geofabrik' or 'overpass'. The former uses geofabrik downloads + osmconvert + osmfilter to more quickly get data extracts (after the initial Geofabrik data download). The latter uses the Overpass API through osmnx, which is considerably slower for large area requests. - way_types: names of OSM keys that are applied to ways that should be kept - use_cache: if True, attempts to use cached data. Only for source='overpass' Returns: - networkx/osmnx graph """ fname = f"{section_name}_way_types={','.join(way_types)}.graphml" graphml_path = self.raw_dir / fname if use_cache and (source == 'overpass') and (graphml_path.exists()): return ox.load_graphml(graphml_path) if source == 'geofabrik': g = self.load_geofabrik(polygon) elif source == 'overpass': # Set osmnx configuration to download desired attributes of nodes and # ways useful_tags_node = ox.settings.useful_tags_node useful_tags_node.extend(['historic', 'wikipedia']) useful_tags_path = ox.settings.useful_tags_path useful_tags_path.extend(['surface', 'wikipedia']) useful_tags_path.extend(way_types) ox.config(useful_tags_node=useful_tags_node, useful_tags_path=useful_tags_path) # Get all ways, then restrict to ways of type `way_types` # https://github.com/gboeing/osmnx/issues/151#issuecomment-379491607 g = ox.graph_from_polygon(polygon, simplify=False, clean_periphery=True, retain_all=True, network_type='all_private', truncate_by_edge=True, name=section_name, infrastructure='way') else: raise ValueError('source must be geofabrik or overpass') # strict=False is very important so that `osmid` in the resulting edges # DataFrame is never a List # Note: simplify_graph should come immediately after first creating the # graph. This is because once you start deleting some ways, there can be # empty nodes, and you get a KeyError when simplifying later. See: # https://github.com/gboeing/osmnx/issues/323 g = ox.simplify_graph(g, strict=False) # Currently the graph g has every line ("way") in OSM in the area of # polygon. I only want the ways of type `way_types` that were provided # as an argument, so find all the other-typed ways and drop them if source == 'overpass': ways_to_drop = [(u, v, k) for u, v, k, d in g.edges(keys=True, data=True) if all(key not in d for key in way_types)] g.remove_edges_from(ways_to_drop) g = ox.remove_isolated_nodes(g) # Save graph object to cache ox.save_graphml(g, graphml_path) return g
def get_network_from(region, root_path, graph_name, graph_filename): """Download network from region. If exists (check filename), try loading. Arguments: region {string} -- Location. E.g., "Manhattan Island, New York City, New York, USA" root_path {string} -- Path where graph is going to saved graph_name {string} -- Name to be stored in graph structure graph_filename {string} -- File name .graphml to be saved in root_path Returns: [networkx] -- Graph loaeded or downloaded """ # Street network G = load_network(graph_filename, folder=root_path) if G is None: # Try to download try: G = download_network(region, "drive") # Create and store graph name G.graph["name"] = graph_name print("#ORIGINAL - NODES: {} ({} -> {}) -- #EDGES: {}".format( len(G.nodes()), min(G.nodes()), max(G.nodes()), len(G.edges()))) G = ox.remove_isolated_nodes(G) # Set of nodes with low connectivity (end points) # Must be eliminated to avoid stuch vehicles (enter but cannot leave) not_reachable = set() for node in G.nodes(): # Node must be accessible by at least 10 nodes forward and backward # e.g.: 1--2--3--4--5 -- node --6--7--8--9--10 if not is_reachable(G, node, 10): not_reachable.add(node) for target in G.neighbors(node): edge_data = G.get_edge_data(node, target) keys = len(edge_data.keys()) try: for i in range(1, keys): del edge_data[i] except: pass for node in not_reachable: G.remove_node(node) # Relabel nodes G = nx.relabel_nodes(G, mapping) # Save ox.save_graphml(G, filename=graph_filename, folder=root_path) except Exception as e: print("Error loading graph:" + e) print("# NETWORK - NODES: {} ({} -> {}) -- #EDGES: {}".format( len(G.nodes()), min(G.nodes()), max(G.nodes()), len(G.edges()))) return G
simplify=False) # filter way types types = [ 'motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary', 'tertiary_link', 'unclassified', 'road' ] minor_streets = [(u, v, k) for u, v, k, d in G.edges(keys=True, data=True) if d['highway'] not in types] # remove minor streets and retain only the largest connected component subgraph G_ter = G G_ter.remove_edges_from(minor_streets) G_ter = ox.remove_isolated_nodes(G_ter) G_ter_connected = ox.get_largest_component(G_ter, strongly=True) # then simplify the graph now that we have only the edge types we want G_ter_simp = ox.simplify_graph(G_ter_connected, strict=True) # create a unique ID for each edge because osmid can # hold multiple values due to topology simplification i = 0 for u, v, k, d in G_ter_simp.edges(data=True, keys=True): d['uniqueid'] = i i += 1 # convert to two-way H = ox.get_undirected(G_ter_simp)