【问题标题】:How do I perform a $geoIntersects query with Mongoid?如何使用 Mongoid 执行 $geoIntersects 查询?
【发布时间】:2013-03-11 14:13:38
【问题描述】:

我正在使用 Sinatra 和 mongoid 驱动程序,现在我正在尝试在 mongoid 中执行此查询,实际上我有一个名为 'geometry 的地理空间(多边形)字段':

db.states.find({
    geometry: {
        $geoIntersects: {
            $geometry: {
                type: "Point",
                coordinates: [-99.176524, 18.929204]
            }
        }
    }
})

其实这个查询是在 mongodb shell 中工作的。

但是,我想找到与给定点(Point-in-polygon)与 mongoid 或其他 ruby​​ 驱动程序相交的状态。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

    标签: mongodb sinatra mongoid geospatial


    【解决方案1】:

    我一直在考虑做同样的事情。据我所知,这在 Mongoid 中尚不支持,而且我不知道它实施的时间范围。

    与此同时,您可以使用 Mongoid/Moped 驱动程序来运行查询,但您不会获得 Mongoid 提供的任何对象映射功能 - 您只会获得数组/哈希值。下面的示例语法:

    ids = Mongoid.default_session["states"].find( geometry:
        { "$geoIntersects" =>
            { "$geometry" =>
                { type: "Point", coordinates: [-99.176524, 18.929204] }
            }
        }
    ).select( id: 1 )
    

    这实际上返回一个带有键“_id”和 _id 字段值的哈希数组,但您可以根据需要进行配置。

    【讨论】:

    • 根据 Durran 的说法,对 $geoIntersects 的支持将在 Mongoid 4.0 版本中。
    • 4.0 已发布,但我在更新日志中没有看到 $geoIntersects :( github.com/mongoid/mongoid/blob/master/CHANGELOG.md
    • 还是没有发布? :) 我在更新日志中看到 4.0,但 4.0 无法下载
    【解决方案2】:

    当我们在等待 Mongoid 4.0 添加 $geoIntersects 支持时,我自己添加了它。它允许链接和所有其他很酷的东西。找到这个文件(你的路径可能看起来有点不同):

    /usr/local/lib/ruby/gems/1.9.1/gems/origin-1.1.0/lib/origin/selectable.rb
    

    在文件的任何地方添加这个:

    def geo_intersects(criterion = nil)
       __override__(criterion, "$geoIntersects")
    end
    key :geo_intersects, :override, "$geoIntersects"
    

    现在你可以这样做了:

    Houses.where(:color => "red").geo_intersects(:loc => {"$geometry" => {:type => "Polygon", :coordinates => [[[1,2],[2,3][1,2]]]})
    

    【讨论】:

    • 我创建了一个 fork here 来添加该功能。您可以在您的 Gemfile 中使用它,例如 gem 'origin', git: "https://github.com/GovSciences/origin.git", branch: "geo_intersects"
    【解决方案3】:

    我最近正在寻找这个,过了一段时间我发现了以下内容。也许其他人会对此有用..

    $geoIntersects 现在在 mongoid 4.0.0.beta1 中实现,但没有很好的记录。我在原始更改日志中发现了这一点:https://github.com/mongoid/origin/blob/master/CHANGELOG.md#new-features-1

    query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]])
    query.geo_spacial(:location.intersects_point => [[ 1, 10 ]])
    query.geo_spacial(:location.intersects_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
    query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]])
    

    并提交:https://github.com/mongoid/origin/commit/30938fad644f17fe38f62cf90571b78783b900d8

     # Add a $geoIntersects selection. Symbol operators must be used as shown in
     # the examples to expand the criteria.
     #
     # @note The only valid geometry shapes for a $geoIntersects are: :line,
     #   :point, and :polygon.
     # ...
     # @example Add a geo intersect criterion for a point.
     #   query.geo_intersects(:location.point => [[ 1, 10 ]])
    

    在我的项目中,我有 mongoid (4.0.0.beta1) 和 origin (2.1.0) 我有一个模型多边形

    class Polygon
      include Mongoid::Document
      # some fields 
    
      embeds_many :loc
    
      # coordinates is an array of two points: [10, 12]
      def find_polygons_with_point(coordinates)
        # This is where the magic happens!
        Polygon.all.geo_spacial(:loc.intersects_point => coordinates)
      end
    
    end
    

    还有一个模型 Loc

    class Loc
      field :type, type: String #Need to be set to 'Polygon' when creating a new location.
      field :coordinates, type: Array
      # For some reason the array has to be in the format
      # [ [ [1,1], [2,3], [5,3], [1,1] ] ]
      # And the first coordinate needs to be the same as the last
      # to close the polygon
    
      embedded_in :polygon
    
      index({ coordinates: "2d" }, { min: -200, max: 200 }) #may not need min/max
    end
    

    此代码返回包含该点的所有多边形。

    可能有更优雅的方式来做到这一点。如果是这样,我想听听:)

    【讨论】:

    猜你喜欢
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多