Note
The model situation expects to have all input data for analysis in GeoDataFrames, including street network (e.g. from shapefile).
GeoDataFrames
[1]:
import momepy import geopandas as gpd import matplotlib.pyplot as plt import networkx as nx
[2]:
streets = gpd.read_file(momepy.datasets.get_path('bubenec'), layer='streets')
[3]:
f, ax = plt.subplots(figsize=(10, 10)) streets.plot(ax=ax) ax.set_axis_off() plt.show()
We have to convert this LineString GeoDataFrame to networkx.Graph. We use momepy.gdf_to_nx and later momepy.nx_to_gdf as pair of interconnected functions. gdf_to_nx supports both primal and dual graphs. Primal approach will save length of each segment to be used as a weight later, while dual will save the angle between segments (allowing angular centrality).
networkx.Graph
momepy.gdf_to_nx
momepy.nx_to_gdf
gdf_to_nx
[4]:
graph = momepy.gdf_to_nx(streets, approach='primal')
[5]:
nx.draw(graph)
[6]:
dual = momepy.gdf_to_nx(streets, approach='dual') nx.draw(dual)
At this moment (almost) any networkx method can be used. For illustration, we will measure the node degree. Using networkx, we can do:
networkx
[7]:
degree = dict(nx.degree(graph)) nx.set_node_attributes(graph, degree, 'degree')
However, node degree is implemented in momepy so we can use directly:
[8]:
graph = momepy.node_degree(graph, name='degree')
Once we have finished our network-based analysis, we want to convert the graph back to geodataframe. For that, we will use momepy.nx_to_gdf, which gives us several options what to export.
lines
original LineString geodataframe
points
point geometry representing street network intersections (nodes of primal graph)
spatial_weights
spatial weights for nodes capturing their relationship within a network
Moreover, edges will contain node_start and node_end columns capturing the ID of both nodes at its ends.
edges
node_start
node_end
[9]:
nodes, edges, sw = momepy.nx_to_gdf(graph, points=True, lines=True, spatial_weights=True)
[10]:
f, ax = plt.subplots(figsize=(10, 10)) nodes.plot(ax=ax, column='degree', cmap='tab20b', markersize=(nodes['degree'] * 100), zorder=2) edges.plot(ax=ax, color='lightgrey', zorder=1) ax.set_axis_off() plt.show()
[11]:
nodes.head(3)
[12]:
edges.head(3)