我需要在我的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的世界中一定有更好的选择。有什么提示吗?
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模板创建数据库。