{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Simplification of roundabouts\n", "\n", "Analysis using street network can be sensitive to the actual geometry representation. For example, one roundabout can be typically represented as 4 or more nodes, while it is topologically only one. Hence measurements attempting to capture topology (e.g. centrality) or node density will be skewed.\n", "\n", "The following code exemplifies a simple process for road network simplification of roundabouts using `momepy.roundabout_simplification()`.\n", "\n", "For this example we will fetch some data from [OpenStreetMap](https://www.openstreetmap.org/#map=6/40.007/-2.488) (using `osmnx`). However, most other data sources should also work as long as their topology has been corrected and can be stored in a GeoDataFrame." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2024-06-14T22:02:47.909114Z", "iopub.status.busy": "2024-06-14T22:02:47.909016Z", "iopub.status.idle": "2024-06-14T22:02:49.229671Z", "shell.execute_reply": "2024-06-14T22:02:49.229332Z" } }, "outputs": [], "source": [ "import geopandas as gpd\n", "import matplotlib.pyplot as plt\n", "import momepy as mm\n", "import osmnx as ox" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load data\n", "Using `osmnx` download a neighborhood and reproject to its local CRS.\n", "\n", "Two things are required to achieve good results:\n", "1. Reproject the network to a projected CRS (in meters)\n", "1. Transform the graph to an undirected graph:\n", " - This helps to remove overlapping LineStrings once moving to GeoDataFrame.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2024-06-14T22:02:49.232043Z", "iopub.status.busy": "2024-06-14T22:02:49.231739Z", "iopub.status.idle": "2024-06-14T22:02:49.939538Z", "shell.execute_reply": "2024-06-14T22:02:49.939295Z" } }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/2f/fhks6w_d0k556plcv3rfmshw0000gn/T/ipykernel_93551/3487061367.py:3: FutureWarning: The buffer_dist argument has been deprecated and will be removed in the v2.0.0 release. Buffer your query area directly, if desired. See the OSMnx v2 migration guide: https://github.com/gboeing/osmnx/issues/1123\n", " G = ox.graph_from_place(\n", "/Users/martin/miniforge3/envs/momepy/lib/python3.11/site-packages/osmnx/graph.py:381: FutureWarning: The buffer_dist argument has been deprecated and will be removed in the v2.0.0 release. Buffer your results directly, if desired. See the OSMnx v2 migration guide: https://github.com/gboeing/osmnx/issues/1123\n", " gdf_place = geocoder.geocode_to_gdf(\n", "/Users/martin/miniforge3/envs/momepy/lib/python3.11/site-packages/osmnx/graph.py:392: FutureWarning: The 'unary_union' attribute is deprecated, use the 'union_all()' method instead.\n", " polygon = gdf_place[\"geometry\"].unary_union\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "/var/folders/2f/fhks6w_d0k556plcv3rfmshw0000gn/T/ipykernel_93551/3487061367.py:9: 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\n", " ox.get_undirected(G_projected), # prevents some (semi)duplicate geometries\n" ] }, { "data": { "text/html": [ "
| \n", " | \n", " | \n", " | osmid | \n", "oneway | \n", "name | \n", "highway | \n", "reversed | \n", "length | \n", "from | \n", "to | \n", "geometry | \n", "maxspeed | \n", "lanes | \n", "bridge | \n", "width | \n", "access | \n", "tunnel | \n", "junction | \n", "
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| u | \n", "v | \n", "key | \n", "\n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " | \n", " |
| 21990706 | \n", "21990729 | \n", "0 | \n", "390868364 | \n", "True | \n", "Calle de Mejía Lequerica | \n", "residential | \n", "False | \n", "60.664 | \n", "21990706 | \n", "21990729 | \n", "LINESTRING (440818.925 4475309.73, 440776.64 4... | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "
| 21990729 | \n", "25906109 | \n", "0 | \n", "44884571 | \n", "True | \n", "Calle de Mejía Lequerica | \n", "residential | \n", "False | \n", "35.206 | \n", "21990729 | \n", "25906109 | \n", "LINESTRING (440776.64 4475353.246, 440750.521 ... | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "
| 25906107 | \n", "0 | \n", "163743121 | \n", "True | \n", "Calle de la Beneficencia | \n", "residential | \n", "False | \n", "65.736 | \n", "21990729 | \n", "25906107 | \n", "LINESTRING (440776.64 4475353.246, 440825.335 ... | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "NaN | \n", "