2009-10-07 53 views
7

我需要使用Rails应用程序中现有的PostGIS数据库。到目前为止,我可以很好地访问数据库,GeoRuby很好地将'geom'列转换为Point对象。从Rails访问PostGIS空间数据

我在寻找的是在这些表上执行类似ActiveRecord的查询的简单方法,例如,

Poi.find_within_radius(...) 

或类似的空间查询如距离计算等。人。

我尝试了geokit的几种组合,附带的rails插件,但是我确定在ruby/rails宇宙中必须有更好的东西。任何提示?

回答

6

既然你已经有了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) 
+0

感谢一堆样品,我试了一下,他们的工作就像一个魅力!现在我已经有了一个开始做更多的研究(或涉足我的案例......) – Lakitu 2009-10-09 13:30:03

0

ST_Distance()不意味着你可能没有安装postgis,或者您没有创建postgis模板...或者如果模板存在,您没有使用postgis模板创建数据库。

1

添加到synecdoche's answer,在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) 

即使你不这样做连锁范围,其中大部分是比使用类的方法更好的时间。