简体   繁体   中英

MySQL 8.0 ST_CONTAINS returns records outside polygon, and misses records within polygon

I'm facing discrepancies when using mysql's st_contains . I have a table of zones which has their latitude and longitude columns, I simply want to query all records that fall within the polygon.

When I do this mysql returns records outside the polygon, and misses records that are definitely within the polygon. I was able to create a visual using google maps of the results from mysql to help me debug.

这是我能够使用谷歌地图创建的记录的视觉效果

Below is the SQL query

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

From the visual it shows records outside the polygon provided, and is missing records that should be within the polygon.

For example I have a zones record for Hastings, Australia with a latitude:-38.3 and longitude:145.216667 which would clearly be in the polygon but mysql never returns this record. There is also several records within New Zealand.

The boundary is generated using google maps drawing plugin.

Is this a mysql bug, or am I doing something wrong?

I pasted your polygon definition to WKT visualizer, and it looks very weird, not at all like what you draw here.

And I think it is caused by these segments, and by missing SRID.

-25.802453489204527 171.74554563498816, -36.08590711168321 -175.3694333408895, -51.731473033051614 172.21043060460465

Without explicit SRID argument, MySQL uses SRID 0 - abstract, unitless, infinite, Cartesian plane. https://mysqlserverteam.com/spatial-reference-systems-in-mysql-8-0/

In this segment the longitude jumps from 171 to -175 and back, crossing anti-meridian. But with SRID = 0, MySQL knows nothing about anti-meridian, and this becomes a long line spanning ~346 degrees of longitude and crossing most of the picture, instead of complimentary short line spanning ~14 degrees and crossing anti-meridian.

You need to provide SRID (I guess you need 4326 ) to tell MySQL things are happening on Earth. Or as simple workaround if you don't need precise polygon - replace -175.3694333408895 with 179.9 to avoid crossing antimeridian.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM