Get all roundabouts GPS coordinates in a given area? [duplicate]

I am still trying to figure out OSM and OSMnx. I want to count how many roundabouts are there in Paris for example. The problem is that many roundabouts are stored as ways, but in pieces. So, if I count all the tags where junction=roundabout, I will count some roundabouts more than once.

How can I avoid this and only count each roundabout once?

# This is what I used to plot all the roundabouts in Paris
roundabouts = ox.graph_from_place('Paris, France', network_type = 'drive', 
              custom_filter = '["junction"~"roundabout"]', retain_all = True, simplify = False)
fig, ax = ox.plot_graph(roundabouts, node_size=0, bgcolor='k')
# This is what I tried to use to count the roundabouts
# 1st option
edges = ox.graph_to_gdfs(roundabouts, nodes=False, edges=True)
print('Roundabouts count:', edges.junction.count() )

# 2nd option, tried to group by OSM id and then count unique IDs
edges = ox.graph_to_gdfs(roundabouts, nodes=False, edges=True)
print('Roundabouts count:', len(edges[edges['junction']=='roundabout'].groupby('osmid').size()))

Both are wrong and I couldn't come up with a right way to do this. Can someone help out?


There is no simple straightforward way to do this, because of how OSM tags these elements. Here are two options that yield similar estimates of the number of roundabouts in a city. Either should get you onto the right track, but will require further experimentation.

import networkx as nx
import osmnx as ox
ox.config(use_cache=True)
place = 'Berkeley, CA, USA'
nt = 'drive'

# OPTION ONE
cf = '["junction"="roundabout"]'
G = ox.graph_from_place(place, network_type=nt, custom_filter=cf, retain_all=True, simplify=False)
roundabouts = list(nx.weakly_connected_components(G))
len(roundabouts) #60


# OPTION TWO
tolerance = 15
G = ox.graph_from_place(place, network_type=nt)
Gp = ox.project_graph(G)
Gc = ox.consolidate_intersections(Gp, tolerance=tolerance)

edges = ox.graph_to_gdfs(Gp, nodes=False)
roundabouts = edges[edges['junction'] == 'roundabout']

nodes = ox.graph_to_gdfs(Gc, edges=False)
nodes_in_roundabouts = nodes[nodes.buffer(tolerance).intersects(roundabouts.unary_union)]
len(nodes_in_roundabouts) #59

The former models just the roundabouts in the city, then looks for all the weakly-connected graph components. Each discrete component is considered a unique roundabout. The latter clusters (topologically consolidates) intersections, then checks to see which ones' buffers overlap a roundabout edge. See also the docs on the consolidate_intersections function.