MySQL 8.0 ST_CONTAINS returns 多边形外记录,多边形内缺失记录
MySQL 8.0 ST_CONTAINS returns records outside polygon, and misses records within polygon
我在使用 mysql 的 st_contains
时遇到了差异。我有一个 table 区域,其中有 latitude
和 longitude
列,我只是想查询落在多边形内的所有记录。
当我这样做时 mysql returns 记录在多边形之外,并且错过了肯定在多边形内的记录。我能够使用来自 mysql 的结果的 google 地图创建视觉效果,以帮助我进行调试。
下面是SQL查询
SELECT *
FROM `zones`
WHERE (ST_CONTAINS(ST_GEOMFROMTEXT('POLYGON((22.43079687220491 89.14206562499999, 33.72385081452048 96.70065937499999, 22.917381576171614 107.77487812499999, 20.796651975524764 108.12644062499999, 17.643461922028166 107.42331562499999, 7.361883956935348 117.26706562499999, 2.1060545562538273 148.54242063498816, -7.365289419995424 171.21820188498816, -25.802453489204527 171.74554563498816, -36.08590711168321 -175.3694333408895, -51.731473033051614 172.21043060460465, -44.34469762328107 138.81199310460465, -34.74750931376504 107.87449310460465, -12.04633897054804 98.73386810460465, 2.804203457833971 93.76073834567285, 16.292162960708847 90.77245709567285, 22.43079687220491 89.14206562499999, 22.43079687220491 89.14206562499999))'), POINT(latitude, longitude))) AND `zones`.`deleted_at` IS NULL
从视觉上看,它显示了提供的多边形之外的记录,并且缺少应该在多边形内的记录。
例如,我有澳大利亚黑斯廷斯的区域记录,其中 latitude:-38.3
和 longitude:145.216667
显然在多边形中,但 mysql 从来没有 returns 这条记录.新西兰国内也有多项记录。
边界是使用 google 地图绘制插件生成的。
这是 mysql 错误,还是我做错了什么?
我将您的多边形定义粘贴到 WKT 可视化工具中,它看起来很奇怪,与您在此处绘制的完全不同。
而且我认为这是由这些段和缺少 SRID 引起的。
-25.802453489204527 171.74554563498816,
-36.08590711168321 -175.3694333408895,
-51.731473033051614 172.21043060460465
没有明确的 SRID 参数,MySQL 使用 SRID 0 - 抽象的、无单位的、无限的笛卡尔平面。
https://mysqlserverteam.com/spatial-reference-systems-in-mysql-8-0/
在此段中,经度从 171 跳到 -175 并返回,穿过反子午线。但是当 SRID = 0 时,MySQL 对反子午线一无所知,这变成了一条跨越 ~346 度经度并跨越大部分图片的长线,而不是跨越 ~14 度并跨越反子午线的免费短线子午线。
您需要提供 SRID(我想您需要 4326
)来告知 MySQL 地球上正在发生的事情。如果您不需要精确的多边形,或者作为简单的解决方法 - 将 -175.3694333408895
替换为 179.9
以避免穿过反子午线。
我在使用 mysql 的 st_contains
时遇到了差异。我有一个 table 区域,其中有 latitude
和 longitude
列,我只是想查询落在多边形内的所有记录。
当我这样做时 mysql returns 记录在多边形之外,并且错过了肯定在多边形内的记录。我能够使用来自 mysql 的结果的 google 地图创建视觉效果,以帮助我进行调试。
下面是SQL查询
SELECT *
FROM `zones`
WHERE (ST_CONTAINS(ST_GEOMFROMTEXT('POLYGON((22.43079687220491 89.14206562499999, 33.72385081452048 96.70065937499999, 22.917381576171614 107.77487812499999, 20.796651975524764 108.12644062499999, 17.643461922028166 107.42331562499999, 7.361883956935348 117.26706562499999, 2.1060545562538273 148.54242063498816, -7.365289419995424 171.21820188498816, -25.802453489204527 171.74554563498816, -36.08590711168321 -175.3694333408895, -51.731473033051614 172.21043060460465, -44.34469762328107 138.81199310460465, -34.74750931376504 107.87449310460465, -12.04633897054804 98.73386810460465, 2.804203457833971 93.76073834567285, 16.292162960708847 90.77245709567285, 22.43079687220491 89.14206562499999, 22.43079687220491 89.14206562499999))'), POINT(latitude, longitude))) AND `zones`.`deleted_at` IS NULL
从视觉上看,它显示了提供的多边形之外的记录,并且缺少应该在多边形内的记录。
例如,我有澳大利亚黑斯廷斯的区域记录,其中 latitude:-38.3
和 longitude:145.216667
显然在多边形中,但 mysql 从来没有 returns 这条记录.新西兰国内也有多项记录。
边界是使用 google 地图绘制插件生成的。
这是 mysql 错误,还是我做错了什么?
我将您的多边形定义粘贴到 WKT 可视化工具中,它看起来很奇怪,与您在此处绘制的完全不同。
而且我认为这是由这些段和缺少 SRID 引起的。
-25.802453489204527 171.74554563498816, -36.08590711168321 -175.3694333408895, -51.731473033051614 172.21043060460465
没有明确的 SRID 参数,MySQL 使用 SRID 0 - 抽象的、无单位的、无限的笛卡尔平面。 https://mysqlserverteam.com/spatial-reference-systems-in-mysql-8-0/
在此段中,经度从 171 跳到 -175 并返回,穿过反子午线。但是当 SRID = 0 时,MySQL 对反子午线一无所知,这变成了一条跨越 ~346 度经度并跨越大部分图片的长线,而不是跨越 ~14 度并跨越反子午线的免费短线子午线。
您需要提供 SRID(我想您需要 4326
)来告知 MySQL 地球上正在发生的事情。如果您不需要精确的多边形,或者作为简单的解决方法 - 将 -175.3694333408895
替换为 179.9
以避免穿过反子午线。