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)?