Saya sudah membuat buffer terlarut dari fitur input multi-point. Dalam contoh di bawah ini, tabel input berisi 4 fitur. Fitur #2
terdiri dari dua titik geometri. Setelah membuat buffer, saya mendapatkan 4 geometri poligon:
Apakah ada cara untuk mengelompokkan hasilnya? Buffer titik #1
dan #2
dilarutkan dan harus menjadi fitur multi-poligon tunggal ( a
).
Apa yang telah saya lakukan sejauh ini:
-- collect all buffers to a single multi-polygon feature
-- dissolve overlapping polygon geometries
CREATE TABLE public.pg_multibuffer AS SELECT
row_number() over() AS gid,
sub_qry.*
FROM (SELECT
ST_Union(ST_Buffer(geom, 1000, 8))::geometry(MultiPolygon, /*SRID*/) AS geom
FROM
public.multipoints)
AS sub_qry;
EDIT:
-- create sample geometries
CREATE TABLE public.multipoints (
gid serial NOT NULL,
geom geometry(MultiPoint, 31256),
CONSTRAINT multipoints_pkey PRIMARY KEY (gid)
);
CREATE INDEX sidx_multipoints_geom
ON public.multipoints
USING gist
(geom);
INSERT INTO public.multipoints (gid, geom) 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));
Jawaban:
Dimulai dengan beberapa titik acak, dalam upaya meniru orang-orang di gambar OP, di mana dua spasial pertama berpotongan, kemudian ke-2 dan ke-3 memiliki atribut id yang sama (2), dengan beberapa titik lain yang tidak berpotongan secara spasial atau memiliki atribut yang sama, permintaan berikut menghasilkan 3 cluster:
Ada beberapa langkah di sini:
ST_Union
, pengelompokan berdasarkan id, ke grup pertama berdasarkan atributST_ClusterIntersecting
untuk menggabungkan mereka dari kelompok yang sama yang bersinggungan secara spasialAgak panjang, tapi berhasil (dan, saya yakin ada jalan yang lebih pendek).
Menggunakan alat WKT di QGIS, (dan menemukan betapa buruknya saya dengan alat pengeditan) menghasilkan cluster seperti berikut, di mana Anda dapat melihat cluster yang Anda beri label sebagai, semuanya bersama-sama - yaitu satu warna.
Jika Anda meletakkan ST_AsText di babak final, ST_UNION (d.geom), maka Anda dapat melihat hasilnya secara langsung.
Sunting berikut informasi lebih lanjut di komentar: Ketika Anda mulai dengan poin Anda akan perlu memasukkan buffer ke dalam solusi asli saya - yang saya masukkan ke dalam CTE temp di awal untuk meniru diagram Anda. Akan lebih mudah untuk menambahkan buffer di CTE serikat pekerja, sehingga Anda dapat melakukan semua geometri sekaligus. Jadi, dengan menggunakan jarak buffer 1000, sebagai contoh, yang berikut sekarang mengembalikan 3 cluster, seperti yang diharapkan.
sumber
ST_SetSRID
,ST_Multi
dan::geometry(Multipolygon, /*SRID*/)
, tetapi saat ini tidak berfungsi.Salah satu cara untuk melakukan ini adalah untuk
ST_Union
semua buffer bersama-sama,ST_Dump
hasil untuk mendapatkan komponen dari poligon yang dihasilkan, dan bergabung denganST_Intersects
kembali ke titik input untuk menemukan berapa banyak / poin mana yang membentuk setiap cluster.Ini bisa dilakukan tanpa perlu bergabung dengan mengelompokkan poin bersama sebelum menelepon
ST_Buffer
. Untuk dua titik yang terletak di dalam buffer terlarut yang sama, mereka harus dapat dicapai dengan melompat antara titik-titik yang jaraknya kurang darieps
. Ini hanya masalah pengelompokan tautan minimum, yang dapat diselesaikan menggunakanST_ClusterDBSCAN
:Perhatikan bahwa ini tidak akan menghasilkan hasil yang sama persis dengan metode buffer-first, karena buffer PostGIS tidak lingkaran sempurna dan terpisah dua poin 1000m mungkin tidak terhubung oleh dua buffer 500m.
sumber
Menurut jawaban ini, Anda ingin melakukan ST_DUMP dalam subquery Anda.
Sesuatu seperti ini:
Alasan mengapa hal itu
ST_UNION
mengembalikan multipoligon terlarut dari semua fitur, danST_DUMP
memecah ini menjadi fitur poligon individu (yang dibubarkan).sumber
ST_Multi((ST_Dump(ST_Union(ST_Buffer(geom, 1000, 8)))).geom)::geometry(MultiPolygon, /*SRID*/) AS geom
, tetapi ini membuat 4 fitur bukannya 3.GROUP_BY
sebelum AndaST_UNION
.