我想帮助构建用于带有activerecord-postgis-adapter的rails的sql查询。我一直在做很多阅读,但现在有点卡住,任何帮助都会非常感激。
我有两个模型事件和领域:
事件有一个'几何'列,其类型为Point
class Event < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"polygon", :geographic=>true}
区域有一个'几何'列,其类型为Polygon
class Area < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"point", :geographic=>true}
我可以在谷歌地图上创建和绘制事件和区域,并通过单击地图并保存到数据库来创建区域。
我希望能够执行以下2个查询:
我知道我可能会在这里问一点,但任何帮助都会非常感激
非常感谢
答案 0 :(得分:6)
这是一种快速的方法。这些只会返回ActiveRecord对象的数组。
class Area
def events
Event.joins("INNER JOIN areas ON areas.id=#{id} AND st_contains(areas.geometry, events.geometry)").all
end
end
class Event
def areas
Area.joins("INNER JOIN events ON events.id=#{id} AND st_contains(areas.geometry, events.geometry)").all
end
end
您可能应该记住(缓存结果),这样每次调用方法时都不会查询数据库。那应该是直截了当的;我将它作为练习留给读者。
可能可以变得复杂并将其包装在一个真正的Rails关联代理中(这样你就可以得到所有Rails协会的好东西)。我没有看过这个。在任何情况下它都不是标准的Rails关联,因为你没有存储ID。
第十二是正确的:您应该为两个表创建空间索引。 Activerecord-postgis-adapter应该可以在迁移过程中轻松完成。
change_table :events do |t|
t.index :geometry, :spatial => true
end
change_table :areas do |t|
t.index :geometry, :spatial => true
end
如果您在安装postgis时遇到问题,我最近就这些内容撰写了大量博客文章。查看http://www.daniel-azuma.com/blog/archives/category/tech/georails。我也是rgeo和activerecord-postgis-adapter本身的作者,所以如果你坚持不懈,我很乐意提供帮助。
答案 1 :(得分:3)
这个答案对你来说将是一项正在进行的工作。我对铁轨上的红宝石很脆弱,但我应该能够帮助你完成数据库部分。
你有两个表,包含多边形的区域和将事件保存为单个点的事件(如果事件也是一个区域而你正试图挑选重叠区域,那就更复杂了......如果事件是单点,这是有效的。)
Select *
from area a inner join event e on 1=1
这将创建一个加入每个事件的每个区域的列表...如果你有500个事件和20个区域,这将查询将返回10'000行。现在,您希望对此进行过滤,以便仅在它们已加入的区域内进行过滤。我们可以将st_contains用作st_contains(polygon,point):
where st_contains(a.polygon,e.point) = 't'
如果你运行它,它应该给你一个。,e。表示区域内的所有事件。现在只需计算你想要计算的数量。
select a.id, count(1)
from area a inner join event e on 1=1
where st_contains(a.polygon,e.point) = 't'
group by 1
这将为您提供所有区域的列表(按ID)以及其中的事件计数。使用e.id切换a.id将给出一个事件ID列表以及它们所在的数字区域。
不幸的是我不知道如何在Ruby中表达这些查询,但是你需要的数据库概念就在这里......
出于速度方面的考虑,你应该研究Postgres的GIStree索引......索引多边形的指数表现更好。
编辑:
PostGIS是Postgres附带的contrib文件,但在标准安装中不存在...您需要找到此contrib文件。这些将在您的数据库中安装一系列GIS功能,包括ST_Contains。 (函数驻留在数据库中,因此请确保在正在使用的数据库中安装函数)
PostGIS contrib文件安装的第二件事是几何数据类型所需的template_postGIS数据库(在安装之前,geom作为数据类型将不存在)。