Estou lutando com um problema por alguns dias e percebi que muitas pessoas também ficam presas quando o tópico é interseções no PostGIS (v2.5). Por isso, decidi pedir uma pergunta comum mais detalhada e genérica.
Eu tenho a seguinte tabela:
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 );
Se parece com isso:
Quero obter todos os polígonos filhos com base na interseção dos polígonos pai. Para o resultado, seria esperado:
- Os polígonos filhos sem sobreposição entre eles.
- Uma coluna contendo a soma do valor de seus polígonos principais,
- Uma coluna contendo a contagem de polígonos pai de uma categoria
- Uma coluna contendo a contagem de outra categoria
- Uma coluna contendo a categoria do polígono filho, com base na seguinte regra: -Se TODOS os polígonos pai são de uma classe, o polígono filho também possui essa classe. Senão, a categoria do polígono filho é uma terceira categoria.
Então parece:
Então, no fim, a tabela de saída gerado (para este exemplo) terá 7 linhas (todas as 7, polígonos, que não se sobrepõem criança), contendo colunas de category
, sum_value
, ct_overlap_cat1
,ct_overlap_cat2
O código a seguir, iniciado, fornece as interseções individuais, comparando um pai com outro.
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);
Como faço um loop recursivo através do resultado desse código mencionado, que, independentemente do número de polígonos sobrepostos, sempre obtenho seus polígonos 'menores' (filho) (Fig. 2)?
Suponho que se você usar o tipo de geometria de polígono em vez de MultiPolygon, tudo se encaixará:
O resultado são 9 entradas que correspondem às diferentes opções de interseção no exemplo fornecido por você.
fonte