Przez kilka dni borykam się z problemem i zdałem sobie sprawę, że wiele osób również utknęło, gdy tematem są skrzyżowania w PostGIS (v2.5). Dlatego postanowiłem zadać bardziej szczegółowe i ogólne, wspólne pytanie.
Mam następującą tabelę:
DROP TABLE IF EXISTS tbl_foo;
CREATE TABLE tbl_foo (
id bigint NOT NULL,
geom public.geometry(MultiPolygon, 4326),
att_category character varying(15),
att_value integer
);
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(1, ST_SetSRID('MULTIPOLYGON (((0 6, 0 12, 8 9, 0 6)))'::geometry,4326) , 'cat1', 2 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(2, ST_SetSRID('MULTIPOLYGON (((5 0, 5 12, 9 12, 9 0, 5 0)))'::geometry,4326), 'cat1', 1 );
INSERT INTO tbl_foo (id, geom, att_category, att_value) VALUES
(3, ST_SetSRID('MULTIPOLYGON (((4 4, 3 8, 4 12, 7 14,10 12, 11 8, 10 4, 4 4)))'::geometry,4326) , 'cat2', 5 );
To wygląda tak:
Chcę uzyskać wszystkie wielokąty potomne na podstawie przecięcia wielokątów macierzystych. Do wyniku należałoby się spodziewać:
- Wielokąty potomne bez nakładania się między nimi.
- Kolumna zawierająca sumę wartości ich macierzystych wielokątów,
- Kolumna zawierająca liczbę wielokątów macierzystych jednej kategorii
- Kolumna zawierająca liczbę innej kategorii
- Kolumna zawierająca kategorię wielokąta potomnego, w oparciu o następującą regułę: -Jeśli WSZYSTKIE wielokąty macierzyste pochodzą z jednej klasy, wielokąt potomny również ma tę klasę. W przeciwnym razie kategoria wielokąta potomnego jest trzecią kategorią.
Wygląda to tak:
Tak, w końcu, stół wyjściowy generowany (w tym przykładzie) będzie miał 7 wierszy (wszystkie 7, nie pokrywających, wielokątów dziecko), zawierające kolumny category
, sum_value
, ct_overlap_cat1
,ct_overlap_cat2
Poniższy kod, który uruchomiłem, podaje mi poszczególne skrzyżowania, porównując jednego rodzica z drugim.
SELECT
(ST_Dump(
ST_SymDifference(a.geom, b.geom)
)).geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom)
UNION ALL
SELECT
ST_Intersection(a.geom, b.geom) as geom
FROM tbl_foo a, tbl_foo b
WHERE a.ID < b.ID AND ST_INTERSECTS(a.geom, b.geom);
Jak rekurencyjnie zapętlać wynik tego wspomnianego kodu, aby niezależnie od liczby nakładających się wielokątów zawsze otrzymywałem jego „najmniejsze” (potomne) wielokąty (ryc. 2)?
Podejrzewam, że jeśli użyjesz geometrii wielokąta zamiast MultiPolygon, wszystko się ułoży:
Wynikiem jest 9 wpisów, które odpowiadają różnym opcjom przecięcia w podanym przez Ciebie przykładzie.
źródło