3

我需要在我的 Rails 应用程序中知道一个点是否在多边形中,以便我想使用 rgeo gem。

要安装这个 geme,我按照rgeo git上的说明进行操作

然后我确定 GEOS 和 Proj4 已正确安装。

在此处输入图像描述

我还添加了这个 gem 'ffi-geos',没有特别的原因,只遵循 rgeo doc

最后我在 Rails 控制台上进行了测试以检查是否正常工作

  1. poly_text = "POLYGON ..." (很多点,我知道第一个点和最后一个点是相同的,否则我认为这不会起作用,因为需要是一个封闭的多边形)
  2. factory = RGeo::Cartesian::Factory (我正在使用笛卡尔工厂,因为根据我的调查,如果我使用球形工厂,这将不起作用)
  3. poly = factory.new().parse_wkt(poly_text)
  4. point1 = factory.new().parse_wkt("POINT (0 0)") (这个点不属于多边形)
  5. poly.within?(point1)
  6. 结果:RGeo::Error::UnsupportedOperation: Method Geometry#contains? 没有定义的。来自 (irb):26

在这里你可以看到输出: 在此处输入图像描述

更多信息:rails 版本 5.1.2 ide c9 os ubuntu

如果有人有解决方案,在此先感谢,我也愿意使用另一个 gem,或者其他什么,我的目标是解决我的点/多边形问题。

4

3 回答 3

5

您可以使用Geokit,只需包含gem 'geokit'在您的 Gemfile 中。

然后,您将需要创建一个点数组,其中每个点都是一个Geokit::LatLng.

例如:

points = []
points << Geokit::LatLng.new("-34.8922513", "-56.1468951")
points << Geokit::LatLng.new("-34.905204", "-56.1848322")
points << Geokit::LatLng.new("-34.9091105", "-56.170756")
polygon = Geokit::Polygon.new(points)
polygon.contains? polygon.centroid #this should return true

不要担心第一点是否与最后一点相同,正如源代码中所解释new那样,已经处理了这一点。

于 2017-10-21T23:58:26.883 回答
2

如果您只需要多边形中的点,则无需使用完整的库。这很简单,你可以自由地从头开始 Geokit 的实现(MIT 许可证):

def initialize(points)
    @points = points

    # A Polygon must be 'closed', the last point equal to the first point
    # Append the first point to the array to close the polygon
    @points << points[0] if points[0] != points[-1]
end

def contains?(point)
    last_point = @points[-1]
    oddNodes = false
    x = point.lng
    y = point.lat

    @points.each do |p|
        yi = p.lat
        xi = p.lng
        yj = last_point.lat
        xj = last_point.lng
        if yi < y && yj >= y ||
           yj < y && yi >= y
            oddNodes = !oddNodes if xi + (y - yi) / (yj - yi) * (xj - xi) < x
        end
        last_point = p
    end

    oddNodes
end

您可以在此处找到完整的源代码。当然,您必须创建自己的类并稍微更改代码。

于 2018-10-08T10:27:46.743 回答
1

在安装 GEOS 之前,我已经安装了 gem。卸载然后再次安装 rgeo gem 工作。

于 2017-10-27T21:28:23.650 回答