How to create a filtered graph from an OSM-formatted XML file using OSMnx?

2k Views Asked by At

In Python, we can use a function osmnx.graph_from_place() and a filter custom_filter='["waterway"="river"]' to get a filtered graph.

import osmnx as ox
G = ox.graph_from_place("isle of man", custom_filter='["waterway"="river"]') # download directly.
fig, ax = ox.plot_graph(G, node_color='r')

I want to get a filtered graph from an OSM-formatted XML file from my disk, but the function osmnx.graph_from_xml() does not support the parameter custom_filter. How to get a filtered graph from *.osm data?

This will just plot the whole *.osm dataset:

import osmnx as ox
G = ox.graph_from_xml("isle-of-man-latest.osm") # from disk.
fig, ax = ox.plot_graph(G, node_color='r')
1

There are 1 best solutions below

4
gboeing On BEST ANSWER

OSMnx's custom_filter parameter lets you filter an Overpass query with OverpassQL to generate filtered raw data for graph construction. If you are loading a .osm file, then you are explicitly bypassing the Overpass query step to instead directly import a local file of raw data for graph construction. OSMnx constructs the graph from whatever raw data you provide it.

You have a couple options. First, you can use OSMnx's graph_from_place or graph_from_polygon functions directly to get your graph, instead of loading from a .osm file, if possible. Second, if you need to use graph_from_xml and want to filter it, you can filter it after you've constructed it:

import osmnx as ox
ox.config(use_cache=True, log_console=True)

# create a graph with more edges than you want
G = ox.graph_from_place('Piedmont, CA, USA', network_type='drive', simplify=False)

# filter graph to retain only certain edge types
filtr = ['tertiary', 'tertiary_link', 'secondary', 'unclassified']
e = [(u, v, k) for u, v, k, d in G.edges(keys=True, data=True) if d['highway'] not in filtr]
G.remove_edges_from(e)

# remove any now-disconnected nodes or subcomponents, then simplify toplogy
G = ox.utils_graph.get_largest_component(G)
G = ox.simplify_graph(G)