Zaczynając od kilku losowych punktów, w celu naśladowania tych na obrazie PO, gdzie pierwsze dwa przestrzennie przecinają się, następnie drugi i trzeci mają ten sam atrybut id (2), z kilkoma innymi punktami, które ani przecinają się przestrzennie, ani nie mają ten sam atrybut, następujące zapytanie tworzy 3 klastry:
WITH
temp (id, geom) AS
(VALUES (1, ST_Buffer(ST_Makepoint(0, 0), 2)),
(2, ST_Buffer(ST_MakePoint(-0.7,0.5), 2)),
(2, ST_Buffer(ST_MakePoint(10, 10), 2)),
(3, ST_Buffer(ST_MakePoint(-2, 12), 2)),
(4, ST_Buffer(ST_MakePoint(5, -6), 2))),
unions(geoms) AS
(SELECT ST_Union(geom) FROM temp GROUP BY id),
clusters(geoms) AS
(SELECT ST_CollectionExtract(unnest(ST_ClusterIntersecting(geoms)), 3)
FROM unions),
multis(id, geoms) AS
(SELECT row_number() over() as id, geoms FROM clusters)
SELECT ST_UNION(d.geom) FROM
(SELECT id, (ST_DUMP(geoms)).geom FROM multis) d GROUP BY id;
Tutaj jest kilka kroków:
- użyj
ST_Union
, pogrupuj według identyfikatora, aby najpierw pogrupować według atrybutu
- Użyj,
ST_ClusterIntersecting
aby połączyć te z tej samej grupy, które przecinają się przestrzennie
- dodaj identyfikator do każdego z klastrów (tabela multis) - próba zrobienia tego bezpośrednio w ClusterIntersecting prowadzi do uzyskania przez wszystkie geometrie id 1
- Połącz zrzucone geometrie z kroku 2, grupując według id z kroku 3 - jest to część rozpuszczania . Powoduje to, że dwa nakładające się wielokąty w klastrze A łączą się ze sobą, zamiast się nakładać, ponieważ znajdują się na końcu kroku 2.
Dość długo, ale działa (i jestem pewien, że jest krótsza droga).
Za pomocą narzędzia WKT w QGIS (i odkrywając, jak okropnie jestem z narzędziami do edycji), powstają klastry takie jak poniżej, w których widać klaster oznaczony jako a, wszystko razem - tzn. Jeden kolor.
Jeśli umieścisz ST_AsText w finale, ST_UNION (d.geom), możesz zobaczyć wyniki bezpośrednio.
EDYTUJ następujące informacje w komentarzach: Gdy zaczynasz od punktów, musisz włączyć bufor do mojego oryginalnego rozwiązania - które umieszczam w temp CTE na początku, aby naśladować twój schemat. Łatwiej byłoby dodać bufor w związkach CTE, dzięki czemu można wykonywać wszystkie geometrie jednocześnie. Tak więc, przykładowo, używając odległości bufora 1000, teraz zwraca 3 klastry, zgodnie z oczekiwaniami.
WITH temp(id, geom) AS
(VALUES
(1, ST_SetSRID(ST_GeomFromText('MultiPoint(12370 361685)'), 31256)),
(2, ST_SetSRID(ST_GeomFromText('MultiPoint(13520 360880, 19325 364350)'), 31256)),
(3, ST_SetSRID(ST_GeomFromText('MultiPoint(11785 367775)'), 31256)),
(4, ST_SetSRID(ST_GeomFromText('MultiPoint(19525 356305)'), 31256))
),
unions(geoms) AS
(SELECT st_buffer(ST_Union(geom), 1000) FROM temp GROUP BY id),
clusters(geoms) AS
(SELECT ST_CollectionExtract(unnest(ST_ClusterIntersecting(geoms)), 3)
FROM unions),
multis(id, geoms) AS
(SELECT row_number() over() as id, geoms FROM clusters)
SELECT id, ST_UNION(d.geom) FROM
(SELECT id, (ST_DUMP(geoms)).geom FROM multis) d GROUP BY id;