database - 在给定半径内搜索相应对象位置的酒店(Gem Geocoder)

标签 database ruby-on-rails-3 postgresql geolocation

我有 3 个表:ObjectsLocationsHotels

每个对象有多个位置,每个位置有几个酒店(默认在 20 英里半径内)。

我的模型(略微简化以专注于主要内容)

对象.rb

attr_accessible :name

has_many :locations
has_many :hotels

location.rb

attr_accessible :name, :address, :longitude, :latitude

has_many :objects
has_many :hotels

hotels.rb

attr_accessible :name, :address, :longitude, :latitude

has_many :objects
has_many :locations

我想创建一个搜索表单,用户可以在其中输入对象的名称搜索半径

输出应该是所有酒店的列表,这些酒店位于距每个位置中心的给定半径(小于或等于 20 英里)内,对应于对象。

我想使用 Geocoder's gem 方法 near,但我不确定如何构建此类任务的 Controller 层。

enter image description here

最佳答案

您希望数据库中有一个空间查询引擎来执行这些查询,例如MongoDB 或 PostGIS(在 Postgres 中)。我认为您正在寻找的答案会因您使用的答案而异。我将 PostGIS 用于这些东西并且非常喜欢它。

也就是说,Geocoder 可以在没有空间查询引擎的情况下用于在内部为此提供支持,尽管它不会那么高效。如果你变得非常大,它会逐渐停止。如果您查看来源:https://github.com/alexreisner/geocoder/blob/master/lib/geocoder/stores/active_record.rb

# skeleton for the controller method
obj = Object.find(name)
locations = obj.locations
near_hotels = locations.map do |loc| 
  locations.hotels.near([loc.latitude, loc.longitude])
end

不确定 near 方法是否正确地接受了 radius 参数,但是您可以通过基本上复制它来很容易地编写自己的方法:

# on the hotel class
def nearby(lat, lon, radius)
    options = self.send(:near_scope_options, lat, lon, radius, {})
    select(options[:select]).where(options[:conditions]).
      order(options[:order])
}

我强烈建议您查看 PostGIS。

请注意,我的示例方法产生了一个关系。您可以将范围限定为符合您目标的酒店,从而缩小选择范围。

关于database - 在给定半径内搜索相应对象位置的酒店(Gem Geocoder),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15324821/

相关文章:

SQL:从一个表中获取所有记录并从第二个表中获取记录数?

ios - 从 Realm 获取所有表(类)

ruby-on-rails - 如何测试 after_sign_in_path_for(resource)?

php - 如何动态地将数据从数据库放到 session 中

database - 为什么刷新物化 View 会同时阻止插入/更新?

ruby catch连接超时错误

ruby-on-rails - Rails,检查是否已发送电子邮件

postgresql - Postgres如何评估从查询到函数中变量的表达式

postgresql - 有条件的时间序列数据聚合

sql - 在不使用子查询的情况下从同一个表中的正则表达式匹配更新