从 Rails 访问 PostGIS 空间数据

发布于 2024-08-06 18:41:17 字数 301 浏览 5 评论 0原文

我需要使用 Rails 应用程序中现有的 PostGIS 数据库。到目前为止,我能够很好地访问数据库,GeoRuby 很好地将“geom”列转换为 Point 对象。

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

Poi.find_within_radius(...)

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

我尝试了多种 geokit 和附带的 Rails 插件的组合,但我很确定 ruby​​/rails 宇宙中一定有更好的东西。有什么提示吗?

I need to use an existing PostGIS database from my Rails application. So far I am able to access the DB just fine, GeoRuby nicely converts the 'geom' column into a Point object.

What I am looking for is an easy way to execute ActiveRecord-like queries on those tables, e.g.

Poi.find_within_radius(...)

or similar spatial queries like distance calculations et. al.

I tried several combinations of geokit, accompanying rails plugins but I'm quite sure there must be something better out there in the ruby/rails universe. Any hints?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烏雲後面有陽光 2024-08-13 18:41:17

既然您已经有了 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)

Since you've got GeoRuby, put in your Poi model

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

For distance calculations you can use methods on the point objects

dist_circle = poi1.geom.spherical_distance(poi2.geom)
dist_projected = poi1.geom.euclidean_distance(poi2.geom)
你是年少的欢喜 2024-08-13 18:41:17

添加到synecdoche的答案,在Rails 3中你可以使用< code>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)

即使您不链接作用域,大多数时候它也比使用类方法更好。

Adding to synecdoche's answer, in Rails 3 you can use ActiveRelation scopes, which would allow you to chain queries.

Untested:

# 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) }

Usage:

home = Point.new(5,5)
Poi.rated(5).within(home, 25)

Even if you don't chain scopes, most of the time it's better than using class methods.

〆凄凉。 2024-08-13 18:41:17

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

ST_Distance() doesn't means you probably don't have postgis installed or you didn't create a postgis template... or you didn't create your database using the postgis template if the template exists.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文