Mam tabelę ulic, którą wybrałem na podstawie zestawu atrybutów (powiedzmy, że to speed_limit < 25
). Istnieją grupy ulic, które są lokalnie przylegające; Chciałbym pogrupować te zestawy połączonych linii w GeometryCollections. Na poniższym obrazku byłyby dwa GeometryCollections: jeden z czerwonymi liniami i jeden z niebieskimi liniami.
Próbowałem uruchomić kilka zapytań „rozpuść, deagreguj” w następujący sposób:
SELECT (ST_Dump(st_union)).geom
FROM
(SELECT ST_Union(geom) FROM roads) sq
Ze wszystkim, co próbowałem, albo kończy się na jednej operacji ( ST_Union
) albo mojej oryginalnej geometrii ( ST_Dump
z ST_Union
).
Może można to zrobić za pomocą jakiejś WITH RECURSIVE
magii?
Odpowiedzi:
Tak na przykład. Oto prosty stół z dwoma połączonymi grupami krawędzi:
Oto funkcja rekurencyjna, która, biorąc pod uwagę identyfikator krawędzi, gromadzi wszystkie dotykające się krawędzie:
To po prostu powoduje, że musimy znaleźć, po zgromadzeniu każdej grupy, identyfikator krawędzi, która nie jest już częścią grupy. Co, tragicznie, wymaga drugiego zapytania rekurencyjnego.
Które razem wzięte zwracają ładny zestaw z identyfikatorem nasion i każdą grupą, którą zgromadził. Zostawiam to jako ćwiczenie dla czytelnika, aby przekształcić tablice id z powrotem w zapytanie, aby utworzyć geometrię do mapowania.
źródło
grouplist
tablicy:insert into lines (id, geom) values ( 15, 'LINESTRING(0 0, 10 10)');
. Zmianaarray_agg(id)
funkcji return naarray_agg(DISTINCT id)
wydaje się rozwiązać problem.Oto podejście wykorzystujące tabelę tymczasową do przyrostowego agregowania klastrów razem. Naprawdę nie dbam o podejście do tabeli tymczasowej, ale wydaje się, że działa całkiem dobrze, gdy liczba linii rośnie (mam 1,2 mln linii na wejściu).
źródło
ST_ClusterIntersecting
funkcję w PostGIS. Jeśli Twoje dane są wystarczająco małe, aby zmieściły się w pamięci, sugeruję sprawdzenie tego w celu uzyskania bardziej wydajnego rozwiązania.