【问题标题】:How to rewrite this RGeo query using AR/Arel?如何使用 AR/Arel 重写此 RGeo 查询?
【发布时间】:2016-03-02 23:14:25
【问题描述】:

我已经开始使用原始 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

其中delivery_zones.shapegeography(Polygon,4326)pointgeography(Point,4326),对于 PostgreSQL 类型。

在 Rails 控制台中,它们分别是 #&lt;RGeo::Geos::CAPIPolygonImpl&gt;#&lt;RGeo::Geos::CAPIPointImpl&gt;

我想写一些类似的东西

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

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

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

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

【问题讨论】:

    标签: ruby-on-rails-4 activerecord postgis rgeo


    【解决方案1】:

    也请不要假设我知道你在说什么,但我使用squeel gem 来编写带有rgeoactiverecord-postgis-adapter 的rails 样式查询。 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 的东西。祝你好运

    【讨论】:

      【解决方案2】:

      没有arelsqueel 也可以这样做:

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

      一般来说,这应该可行:

      where("point_column &amp;&amp; ?", 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')"
      

      【讨论】:

      • 如果我没看错,这似乎会返回多边形内的所有点,对吧?不仅仅是那些与创建周长的线串相交的线串?一个星期以来,我一直在寻找完全相同的东西!
      • 是的,它将返回边界框内带有点(在本例中为coordinates 列)的所有记录。
      猜你喜欢
      • 1970-01-01
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多