Разделение города на зоны, это хорошая идея?

#ruby-on-rails #ruby #google-maps #postgis #rails-geocoder

#ruby-on-rails #ruby #google-карты #postgis #rails-геокодер

Вопрос:

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

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

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

Но хорошая ли это идея или я могу сделать лучше?

Комментарии:

1. Какую базу данных вы используете? Именно в этом превосходят пространственные индексы, поскольку они двумерны (с использованием R-деревьев) и позволяют выполнять запросы типа «внутри», «содержит», «пересекает», «расстояние».

2. Я планирую использовать postgres

3. В этом случае просто используйте пространственный индекс, а затем используйте запросы типа ST_DWithin (geom1, geom2, distance) см. postgis.net/docs/ST_DWithin.html

4. Это действительно здорово! Я думаю, мне даже не нужно использовать geocoder gem, я могу просто выполнить соответствующий SQL-запрос и получить результаты.

5. Я написал более полный ответ и добавил теги Postgres / Postgis к вашему вопросу: D

Ответ №1:

При использовании Postgres / Postgis вы можете использовать пространственные индексы, а затем использовать запросы типа ST_DWithin (geom1, geom2, расстояние), см. Документы ST_DWithin. Пространственный индекс разделит пространство за вас, что сделает такого рода запросы очень эффективными и избавит вас от необходимости придумывать какую-либо собственную схему пространственного разделения.

Другим оператором, который вы можете использовать, является оператор <->, который очень эффективен с пространственным индексом и используется в предложении order by, чтобы получить ближайшие объекты y к некоторой точке x (поиск k ближайших соседей), см. <-> operator docs . Одно предостережение для того, чтобы этот оператор правильно работал с индексом, точка, которую вы ищете, должна быть постоянной, как это звучит в вашем случае.