Как переписать этот запрос RGeo, используя AR/Arel?

У меня есть следующая область, которую я получил для работы с сырым 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.shape это geography(Polygon,4326) а также point это geography(Point,4326), для типов PostgreSQL.

В консоли рельсов они #<RGeo::Geos::CAPIPolygonImpl> а также #<RGeo::Geos::CAPIPointImpl> соответственно.

Я хочу написать что-то более похожее на

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

... но это дает мне эту ошибку:

Ошибка времени выполнения: не поддерживается: RGeo::Geos::CAPIPointImpl

Хотелось бы получить некоторую помощь в получении сырого SQL из моей модели Кроме того, я новичок в RGeo/PostGIS, поэтому, пожалуйста, не думайте, что я знаю, что делаю.:D

2 ответа

Вы можете сделать это без arel или же 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')"

Пожалуйста, также не думайте, что я знаю, о чем именно вы говорите, но я использую squeel gem для написания запросов в стиле rails с rgeo а также activerecord-postgis-adapter, Даниэль Азума написал несколько отличных блогов на эту тему, которые дали мне начало пару лет назад. Вот первая из этой серии: http://daniel-azuma.com/articles/georails/part-1

Из того, что я понимаю, это может немного помочь:

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

Обратите внимание, что это работает, только если вы установили самоцвет squeel. И если вы хотите быть особенно внимательным, возможно, вам следует использовать это вместо этого:

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

Рад, что кто-то другой использует рельсы для ГИС. Удачи

Другие вопросы по тегам