Comments (8)
I think this solution is fast, powerful, and useful enough that I'll bake it into OSMnx directly. It'll be pushed shortly and released in the upcoming minor version.
from osmnx.
@kuanb @kelanstoy see OSMnx's new clean_intersections function and this example notebook demonstrating it.
from osmnx.
This is primarily an issue with the data model that OSM (and TIGER/Line shapefiles, etc) use to represent street networks. Generally, divided roads get represented as separate centerline edges. I've floated some ideas for dealing with this from a geometric perspective (see #12) but dealing with it topologically is a different story and probably outside the scope of OSMnx for now.
from osmnx.
@kelanstoy @kuanb here's a simple solution using the geometric dissolve method I suggested in #12:
import osmnx as ox, matplotlib.pyplot as plt, numpy as np, geopandas as gpd
# get a street network and plot it with all edge intersections
address = '2700 Shattuck Ave, Berkeley, CA'
G = ox.graph_from_address(address, network_type='drive', distance=750)
G_proj = ox.project_graph(G)
fig, ax = ox.plot_graph(G_proj, fig_height=10, node_color='orange', node_size=30,
node_zorder=2, node_edgecolor='k')
# clean up intersections by buffering 15 meters, dissolving, and using centroid
gdf_nodes = ox.graph_to_gdfs(G_proj, edges=False)
buff = gdf_nodes.buffer(15)
unified = gpd.GeoDataFrame(geometry=list(buff.unary_union))
intersections = unified.centroid
# plot the cleaned-up intersections
fig, ax = ox.plot_graph(G_proj, fig_height=10, show=False, close=False, node_alpha=0)
points = np.array([point.xy for point in intersections])
ax.scatter(x=points[:,0], y=points[:,1], zorder=2, color='#66ccff', edgecolors='k')
plt.show()
...and you get something like this: before (left) and after (right):
It doesn't fix the topology (i.e., reconnect all the streets to the new intersection point), but it improves the intersection density counts.
from osmnx.
Just to add my solution here for anyone else interested in dealing with this, I set up a simple for loop that (hopefully) should not get "out of control" with larger datasets.
Here's what the results look like with a small subset of data:
The gist is here with the most critical bit of code in lines 40 - up.
Basically, I create a boolean column and for loop through the geodataframe, marking "off" any intersections whose buffer intersects the one being currently reviewed. As I move through the whole geodataframe, I skip any rows that have already been marked as "off," thereby avoiding repeating the intersection test on any of an already reviewed intersection's "siblings."
# set a bool column to track which intersections to use
gdf_nodes['use'] = True
list_of_nodes = gdf_nodes.index.values
for node_id in list_of_nodes:
current = gdf_nodes.loc[node_id]
# only proceed if has not already been marked as False (don't use)
if current['use']:
ints_with = gdf_nodes.intersects(current.geometry)
# review intersecting buffered nodes
sub_gdf = gdf_nodes[ints_with]
sub_gdf_sans_current = sub_gdf[sub_gdf.index != node_id]
# get the indexes of other rows and 'turn them off'
turn_these_off = sub_gdf_sans_current.index.values
for sub_node_id in turn_these_off:
gdf_nodes.loc[sub_node_id, 'use'] = False
# here is a dataframe of unique geometries
cleaned_ints = gdf_nodes[gdf_nodes['use'] == True]
from osmnx.
Fantastic!
So a plain language interpretation of your methodology:
- Convert network to GeoDataFrame
- Create a GeoSeries of buffered nodes (in your case, 15 meters)
- Perform a unary union on the GeoSeries (I presume a MultiPolygon is returned)
- Extract all centroids from aforementioned MultPolygon
from osmnx.
Update - Geoff's method took under 2 minutes whereas for the for
loop method took over 30 minutes!
from osmnx.
Nice, thanks!!
from osmnx.
Related Issues (20)
- Add edge_attrs_differ argument to each graph.graph_from_* method HOT 2
- Add support for implicit maxspeed values
- `ox.shortest_path` returns `None` HOT 3
- Add function to merge parallel roads HOT 4
- Publish v2 pre-releases HOT 1
- Issues with plotting and basic stats when using DiGraphs HOT 1
- AttributeError: module 'osmnx' has no attribute 'convert' HOT 1
- InsufficientResponseError while HOT 1
- FutureWarning: The 'unary_union' attribute is deprecated HOT 4
- Issue with graph_from_bbox on Visual Studio code. HOT 5
- plot_graph raises an MPL error while running in a remote Linux machine HOT 1
- Change bounding box coordinates' order for v2.0.0? HOT 2
- Graph route animations HOT 3
- `consolidate_intersections` crashes with dictionary for tolerances HOT 4
- Bounding Box doesn't work in ox.features_from_bbox(bbox, tags) HOT 1
- We need a fucntion that can generate gdf_nodes and gdf_edges from locallly downloaded road network loaded using geopandas as gdf HOT 3
- No Modules 1.9.3 HOT 1
- Unions filter HOT 5
- Optimize _remove_polygon_holes function for improved performance with complex geometries HOT 9
- Response Error for some network types/cities HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from osmnx.