Получите полигоны близко к lat, долго в MySQL

Кто-либо знает о способе выбрать все полигоны в дб MySQL на данном расстоянии от точки? Фактическое расстояние не настолько важно, так как оно вычисляется для каждого найденного полигона позже, но это была бы огромная оптимизация, чтобы просто сделать то вычисление для полигонов, которые "близки".

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

Какие-либо предложения?

7
задан JackalopeZero 21 September 2017 в 15:11
поделиться

3 ответа

Медленная версия (без пространственных индексов):

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 в вашу базу данных, а не широту и долготу.

4
ответ дан 7 December 2019 в 12:21
поделиться

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

Первая идея, которая приходит мне в голову, - это использовать сетку, назначить каждую точку квадрату и установите флажок, выберите квадрат, в котором находится точка, и те, кто вокруг него. Если мы говорим о бесконечных сетках, тогда используйте хеш-значение квадрата, это даст вам больше очков, чем нужно (где у вас есть коллизии), но все равно уменьшит количество на кучу. Конечно, это не сразу применимо к полигонам, это просто мозговой штурм. Возможный подход, который может привести к слишком большому количеству коллизий, заключался бы в том, чтобы объединить все хешированные значения по ИЛИ и выбрать все записи, в которых хэши, объединенные с помощью AND с этим значением, не равны нулю (не уверен, возможно ли это в MySQL), вы можете использовать большой количество битов.

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

1
ответ дан 7 December 2019 в 12:21
поделиться

Создайте ограничивающую рамку для всех полигонов и (при необходимости сохранение этих результатов в базе данных сделает это намного быстрее для сложных полигонов). Затем вы можете сравнить ограничивающую рамку для каждого многоугольника с рамкой желаемого размера. Выберите все многоугольники с пересекающимися ограничивающими рамками.

0
ответ дан 7 December 2019 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: