I'm struggling with a problem for a couple of days and realized many people also get stuck when the topic is intersections in PostGIS (v2.5). That's why I decided to ask for a more detailed and generic, common question.
I have the following table:
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 );
It looks like this:
I want to get all the child polygons based on the intersection of the parent polygons. For the outcome, it'd be expected:
- The child polygons with no overlap between them.
- An column containing the sum of the value of their parent polygons,
- An column containing the count of parent polygons of one category
- An column containing the count of another category
- An column containing the category of the child polygon, based on the following rule: -If ALL the parent polygons are from one class, the child polygon also have this class. Else, the category of the child polygon is a third category.
So it'd looks like it:
So, in the end, the output table generated (for this example) will have 7 rows (all the 7, non-overlapping, child polygons), containing columns of category
, sum_value
, ct_overlap_cat1
, ct_overlap_cat2
The following code I started, gives me the individual intersections, comparing one parent with another.
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);
How do I recursively loop through the result of this mentioned code, that, independent of the number of overlap polygons I always get its 'smallest' (child) polygons (Fig. 2)?