Кто-либо знает о способе выбрать все полигоны в дб MySQL на данном расстоянии от точки? Фактическое расстояние не настолько важно, так как оно вычисляется для каждого найденного полигона позже, но это была бы огромная оптимизация, чтобы просто сделать то вычисление для полигонов, которые "близки".
Я посмотрел на MBR, и содержит функции, но проблема состоит в том, что некоторые полигоны не содержатся в ограничительной рамке, оттянутой вокруг точки, так как они являются очень большими, но некоторые их вершины все еще близки.
Какие-либо предложения?
Медленная версия (без пространственных индексов):
SELECT *
FROM mytable
WHERE MBRIntersects(mypolygon, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
Чтобы использовать пространственные индексы, вам необходимо денормализовать таблицу, чтобы каждая вершина полигона хранилась в отдельной записи.
Затем создайте ПРОСТРАНСТВЕННЫЙ ИНДЕКС
в поле, содержащем координаты вершин, и просто введите следующий запрос:
SELECT DISTINCT polygon_id
FROM vertices
WHERE MBRContains(vertex, LineString(Point(@X - @distance, @Y - @distance), Point(@X + @distance, @Y + @distance))
Все будет намного проще, если вы сохраните координаты UTM
в вашу базу данных, а не широту и долготу.
Я не думаю, что на этот вопрос есть однозначный ответ. Обычно это вопрос о том, как организовать ваши данные так, чтобы они использовали пространственную локальность, присущую вашей проблеме.
Первая идея, которая приходит мне в голову, - это использовать сетку, назначить каждую точку квадрату и установите флажок, выберите квадрат, в котором находится точка, и те, кто вокруг него. Если мы говорим о бесконечных сетках, тогда используйте хеш-значение квадрата, это даст вам больше очков, чем нужно (где у вас есть коллизии), но все равно уменьшит количество на кучу. Конечно, это не сразу применимо к полигонам, это просто мозговой штурм. Возможный подход, который может привести к слишком большому количеству коллизий, заключался бы в том, чтобы объединить все хешированные значения по ИЛИ и выбрать все записи, в которых хэши, объединенные с помощью AND с этим значением, не равны нулю (не уверен, возможно ли это в MySQL), вы можете использовать большой количество битов.
Проблема с этим подходом состоит в том, что если мы говорим о сферических координатах (широта, долгота, как правило), это сингулярности, поскольку «квадраты» сетки сужаются по мере приближения к полюсам. Самый простой способ - не ставить точки близко к полюсам ... :)
Создайте ограничивающую рамку для всех полигонов и (при необходимости сохранение этих результатов в базе данных сделает это намного быстрее для сложных полигонов). Затем вы можете сравнить ограничивающую рамку для каждого многоугольника с рамкой желаемого размера. Выберите все многоугольники с пересекающимися ограничивающими рамками.