Sto affrontando un problema da un paio di giorni e ho capito che molte persone rimangono bloccate quando l'argomento è l'intersezione in PostGIS (v2.5). Ecco perché ho deciso di porre una domanda più dettagliata e generica, comune.
Ho la seguente tabella:
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 );
Sembra così:
Voglio ottenere tutti i poligoni figlio in base all'intersezione dei poligoni padre. Per il risultato, ci si aspetterebbe:
- I poligoni bambini senza sovrapposizioni tra di loro.
- Una colonna contenente la somma del valore dei loro poligoni principali,
- Una colonna contenente il conteggio dei poligoni principali di una categoria
- Una colonna contenente il conteggio di un'altra categoria
- Una colonna contenente la categoria del poligono figlio, basata sulla seguente regola: -Se TUTTI i poligoni padre appartengono a una classe, anche il poligono figlio ha questa classe. Altrimenti, la categoria del poligono figlio è una terza categoria.
Quindi sarebbe simile:
Quindi, alla fine, la tabella di output generato (in questo esempio) avrà 7 righe (tutte le 7, poligoni, non sovrapposti bambino), contenenti colonne category
, sum_value
, ct_overlap_cat1
,ct_overlap_cat2
Il seguente codice che ho iniziato mi dà le singole intersezioni, confrontando un genitore con un altro.
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);
Come posso ricorrere in modo ricorsivo al risultato di questo codice citato, che, indipendentemente dal numero di poligoni sovrapposti, ottengo sempre i suoi poligoni (più piccoli) (figura 2)?