在应用过程中,“我认为的”,1个点明明落在了2个多面上,结果却不同。其实你会发现,坐标点的数据是一样的,但是定义的方法不同,导致结果不同。
--基础数据--
CREATE TABLE public.test_geometry_4490 (
id serial4 NOT NULL PRIMARY KEY,
geom public.geometry(geometry, 4490) NULL
);
--线行环(挖洞)
insert into test_geometry_4490 values (2,'MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5), (2 3,2 4,4 4,4 3,2 3)))')
--多面
insert into test_geometry_4490 values (1,'MULTIPOLYGON (((1 5, 5 5, 5 1, 1 1, 1 5)), ((2 3,2 4,4 4,4 3,2 3)))')
--查询--
select ST_Intersects(geom,ST_GeomFromText('POINT(3.5 3.5)',4490)) from test_geometry_4490
结果是:第一行不相交(挖洞了),第二行相交(多面以最大为主)。请继续往下看
1 | f |
2 | t |
可能只看坐标点不够直观,大家看下图
其实使用web呈现来看,2个图是一样的,因为多面不管如何定义,转成web的geojson都一样,所以这也不怪web端。但是在数据库中的拓扑关系容不得一点马虎。
postgis官方文档
多边形是二维平面区域,它有一个外部边界(壳)和零个或多个内部边界(孔)分隔,每个边界都是线性环。
POLYGON (
(0 0 ,4 0 ,4 4 ,0 4 ,0 0 ),--多边形外环
(1 1 ,2 1 ,2 2 ,1 2 ,1 1) --多边形内环
)
通俗来说,这种多边形定义方式就是2个环,前面大,后面小,后面在前面的中间“挖洞”,“洞”里的空间不属于这个多边形。
如图所示,像这种“挖洞”的双环,大环是A边界,小环是B的边界,挖出的洞就是B边界内的空间。
所以说B空间内的区域,和这个多边形“不相交” 。
这个多边形的面积就是A边界和B边界内的空间。
多面是非重叠、不相邻多边形的集合。集合中的多边形只能在有限数量的点处接触。
注意,多面的定义有2种,
第1种是“挖洞”,就是上面Polygon多边形定义。
第2种定义是都个面。
他们的区别就是括号的位置。出现2对(())是一个图形。1对()就是“挖洞”多边形。
MULTIPOLYGON ((
(0 0 ,4 0 ,4 4 ,0 4 ,0 0 ),--第一个多边形环
(1 1 ,2 1 ,2 2 ,1 2 ,1 1) --第二个多边形环
))
MULTIPOLYGON (
((1 5, 5 5, 5 1, 1 1, 1 5)), --这是第一个多边形
((6 5, 9 1, 6 1, 6 5)) --这是第二个多边形
)
多面定义意义在于,每个(())里面都是一个完整的多边形,这里定义了2个多边形。
如果定义的2个多边形存在包含,那么以做大的为主。
引用chatgpt的回答,我觉得很准确。
所以这也解释了为什么,我的POINT落在2条“数据一样”的多面上,结果却不同。