MySQL使用ST_Contains函数返回错误结果

3

我正在使用MySQL ST_Contains来确定一个区域是否被另一个区域包含。因此,我有一个类似这样的表:

CREATE TABLE tablex (id int, geoPoly MULTIPOLYGON NOT NULL, SPATIAL INDEX(geoPoly))

为了找出某个区域包含哪些区域,我使用以下查询:
SELECT b.* FROM tablex as a 
LEFT JOIN tablex as b  ON ST_CONTAINS(b.geoPoly, a.geoPoly) 
WHERE a.intID = 123 

这对大多数情况都有效,但有一种特殊情况会给出错误的答案:
我从 OpenStreetMap 复制了奥地利 Bregenz 和 Mellau 地区的地理坐标。Mellau 包含在 Bregenz 中。但是上面的查询说 Mellau 被包含了但不在 Bregenz 中(这显然是不正确的)。两个形状在左侧使用相同的“路径”作为公共边界,在右侧,Bregenz 比 Mellau 大得多。
在地图上查看: http://www.openstreetmap.org/relation/74231http://www.openstreetmap.org/relation/75097 不幸的是,我无法在此处发布我的坐标数据(stackoverflow 只允许发布 30,000 个字符)。因此问题是:我如何找出 MySQL 为什么说它不包含的原因?
先谢谢!

PS:查询SELECT b.* FROM tablex as a LEFT JOIN tablex as b ON ST_intersects(b.geoPoly, a.geoPoly) AND NOT ST_touches(b.geoPoly, a.geoPoly) WHERE a.intID = 123可以返回正确的结果,但需要10倍的时间。(而且这不是最好的方法) - derjan
2个回答

1

你可以使用ST_Buffer函数并设置非常小的距离(如0.0000001),但不要太小,要小心。下面是一个示例:

SELECT st_within(g1.shape, ST_buffer(geometrycollection(g1.shape, g2.shape), 0.0000001))
FROM (SELECT * FROM geoflas WHERE id = 1) as g1, 
    (SELECT * FROM geoflas WHERE id = 2) as g2;

0

我建议您的多边形坐标沿共享线可能略有不同,因此较小的区域并未完全包含在较大的区域内。

如果较小多边形的任何一个坐标超出了较大区域(即使是第8位小数点,肉眼也看不到!!!),则一些小区域将无法包含在较大区域内,因此您可以得到正确的答案,但不一定是您要寻找的答案。

您应该能够使用Intersection和Difference空间函数的组合来查找问题 - 您需要能够将结果投影到地图上以查看问题所在。请参见http://dev.mysql.com/doc/refman/5.7/en/spatial-operator-functions.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接