我有一个带有 id、几何形状的表,其中几何形状的类型为线串或多线串。 我想将所有相互连接的线串分组。例如
Id geometry
1 linestring(a, b)
2 linestring(b, c)
3 linestring(b, d)
4 linestring(e, f)
那么结果应该是
Id geometry
1,2,3 linestring(a,b,c,d)
4 linestring(e, f)
我尝试做
st_intersects
和 st_union
,这给出了仅一行的多行字符串。
select STRING_AGG(t.id::TEXT, ', '), st_union(t.geom) from table t
group by ST_intersects(t.geom, t.geom)
一定要喜欢它们的递归 CTE 🥰
WITH RECURSIVE some_points AS (
SELECT
ST_MakePoint(0, 0) AS a,
ST_MakePoint(1, 0) AS b,
ST_MakePoint(2, 0) AS c,
ST_MakePoint(1, 1) AS d,
ST_MakePoint(0, 2) AS e,
ST_MakePoint(1, 2) AS f
), some_lines AS (
SELECT
UNNEST(ARRAY[1,2,3,4]) AS id,
UNNEST(ARRAY[
ST_MakeLine(a, b),
ST_MakeLine(b, c),
ST_MakeLine(b, d),
ST_MakeLine(e, f)
]) AS geom
FROM some_points
), paths AS ( -- for each line segment add connected line segments recursively
SELECT id AS path_id, 1 AS degree, ARRAY[id] AS ids, geom
FROM some_lines
UNION ALL
SELECT p.path_id, degree + 1, ARRAY_APPEND(p.ids, l.id), ST_Union(p.geom, l.geom)
FROM paths AS p
INNER JOIN some_lines AS l
ON ST_Intersects(p.geom, l.geom)
AND NOT ST_Contains(p.geom, l.geom)
), paths_expanded AS ( -- expand paths so we can order them
SELECT
array_to_string(ids, ',') AS path_variation_id,
geom,
degree,
MAX(degree) OVER(PARTITION BY path_id) AS max_degree,
UNNEST(ids) AS id
FROM paths
), full_paths_ordered AS ( -- order full paths so we can remove duplicates
SELECT path_variation_id, geom, ARRAY_AGG(id ORDER BY id) AS ids
FROM paths_expanded
WHERE degree = max_degree
GROUP BY path_variation_id, geom
) -- remove duplicate paths
SELECT DISTINCT ON(ids) ids, ST_AsText(geom) AS wkt
FROM full_paths_ordered
ORDER BY ids, path_variation_id;