我需要使用 Rails 应用程序中现有的 PostGIS 数据库。到目前为止,我能够很好地访问数据库,GeoRuby 很好地将“geom”列转换为一个点对象。
我正在寻找的是一种在这些表上执行类似 ActiveRecord 查询的简单方法,例如
Poi.find_within_radius(...)
或类似的空间查询,如距离计算等。人。
我尝试了几个 geokit 的组合,附带的 rails 插件,但我很确定在 ruby/rails 世界中一定有更好的东西。有什么提示吗?
我需要使用 Rails 应用程序中现有的 PostGIS 数据库。到目前为止,我能够很好地访问数据库,GeoRuby 很好地将“geom”列转换为一个点对象。
我正在寻找的是一种在这些表上执行类似 ActiveRecord 查询的简单方法,例如
Poi.find_within_radius(...)
或类似的空间查询,如距离计算等。人。
我尝试了几个 geokit 的组合,附带的 rails 插件,但我很确定在 ruby/rails 世界中一定有更好的东西。有什么提示吗?
既然你有 GeoRuby,把你的 Poi 模型
SRID = 4326 #WGS84
# geometry column is geom
# pt is a GeoRuby Point
def self.find_within_radius(pt, dist = 0.01)
self.all :conditions => "ST_DWithin(geom, ST_GeomFromText('POINT(#{pt.x} #{pt.y})', #{SRID}), #{dist})"
end
对于距离计算,您可以在点对象上使用方法
dist_circle = poi1.geom.spherical_distance(poi2.geom)
dist_projected = poi1.geom.euclidean_distance(poi2.geom)
添加到synecdoche 的答案中,在 Rails 3 中,您可以使用ActiveRelation
范围,这将允许您链接查询。
未经测试:
# Poi.rb
scope :within, proc { |point, distance|
p = "POINT(#{point.x} #{point.y})"
where("ST_DWithin(geom, ST_GeomFromText('#{p}', #{SRID}), #{distance})")
}
scope :rated, proc { |rating| where(rating: rating) }
用法:
home = Point.new(5,5)
Poi.rated(5).within(home, 25)
即使您不链接作用域,大多数时候它也比使用类方法更好。
ST_Distance() 并不意味着您可能没有安装 postgis 或者您没有创建 postgis 模板......或者如果模板存在,您没有使用 postgis 模板创建数据库。