इसलिए, उदाहरण के लिए। यहां किनारों से जुड़े दो समूहों के साथ एक सरल तालिका है:
drop table lines;
create table lines ( id integer primary key, geom geometry(linestring) );
insert into lines (id, geom) values ( 1, 'LINESTRING(0 0, 0 1)');
insert into lines (id, geom) values ( 2, 'LINESTRING(0 1, 1 1)');
insert into lines (id, geom) values ( 3, 'LINESTRING(1 1, 1 2)');
insert into lines (id, geom) values ( 4, 'LINESTRING(1 2, 2 2)');
insert into lines (id, geom) values ( 11, 'LINESTRING(10 10, 10 11)');
insert into lines (id, geom) values ( 12, 'LINESTRING(10 11, 11 11)');
insert into lines (id, geom) values ( 13, 'LINESTRING(11 11, 11 12)');
insert into lines (id, geom) values ( 14, 'LINESTRING(11 12, 12 12)');
create index lines_gix on lines using gist(geom);
अब, यहाँ एक पुनरावर्ती फ़ंक्शन है, जो एक किनारे की आईडी को देखते हुए, स्पर्श करने वाले सभी किनारों को जमा करता है:
CREATE OR REPLACE FUNCTION find_connected(integer) returns integer[] AS
$$
WITH RECURSIVE lines_r AS (
SELECT ARRAY[id] AS idlist, geom, id
FROM lines
WHERE id = $1
UNION ALL
SELECT array_append(lines_r.idlist, lines.id) AS idlist,
lines.geom AS geom,
lines.id AS id
FROM lines, lines_r
WHERE ST_Touches(lines.geom, lines_r.geom)
AND NOT lines_r.idlist @> ARRAY[lines.id]
)
SELECT
array_agg(id) AS idlist
FROM lines_r
$$
LANGUAGE 'sql';
वह बस हमें खोजने की जरूरत छोड़ देता है, प्रत्येक समूह के जमा होने के बाद, एक किनारे की आईडी जो पहले से ही एक समूह का हिस्सा नहीं है। जो, दुख की बात है, एक दूसरी पुनरावर्ती क्वेरी की आवश्यकता है।
WITH RECURSIVE groups_r AS (
(SELECT find_connected(id) AS idlist,
find_connected(id) AS grouplist,
id FROM lines WHERE id = 1)
UNION ALL
(SELECT array_cat(groups_r.idlist,find_connected(lines.id)) AS idlist,
find_connected(lines.id) AS grouplist,
lines.id
FROM lines, groups_r
WHERE NOT idlist @> ARRAY[lines.id]
LIMIT 1)
)
SELECT id, grouplist
FROM groups_r;
जो एक साथ लिया एक अच्छा सेट बीज आईडी और इसे जमा प्रत्येक समूह के साथ वापसी। मैं इसे मैपिंग के लिए ज्यामिति बनाने के लिए id के सरणियों को क्वेरी में वापस करने के लिए एक अभ्यास के रूप में छोड़ता हूं।
id | grouplist
----+---------------
1 | {1,2,3,4}
11 | {11,12,13,14}
(2 rows)