【问题标题】:RGeo contains? on ModelRGeo 包含?在模型上
【发布时间】:2018-03-09 06:44:29
【问题描述】:

我需要找到类Place 的所有实例,其中它的多边形属性包含一个提供的点,如Place.for_point(pt)

==== 已添加 ====

好的,我可以执行这个查询,但是结果错误:

Place.all.where("ST_Contains(poly, ST_Point(#{up_pt.join(',')}))")
Place Load (0.5ms)  SELECT  "places".* FROM "places" WHERE (ST_Contains(poly, ST_Point(25.1,25.09999999999999))) LIMIT $1  [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>

提供的坐标似乎很清楚:提供的点中的坐标是 latlon 格式。但是坐标来自表中一个多边形的质心,所以它们应该在那个多边形内,这意味着我应该得到一组返回的 Place 记录......但我不是。

为什么?我错过了什么?

这是我期望包含点的多边形:

f.unproject(Place.last[:poly])
  Place Load (0.3ms)  SELECT  "places".* FROM "places" ORDER BY "places"."id" DESC LIMIT $1  [["LIMIT", 1]]
=> #<RGeo::Geographic::ProjectedPolygonImpl:0x3fcdc30f807c "POLYGON ((24.999999999999996 24.999999999999996, 25.2 24.999999999999996, 25.2 25.20000000000001, 24.999999999999996 25.20000000000001, 24.999999999999996 24.999999999999996))">
irb(main):134:0> 

==== 原帖====

我无法理解如何构建它。对于单个实例,我有一个方法contains?(pt) 作为Place 的实例方法,当调用place.contains?(@f.project(@pt_inside))@pt_inside 时工作正常:@pt_inside = @f.point(25.1,25.1),其中@f 是对象的工厂。

Place 的架构如下所示:

  create_table "places", force: :cascade do |t|
t.geometry "loc", limit: {:srid=>3857, :type=>"st_point"}
t.geometry "poly", limit: {:srid=>3857, :type=>"st_polygon"}
t.datetime "created_at", null: false
t.datetime "updated_at", null: false

结束

我的铁轨生锈了,但我无法对 Place work 类进行查询....

【问题讨论】:

  • def contains? 的正文是什么?如果我们不知道它是如何工作的,我们如何帮助您将其转换为查询? ;)
  • 我并没有刻薄,但我不确定一个不起作用的方法的内部机制是否会很有帮助......我明白你在说什么,我可以稍后发布(不是现在在带有代码的计算机上)。但目标很明确:根据参数点找到包含对象的多边形......

标签: ruby-on-rails rgeo


【解决方案1】:

根据 Taryn 的要求,这是返回二进制响应以确定当前对象的 :poly 属性是否包含该点的有效实例方法

def contains? pt
    self[:poly].contains?(pt)
end

显然是微不足道的。我遇到的问题是,当使用类方法查看哪些实例的多边形属性包含该点时,我迷失了......

def self.for_point pt
    where([:poly].contains?(pt))
end

这只是最后的、简化的、绝望的尝试。显然,需要发生的是每个对象都必须调用一个实例方法,但这基本上是一个 Ruby 循环,这样做似乎很疯狂,遍历一个可能有数百万个条目的表......

我不能完全理解示例显示的基于 sql 的语法,但无论如何,实例方法是纯 Ruby,为什么我需要在类查询中放入 sql,我问自己?还是我?

另外:我之前在没有 RGeo gem 的情况下编写了这样的代码,所以我检查了边界框,这很容易做到,而且会很好,因为所有此类查询都将基于矩形区域,该矩形区域基于垂直和水平边界。但我使用 gem 是有原因的,以避免我必须维护的许多功能和黑客行为......

【讨论】:

  • 很公平 - 我没有意识到这是一个如此简单的方法:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
相关资源
最近更新 更多