MySQL ST_CONTAINS в случае перекрытия - PullRequest
0 голосов
/ 08 февраля 2020

У меня проблема с использованием геопространственной функции ST_CONTAINS на MySQL 5.6.31.

У меня есть следующий МНОГОПОЛИГОН:

MULTIPOLYGON

Мне нужно проверить, находится ли какая-либо точка внутри МНОГОПОЛИГА, в данном случае красная на изображении, поэтому я делаю:

SET @g1 = ST_GEOMFROMTEXT('MULTIPOLYGON(((41.94142040508967 12.41757292797851,41.94442097040815 12.419032049682611,41.93529115206086 12.43456740429687,41.91939065648979 12.425126028564447,41.92475512204906 12.407702398803705,41.94142040508967 12.41757292797851),(41.92552143745503 12.409933996704096,41.90987400689221 12.402638388183588,41.90252797153794 12.421864462402338,41.907446714803015 12.433194113281244,41.92603230927889 12.419461203124994,41.92552143745503 12.409933996704096,41.92552143745503 12.409933996704096),(41.906248516384416 12.397567221513638,41.89551602293968 12.423402258745083,41.90101026279693 12.430268713823208,41.90771770545893 12.420398184648404,41.91033661082307 12.39653725325192,41.906248516384416 12.397567221513599,41.906248516384416 12.397567221513599,41.906248516384416 12.397567221513638,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.39756722151363,41.906248516384416 12.397567221513638)))');

SET @g2 = POINT(41.9059998,12.4159939);

SELECT ST_CONTAINS(@g1,@g2);

Результат равен 0.

Если я изменил точку, указав, например, точку в верхнем многоугольнике, я получил 1.

Почему это поведение? Кажется, что когда два многоугольника перекрываются, ST_CONTAINS видят его как пустую их часть.

Что я могу сделать?

Спасибо всем!

1 Ответ

1 голос
/ 09 февраля 2020

Это странный (не соответствует стандарту и, вероятно, недопустимый) многогранник.

Многогранник описывается примерно так:

MULTIPOLYGON(((p1_shell), (p1_hole1), (p1_hole2)), ((p2_shell), (p2_hole1), (p2_hole2)))

Т.е. многоугольники разделены двойными круглыми скобками, а оболочка многоугольника отделяется от отверстий одинарными круглыми скобками. В вашем случае это одиночные скобки - так что этот WKT описывает один многоугольник с двумя отверстиями ! Обратите внимание, что это недопустимо (вы можете позвонить ST_IsValid для проверки) - отверстие не полностью содержится в оболочке, как того требует стандарт. Но в любом случае MySql это позволяет, и, поскольку красная точка находится внутри отверстия, она не содержится в форме, поэтому MySql результат верен.

Если желаемое семантио c фигуры является многоугольником, а не многоугольником с отверстиями, замените ),( на )),((, чтобы получить эта семантика. Обратите внимание, что это по-прежнему недопустимая форма WKT - отдельные многоугольники в многоугольнике не могут пересекаться (снова проверьте с помощью ST_IsValid). Но в любом случае это должно дать вам правильный результат (хотя, будучи нестандартным, это несколько неопределенное поведение).

Если вы хотите быть совместимым со стандартом, вы должны очистить этот WKT. Что вы делаете, зависит от семантики, которая вам нужна. Может быть ST_UNION эти полигоны и получить один. Или оставить все три - правильный способ описать фигуру, состоящую из возможно пересекающихся многоугольников, - это GEOMETRYCOLLECTION с многоугольниками в качестве элементов.

...