1

我有以下使用原始 SQL 的范围:

class DeliveryZone < ActiveRecord::Base
  def self.contains(addressable)
    point = addressable.lonlat
    where(<<-SQL.squish)
    ST_Intersects("delivery_zones"."shape", ST_GeomFromText('#{point}'))
    SQL
  end
end

对于 PostgreSQL 类型,其中delivery_zones.shapeageography(Polygon,4326)point是 a 。geography(Point,4326)

在 Rails 控制台中,它们分别是 a#<RGeo::Geos::CAPIPolygonImpl>#<RGeo::Geos::CAPIPointImpl>

我想写一些更类似于

where(arel_table[:shape].st_intersects(point))

...但这给了我这个错误:

RuntimeError:不支持:RGeo::Geos::CAPIPointImpl

希望从我的模型中获取原始 SQL 的帮助!另外,我是 RGeo/PostGIS 新手,所以请不要以为我知道自己在做什么。:D

4

2 回答 2

0

您可以在没有arelor的情况下执行此操作squeel

where("delivery_zones.shape && ?", addressable.lonlat.to_geometry)

一般来说,这应该有效:

where("point_column && ?", rgeo_object.to_geometry)

这是一个模型的示例,其中City包含一个名为 的点列coordinates,即st_point. 我想查询由两个角点(SE 和 NW)定义的边界框中的所有城市:

box = RGeo::Cartesian::BoundingBox.create_from_points(
        City.first.coordinates, City.last.coordinates)

City.where("coordinates && ?", box.to_geometry)

这是怎么回事?

> box.to_geometry.to_s
=> "POLYGON ((-90.0674 29.9627, -79.09529 29.9627, -79.09529 36.18375, -90.0674 36.18375, -90.0674 29.9627))"

> City.where("coordinates && ?", box.to_geometry).to_sql
=> "SELECT \"cities\".* FROM \"cities\" WHERE (coordinates && '0020000003000010e60000000100000005c05684504816f007403df67381d7dbf5c053c6193b3a68b2403df67381d7dbf5c053c6193b3a68b2404217851eb851ecc05684504816f007404217851eb851ecc05684504816f007403df67381d7dbf5')"
于 2016-03-16T16:43:47.747 回答
0

也请不要假设我知道你在说什么,但我使用squeelgem 用rgeoand编写 rails 样式的查询activerecord-postgis-adapter。Daniel Azuma 写了一些关于这个主题的很棒的博客,这让我在几年前开始了。这是该系列的第一篇:http: //daniel-azuma.com/articles/georails/part-1

据我了解,这可能会有所帮助:

class DeliveryZone < ActiveRecord::Base
  def self.contains(addressable)
    where{st_intersects(:shape, addressable)}
  end
end

请注意,这仅在您安装了 squeel gem 时才有效。如果你想特别注意它,也许你应该改用这个:

class DeliveryZone < ActiveRecord::Base
  def self.contains(addressable)
    where{st_contains(:shape, addressable)}
  end
end

很高兴其他人将导轨用于 GIS 的东西。祝你好运

于 2016-01-07T19:09:47.113 回答