Mysql Расстояние от контрольной точки до полигона

Я сохранил некоторые зоны карты в таблицу, используя поле типа геометрии.

Итак, вставки такие:

INSERT INTO zones (zoneName, coords) VALUES ('name',
PolygonFromText('POLYGON((
41.11396418691335 1.2562662363052368,
41.11370552595821 1.2560248374938965,
41.11851079510035 1.2459397315979004,
41.11880984984478 1.2461864948272705,
41.11396418691335 1.2562662363052368))'));

Затем у меня есть позиция пользователя, и мне нужно знать, находится ли он внутри какой-то зоны. Это хорошо работает с этим:

SELECT id 
  FROM zones 
 WHERE MBRContains(coords,GeomFromText('POINT(41.117783 1.260590)'))

Но иногда позиция пользователя не идеальна, поэтому я думаю, что лучше знать, какая зона ближе всего к положению пользователя.

Это та часть, о которой я понятия не имею... Я нашел несколько запросов, чтобы получить расстояние между двумя точками, но не точкой и многоугольниками.


person Biwu    schedule 19.06.2012    source источник


Ответы (1)


Серия функций MBR (например, MBRContains) не подходит для того, что вы пытаетесь сделать; они только проверяют включение ограничивающего прямоугольника.

Вы можете перейти к MySQL 5.6.1 и использовать функции ST_, такие как ST_Contains. Эти функции фактически проверяют геометрию.

Проблема, над которой вы работаете, может быть определена как неопределенность положения вашего POINT, когда вы идете сравнивать его с вашей коллекцией граничных POLYGON элементов.

Попробуйте следующее: создайте POLYGON из вашей точки, которая представляет собой квадрат с размером вашей неопределенности. Вы можете думать об этом квадрате как о «нечеткой» точке. (Вы также можете использовать восьмиугольник или другое близкое приближение к кругу вместо прямоугольника, но ваша скорость запросов будет медленнее.)

Затем используйте ST_Within, чтобы увидеть, есть ли у вас уникальный многоугольник, полностью содержащий вашу нечеткую точку. Если вы получите только один полигон, все готово.

Если вы получаете несколько полигонов, которые полностью содержат вашу нечеткую точку, это означает, что некоторые из ваших граничных полигонов перекрывают другие. Вам нужно выяснить, что это означает в вашем проблемном пространстве. Если ваши данные должны быть правильно структурированными картографическими граничными данными, это означает, что у вас есть ошибка в данных. (ПРИМЕЧАНИЕ: это не неслыханно :-)

Если у вас нет многоугольников, которые полностью содержат вашу нечеткую точку, то ваша нечеткая точка может перекрывать или не перекрывать границу по крайней мере одного многоугольника. Используйте ST_Overlaps, чтобы найти эти полигоны.

Если вы получите только один, все готово — ваша нечеткая точка находится рядом с границей только одного многоугольника.

Если вы ничего не получили, все готово — ваша нечеткая точка находится вдали от границ всех ваших полигонов.

Если вы получаете более одного совпадения, у вас есть неоднозначность — ваша нечеткая точка находится рядом с границей более чем одного полигона.

Это сложный случай, чтобы разобраться. Вы можете уменьшить размер нечеткой точки и повторить попытку. Это МОЖЕТ дать только один результат многоугольника. Но вы можете обмануть себя, думая, что ваши точки более точны, чем они есть, делая это.

MySQL не имеет геометрического оператора Area(Intersection(Polygon, FuzzyPoint)). Если бы это было так, вы могли бы выбрать многоугольник с наибольшей площадью пересечения с вашей нечеткой точкой, и это было бы хорошим средством устранения неоднозначности. Но это все равно будет столь же неточным, как и положение вашей точки.

Возможно, ваше приложение должно обрабатывать категорию результата «слишком близко к границе A, B и C, чтобы быть уверенным».

person O. Jones    schedule 19.06.2012
comment
PostgreSQL с расширением PostGIS имеет гораздо более сложный набор функций для такого рода обработки, чем MySQL. - person O. Jones; 20.06.2012