Note

This page was generated from user_guide/graph/coins.ipynb.
Interactive online version: Binder badge

Continuity in street networks#

Momepy allows for the deduction of natural continuity of street networks using the COINS algorithm. The street network is split into individual segments and deflection angles between adjacent segments are computed. Segments are then joined to continuous strokes. Segments will only be considered a part of the same stroke if the deflection angle is above the threshold (defaults to zero).

Using a small network#

[1]:
import geopandas as gpd
import momepy
[2]:
streets = gpd.read_file(momepy.datasets.get_path("bubenec"), layer="streets")
[3]:
streets.plot(figsize=(10, 10)).set_axis_off()
../../_images/user_guide_graph_coins_3_0.png

momepy.COINS allows you to create a GeoDataFrame of the final merged strokes or return a Series with a stroke attribute which can be attached to the original geometry.

You first need to compute continuity using the momepy.COINS class.

[4]:
continuity = momepy.COINS(streets)

Now you can generate required outputs.

[5]:
stroke_gdf = continuity.stroke_gdf()
stroke_gdf
[5]:
n_segments geometry
stroke_group
0 8 LINESTRING (1603278.899 6463669.186, 1603283.7...
1 19 LINESTRING (1603077.5 6464475.323, 1603085.515...
2 17 LINESTRING (1603537.194 6464558.112, 1603557.6...
3 13 LINESTRING (1603706.388 6464617.784, 1603705.7...
4 5 LINESTRING (1603413.206 6464228.73, 1603274.45...
5 14 LINESTRING (1602970.377 6464268.058, 1602974.0...
6 2 LINESTRING (1603071.956 6463729.979, 1603089.0...
7 3 LINESTRING (1602959.88 6463839.712, 1602973.36...
8 3 LINESTRING (1603146.696 6463924.63, 1603157.04...
9 5 LINESTRING (1603287.304 6464587.705, 1603286.8...

We can plot the data using an unique color per stroke geometry.

[6]:
stroke_gdf.plot(cmap="tab10", figsize=(10, 10)).set_axis_off()
../../_images/user_guide_graph_coins_9_0.png
[7]:
streets["continuity_stroke"] = continuity.stroke_attribute()
[8]:
streets.head()
[8]:
geometry continuity_stroke
0 LINESTRING (1603585.64 6464428.774, 1603413.20... 0
1 LINESTRING (1603268.502 6464060.781, 1603296.8... 1
2 LINESTRING (1603607.303 6464181.853, 1603592.8... 2
3 LINESTRING (1603678.97 6464477.215, 1603675.68... 3
4 LINESTRING (1603537.194 6464558.112, 1603557.6... 2
[9]:
streets.plot(
    "continuity_stroke", categorical=True, figsize=(10, 10)
).set_axis_off()
../../_images/user_guide_graph_coins_12_0.png

Using OpenStreetMap data#

[10]:
import osmnx as ox
[ ]:
streets_graph = ox.graph_from_place(
    "Vicenza, Vicenza, Italy", network_type="drive"
)
streets_graph = ox.projection.project_graph(streets_graph)

streets = ox.graph_to_gdfs(
    ox.convert.to_undirected(streets_graph),
    nodes=False,
    edges=True,
    node_geometry=False,
    fill_edge_geometry=True,
)
/var/folders/2f/fhks6w_d0k556plcv3rfmshw0000gn/T/ipykernel_47860/1838035322.py:7: FutureWarning: The `get_undirected` function is deprecated and will be removed in the v2.0.0 release. Replace it with `convert.to_undirected` instead. See the OSMnx v2 migration guide: https://github.com/gboeing/osmnx/issues/1123
  ox.get_undirected(streets_graph),
[12]:
streets.plot(figsize=(10, 10), linewidth=0.2).set_axis_off()
../../_images/user_guide_graph_coins_16_0.png
[13]:
continuity = momepy.COINS(streets)
[14]:
stroke_gdf = continuity.stroke_gdf()

We can look into the continuity-based hierarchy of streets based on their total length.

[15]:
stroke_gdf.plot(
    stroke_gdf.length,
    figsize=(15, 15),
    cmap="viridis_r",
    linewidth=0.5,
    scheme="headtailbreaks",
).set_axis_off()
../../_images/user_guide_graph_coins_20_0.png

For details, see the original paper:

Tripathy, P., Rao, P., Balakrishnan, K., & Malladi, T. (2020). An open-source tool to extract natural continuity and hierarchy of urban street networks. Environment and Planning B: Urban Analytics and City Science. http://dx.doi.org/10.1177/2399808320967680