2009-10-07 5 views
7

레일스 애플리케이션에서 기존의 PostGIS 데이터베이스를 사용해야합니다. 지금까지 DB에 액세스 할 수 있었지만 GeoRuby는 '기하 구조'열을 Point 객체로 올바르게 변환합니다.레일스에서 ​​PostGIS 공간 데이터에 접근하기

내가 찾고있는 것은 이러한 테이블에서 ActiveRecord와 유사한 쿼리를 쉽게 실행할 수있는 방법입니다.

Poi.find_within_radius(...) 

또는 거리 계산과 같은 유사한 공간 쿼리. al.

레일즈 플러그인을 동반 한 geokit의 여러 조합을 시도했지만, 루비/레일 우주에서 더 나은 무언가가 있어야한다고 확신합니다. 어떤 힌트?

답변

6

당신이 지점에 방법을 사용할 수 있습니다 거리 계산에 대한 포이 모델

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 

에 넣어 GeoRuby을 가지고 있기 때문에

dist_circle = poi1.geom.spherical_distance(poi2.geom) 
dist_projected = poi1.geom.euclidean_distance(poi2.geom) 
+0

견본을 가져 주셔서 감사합니다. 나는 그들을 시험해 보았고 매력처럼 작동합니다! 이제 좀 더 연구를 할 수있는 출발점이 있습니다. (제 경우에는 ...) – Lakitu

0

이 ST_Distance을() 아마 당신을 의미하지 않는 객체 Postgis를 설치하지 않았거나 Postgis 템플릿을 만들지 않았거나 ... 템플릿이 존재하는 경우 Postgis 템플릿을 사용하여 데이터베이스를 만들지 않았습니다.

1

레일 3에서 synecdoche's answer에 추가하면 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) 

그렇지 체인 범위를 할 경우에도, 그것은 클래스 메소드를 사용하는 것보다 더 나은 대부분의 시간.