#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 . Одно предостережение для того, чтобы этот оператор правильно работал с индексом, точка, которую вы ищете, должна быть постоянной, как это звучит в вашем случае.