递归 PostGIS 查询
Recursive PostGIS query
我正在尝试将城市中的所有环形交叉路口转换为简单的 intersections/crossroads (o -> +)。由于我将 OpenStreetMap 用于初始拓扑,因此一些环岛不是圆而是圆的一部分(例如:https://www.openstreetmap.org/#map=18/43.34516/-8.41536)。
在实践中,问题是我需要每个环形交叉路口的质心,几乎在所有情况下我都能得到它,但有时我会为同一个环形交叉路口获得多个质心(拱门的质心,没有完整的环形交叉路口)。
我已经做到了:
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';
但这并没有解决问题,只是减少了问题。我没有得到完整的圆圈,只是更大的部分。
所以我想我需要一个递归查询才能执行此操作,直到检索到的几何图形数量保持不变(完整的圆圈)。关于如何构建此查询的任何想法?
我一直在寻找这样的东西(希望它能帮助有需要的人):
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;
我正在尝试将城市中的所有环形交叉路口转换为简单的 intersections/crossroads (o -> +)。由于我将 OpenStreetMap 用于初始拓扑,因此一些环岛不是圆而是圆的一部分(例如:https://www.openstreetmap.org/#map=18/43.34516/-8.41536)。
在实践中,问题是我需要每个环形交叉路口的质心,几乎在所有情况下我都能得到它,但有时我会为同一个环形交叉路口获得多个质心(拱门的质心,没有完整的环形交叉路口)。
我已经做到了:
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';
但这并没有解决问题,只是减少了问题。我没有得到完整的圆圈,只是更大的部分。
所以我想我需要一个递归查询才能执行此操作,直到检索到的几何图形数量保持不变(完整的圆圈)。关于如何构建此查询的任何想法?
我一直在寻找这样的东西(希望它能帮助有需要的人):
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;