I am trying to transform all the roundabouts in a city into simple intersections/crossroads (o -> +). As I am using OpenStreetMap for the initial topology, some roundabouts are not a circle but just the segments of the circle (Ex: https://www.openstreetmap.org/#map=18/43.34516/-8.41536).
In practice the problem is that I need the centroid of each roundabout and I get it almost in all cases but sometimes I get several centroids for the same roundabout (centroids of the arches, no the full roundabout).
I have achieved this:
select f.osm_id as fid, (select ST_CENTROID(ST_Buffer(ST_UNION(way),1)) as r_geom
from planet_osm_line d
where st_intersects(f.way, d.way) and junction = 'roundabout') as rotonda
from planet_osm_line f
where junction like 'roundabout';
But this does not resolve the problem, it only reduces it. I am not getting the full circle, just bigger segments of it.
So I guess I need a recursive query in order to do this until the number of geometries retrieved remains the same (the full circle). Any ideas about how to build this query?
I was looking for something like this (hope it helps others in need):
create table no_roundabouts as
with recursive roundabout(geom) as (--Recursive function to build closed circled roundabouts even with roundabouts mapped as differents arches.
SELECT ST_TRANSFORM(way,3857)
FROM planet_osm_line ways --Get all segments tagged as 'roundabout'
WHERE ways.junction = 'roundabout'
UNION ALL
SELECT ST_TRANSFORM(ST_UNION(ways.way, roundabout.geom),3857)
FROM roundabout, planet_osm_line ways -- Compose segments building greater arches of the roundabout until we have the full circle (My_segment + a touching segment that is no contained in my segment)
WHERE ways.junction = 'roundabout' and ST_INTERSECTS(roundabout.geom, ways.way) and not ST_CONTAINS(roundabout.geom, ways.way)
)
SELECT * FROM roundabout;
alter table no_roundabouts add column id bigserial; -- Add id to each line
delete from no_roundabouts a -- Delete repeated roundabouts generated during recursion
where exists (select geom from no_roundabouts b where ST_CONTAINS(b.geom, a.geom) and b.id > a.id);
--select count(*) from no_roundabouts WHERE ST_IsClosed(geom) = false;
update no_roundabouts set geom = ST_LINEMERGE(geom) where ST_ISCLOSED(geom) is false --Force closed roundabouts
-- Query replacing roundabouts with crossroads (linking each way in and out with the centroid of the roundabout)
SELECT ST_TRANSFORM(ST_ADDPOINT(y.way, ST_CENTROID(x.geom), 0),4326)
FROM no_roundabouts x JOIN planet_osm_line y ON ST_INTERSECTS(y.way, x.geom)
WHERE y.highway is not null and ST_INTERSECTS(x.geom, st_pointn(y.way,1)) and ST_CONTAINS(x.geom, y.way) = false
UNION
SELECT ST_TRANSFORM(ST_ADDPOINT(y.way, ST_CENTROID(x.geom), -1),4326)
FROM no_roundabouts x JOIN planet_osm_line y ON ST_INTERSECTS(y.way, x.geom)
WHERE y.highway is not null and ST_INTERSECTS(x.geom, ST_POINTN(y.way,-1)) and ST_CONTAINS(x.geom, y.way) = false;