0

我需要st_intersection在 Ruby 的 SQL SELECT 子句中执行 PostGIS 函数。目前我将其作为原始 SQL 查询进行:

sql_query = "SELECT id, ST_ASEWKT(ST_INTERSECTION(geometry, ?)) FROM trips WHERE status='active';"
intersections = Trip.execute_sql(sql_query, self[:geometry].to_s)

这种方式的缺点是我将结果作为文本接收,并且我需要从字符串中解析出对象。更好的是使用 ActiveRecord 接口进行查询。但是,我还没有找到st_intersection在 ActiveRecord 中运行 PostGIS 功能(例如)的任何解决方案。

activerecord-postgis-adapter 的README的早期版本展示了一个使用 gem 的好例子squeel

my_polygon = get_my_polygon    # Obtain the polygon as an RGeo geometry
MySpatialTable.where{st_intersects(lonlat, my_polygon)}.first

由于这不再是当前自述文件的一部分,我想知道是否不推荐这样做,或者是否有更好的选择。

4

1 回答 1

2

这里有两个问题需要解决。

第一种是在.select子句中使用 SQL 函数。通常这很容易——你只需用它AS来给结果命名。这是ActiveRecord Rails 指南中的一个示例:

Order.select("date(created_at) as ordered_date, sum(price) as total_price").group("date(created_at)")

生成的 Order 对象将具有ordered_datetotal_price属性。

这给我们带来了第二个问题,即 Rails 没有给我们提供参数化 a 的简单方法select(即使用?占位符),所以(据我所知)你需要自己做sanitize_sql_array

sql_for_select_intersection = sanitize_sql_array([
  "ST_ASEWKT(ST_INTERSECTION(geometry, ?)) AS intersection",
  geometry,
])

这将返回一个经过清理的 SQL 片段,例如ST_ASEWKT(ST_INTERSECTION(geometry, '...')),然后您可以使用它来指定一个字段select

Trip.where(status: "active").select(:id, sql_for_select_intersection))

结果查询将返回带有idintersection属性的 Trip 对象。

于 2019-06-11T16:46:40.010 回答