Как переписать этот запрос 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
Рад, что кто-то другой использует рельсы для ГИС. Удачи