Ruby Rails Postgis - 查找多边形中的所有点
我想要一些关于构建 sql 查询的帮助,以便在带有 activerecord-postgis-adapter 的 Rails 中使用。我已经做了很多阅读,但现在有点卡住了,任何帮助将不胜感激。
我有两个模型事件和区域:
事件有一个“几何”列,其类型为点
class Event < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"polygon", :geographic=>true}
区域有一个“几何”列,其类型为多边形
class Area < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"point", :geographic=>true}
我可以在谷歌地图上创建和绘制事件和区域,并创建区域通过单击地图并将其保存到数据库。
我希望能够执行以下 2 个查询:
- @area.events - 显示某个区域中的所有事件
- @event.areas - 显示单个事件所在的所有区域
我知道我在这里可能问得有点多,但是任何帮助将不胜感激 非常
感谢
I would like some help on constructing sql queries for use in rails with activerecord-postgis-adapter. I have been doing quite a bit of reading but am now a bit stuck, any help would be much appreciated.
I have the two models Events and Areas:
Events have a 'geometry' column which is of type Point
class Event < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"polygon", :geographic=>true}
Areas have a 'geometry' column which is of type Polygon
class Area < ActiveRecord::Base
self.rgeo_factory_generator = RGeo::Geos.factory_generator
end
t.spatial "geometry", :limit => {:srid=>4326, :type=>"point", :geographic=>true}
I can create and plot both events and areas on a google map, and create areas by clicking on a map and saving to the database.
I want to be able to do the follow 2 queries:
- @area.events - show all the events in an area
- @event.areas - show all the areas a single event is in
I know i might be asking a bit much here, but any help would be much appreciated
Many thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是执行此操作的快速方法。这些将简单地返回 ActiveRecord 对象的数组。
您可能应该记住(缓存结果),这样您就不会在每次调用该方法时都查询数据库。这应该很简单;我把它作为练习留给读者。
可能变得复杂,并将其包装在真正的 Rails 关联代理中(这样您就可以获得所有 Rails 关联的好处)。不过我还没有研究过这个。无论如何,它都不是标准的 Rails 关联,因为您不存储 ID。
第十二点是正确的:您应该为两个表创建空间索引。 Activerecord-postgis-adapter 应该可以让您在迁移中轻松完成这些任务。
如果您在安装 postgis 时遇到问题,我最近写了很多关于这方面的博客文章。查看 http://www.daniel-azuma.com/blog/archives /category/tech/georarails。我也是 rgeo 和 activerecord-postgis-adapter 的作者,所以如果您遇到困难,我很乐意为您提供帮助。
Here's a quick way to do this. These will simply return arrays of ActiveRecord objects.
You probably should memoize (cache the result) so that you don't query the database every time you call the method. That should be straightforward; I leave it as an exercise for the reader.
It may be possible to get sophisticated and wrap this up in a true Rails association proxy (so you can get all the Rails association goodies). I haven't looked into this though. It wouldn't be a standard Rails association in any case, because you're not storing IDs.
Twelfth is right: you should create spatial indexes for both tables. Activerecord-postgis-adapter should make those easy to do in your migration.
If you're having trouble with installing postgis, I recently wrote up a bunch of blog entries on this stuff. Check out http://www.daniel-azuma.com/blog/archives/category/tech/georails. I'm also the author of rgeo and activerecord-postgis-adapter themselves, so I'm happy to help if you're stuck on stuff.
这个答案对您来说将是一项正在进行的工作。我对 ruby on Rails 不太了解,但我应该能够帮助您完成数据库部分。
您有两个表,包含多边形的区域和将事件保存为单个点的事件(如果事件也是一个区域并且您试图挑选出重叠区域...如果事件是单个点,则情况会更复杂点这有效)。
这将创建加入每个事件的每个区域的列表...如果您有 500 个事件和 20 个区域,则此查询将返回 10'000 行。现在您想要对此进行过滤,以便仅过滤其所加入的区域内的事件。我们可以将 st_contains 用作 st_contains(polygon,point):
如果运行此命令,它应该为您提供区域内所有事件的 a.,e.。现在只要数你想数的就可以了。
这将为您提供所有区域的列表(按 ID)以及其中的事件计数。用 e.id 替换 a.id 将给出事件 id 的列表以及它们所在的数字区域。
不幸的是,我不知道如何在 Ruby 中表达这些查询,但是您需要的数据库概念都在这里。 出于速度考虑,
您应该查看 Postgres 的 GIStree 索引...索引多边形的性能呈指数级提高。
编辑:
PostGIS 是 Postgres 附带的一个 contrib 文件,但标准安装中不存在...您需要找到此 contrib 文件。这些将在您的数据库中安装一系列 GIS 功能,包括 ST_Contains。 (函数驻留在数据库中,因此请确保在您正在使用的数据库中安装函数)
PostGIS contrib 文件安装的第二件事是 template_postGIS 数据库,这是几何数据类型所需的(geom 作为数据类型将不存在)直到安装完毕)。
This answer will be a bit of a work in progress for you. I'm weak with ruby on rails, but I should be able to help you through the DB section.
You have two tables, Area which holds a polygon and Event which holds the event as a single point (it's a bit more complicated if the event is also an area and you're trying to pick out overlapping area's...if events are single points this works).
This is going to create a list of every area joined to every event...if you have 500 events and 20 area's, this will query will return 10'000 lines. Now you want to filter this so only events that are within the area they've been joined to. We can use st_contains for this as st_contains(polygon,point):
If you run this, it should give you a.,e. for all events within area's. Now it's just a matter of counting what you want to count.
This will give you a list of all your area's (by id) and the count of the events in it. Switching out a.id with e.id will give a list of event id's and the number area's they are in.
Unfortunately I have no idea how to express these queries within Ruby, but the DB concepts that you'll need are here...
For speed considerations, you should look into the GIStree indexing that Postgres has...indexed polygons perform exponentially better.
Edit:
PostGIS is a contrib file that comes with Postgres but does not exist in a standard install...you'll need to find this contrib file. These will install a series of GIS functions within your database including ST_Contains. (functions reside in a database, so make sure you install the functions in the DB you are using)
The second thing the PostGIS contrib files installs is the template_postGIS database which is required for the geometry datatypes (geom as a data type won't exist until this is installed).