我想在宗地(多边形)层上进行邻接测试,并在它们符合特定条件(可能是大小)的情况下合并它们。根据下面的图片,我想合并多边形1、2、3和4,但不合并5。
我有两个问题:
ST_TOUCHES
如果仅接触角而不是线段,则返回TRUE。我想我需要ST_RELATE检查共享的线段。- 理想情况下,我想将所有相邻的多边形合并为一个,但是我不确定如何缩放到两个以上,例如在一轮中合并1,2,3和4(可能合并更多的实际数据)。
我现在拥有的结构基于上的自我联接ST_TOUCHES
。
玩具数据
CREATE TABLE testpoly AS
SELECT
1 AS id, ST_PolyFromText('POLYGON ((0 0, 10 0, 10 20, 00 20, 0 0 ))') AS geom UNION SELECT
2 AS id, ST_PolyFromText('POLYGON ((10 0, 20 0, 20 20, 10 20, 10 0 ))') AS geom UNION SELECT
3 AS id, ST_PolyFromText('POLYGON ((10 -20, 20 -20, 20 0, 10 0, 10 -20 ))') AS geom UNION SELECT
4 AS id, ST_PolyFromText('POLYGON ((20 -20, 30 -20, 30 0, 20 0, 20 -20 ))') AS geom UNION SELECT
5 AS id, ST_PolyFromText('POLYGON ((30 0, 40 0, 40 20, 30 20, 30 0 ))') AS geom ;
选拔
SELECT
gid, adj_gid,
st_AStext(st_union(l2.g1,l2.g2)) AS geo_combo
from (
--level 2
SELECT
t1.id AS gid,
t1.geom AS g1,
t2.id AS adj_gid,
t2.geom AS g2
from
testpoly t1,
testpoly t2
where
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
)
l2
这是输出:
+-----+---------+-------------------------------------------------------------------------------+
| gid | adj_gid | geo_combo |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 2 | POLYGON((10 0,0 0,0 20,10 20,20 20,20 0,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 1 | 3 | MULTIPOLYGON(((10 0,0 0,0 20,10 20,10 0)),((10 0,20 0,20 -20,10 -20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 1 | POLYGON((10 20,20 20,20 0,10 0,0 0,0 20,10 20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 3 | POLYGON((10 0,10 20,20 20,20 0,20 -20,10 -20,10 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 2 | 4 | MULTIPOLYGON(((20 0,10 0,10 20,20 20,20 0)),((20 0,30 0,30 -20,20 -20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 1 | MULTIPOLYGON(((10 0,20 0,20 -20,10 -20,10 0)),((10 0,0 0,0 20,10 20,10 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 2 | POLYGON((20 0,20 -20,10 -20,10 0,10 20,20 20,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 3 | 4 | POLYGON((20 -20,10 -20,10 0,20 0,30 0,30 -20,20 -20)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 2 | MULTIPOLYGON(((20 0,30 0,30 -20,20 -20,20 0)),((20 0,10 0,10 20,20 20,20 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 3 | POLYGON((20 0,30 0,30 -20,20 -20,10 -20,10 0,20 0)) |
+-----+---------+-------------------------------------------------------------------------------+
| 4 | 5 | MULTIPOLYGON(((30 0,30 -20,20 -20,20 0,30 0)),((30 0,30 20,40 20,40 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
| 5 | 4 | MULTIPOLYGON(((30 0,30 20,40 20,40 0,30 0)),((30 0,30 -20,20 -20,20 0,30 0))) |
+-----+---------+-------------------------------------------------------------------------------+
请注意,多边形id = 3与id = 1共享一个点,因此将其作为肯定结果返回。如果我将WHERE子句更改为ST_Touches( t1.geom, t2.geom ) AND t1.geom && t2.geom AND ST_Relate(t1.geom, t2.geom ,'T*T***T**');
我根本没有记录。
因此,首先,我如何指定ST_Relate以确保仅考虑共享线段的宗地。
然后,我如何将多边形1,2,3,4合并为一轮,从而折叠上述调用的结果,同时又认识到1到2的邻接与反向相同?
更新资料
如果将其添加到where
子句中,显然我只会得到多边形而不是多多边形,因此出于我的目的清除了误报-角触摸将被忽略。
GeometryType(st_union(t1.geom,t2.geom)) != 'MULTIPOLYGON'
尽管这不是理想的选择(我宁愿使用拓扑检查ST_RELATE
作为更通用的解决方案),但这是一种前进的道路。然后剩下去重复和合并这些问题。可能的话,如果我只能为接触的多边形生成一个序列,那么我可以对此进行合并。
更新二
这似乎适用于选择共享线(而不是角)的多边形,因此是比上述MULTIPOLYGON
测试更通用的解决方案。我的where子句现在看起来像这样:
WHERE
ST_Touches( t1.geom, t2.geom )
AND t1.geom && t2.geom
-- 'overlap' relation
AND ST_Relate(t1.geom, t2.geom)='FF2F11212') t2
现在剩下的仍然是如何对不仅仅是一对多边形的合并进行合并,而是一次性地对符合条件的任意数进行合并。
ST_IntersectionArray
[function] [1]以与ST_Union [1]一起使用:gis.stackexchange.com/a/60295/36886