我在问题上挣扎了几天,意识到当主题是PostGIS(v2.5)中的交叉点时,很多人也陷入困境。因此,我决定提出一个更详细,更通用的常见问题。
我有下表:
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 );
看起来像这样:
我想基于父多边形的交集获得所有子多边形。对于结果,可以预期:
- 子多边形之间没有重叠。
- 包含其父多边形值之和的列,
- 包含一个类别的父多边形数量的列
- 包含其他类别计数的列
- 根据以下规则,包含子多边形类别的列:-如果所有父多边形都来自一个类别,则子多边形也具有该类别。否则,子多边形的类别是第三类别。
所以看起来像这样:
因此,在结束时,产生的输出表(在这个例子中)将具有7行(所有7,非重叠,子多边形),包含的列category
,sum_value
,ct_overlap_cat1
,ct_overlap_cat2
我开始的以下代码为我提供了各个交集,将一个父级与另一个父级进行比较。
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);
我如何递归遍历上述代码的结果,即与重叠多边形的数量无关,我总是得到其“最小”(子)多边形(图2)?