2013-03-21 20 views
5

Ich bin mit Sinatra und mongoid Fahrer, jetzt versuche ich diese Abfrage in mongoid auszuführen, ich habe tatsächlich ein Geospatial (Polygon) Feld 'Geometrie' genannt:

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

eigentlich gut Abfrage funktioniert in mongodb Shell.

Allerdings möchte ich Staaten finden, die sich mit gegebenen Punkt (Point-in-Polygon) mit Mongoid oder vielleicht anderen Ruby-Treiber schneidet.

Jede Hilfe würde sehr geschätzt werden.

Danke.

Antwort

3

Ich habe versucht, das gleiche zu tun. Soweit ich sehen konnte, wird dies in Mongoid noch nicht unterstützt, und ich weiß nicht, wie der Zeitrahmen in Bezug auf die Implementierung aussieht.

In der Zwischenzeit können Sie den Mongoid/Moped-Treiber verwenden, um die Abfrage auszuführen, aber Sie erhalten keine der Objekt-Mapping-Niceeness, die Mongoid bietet - Sie erhalten nur Arrays/Hashes zurück. Beispiel Syntax unten:

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

Dieses tatsächlich gibt ein Array von Hashes mit einem Schlüssel „_id“ und dem Wert des _id Feldes, aber man kann diese konfigurieren, wie Sie es wünschen.

+0

Laut Durran wird die Unterstützung für $ geoIntersects in der Mongoid 4.0-Version sein. – chrishol

+0

4.0 ist freigegeben, aber ich sehe '$ geoIntersects' nicht in changelog :(https://github.com/mongoid/mongoid/blob/master/CHANGELOG.md – oyatek

+0

oder nicht veröffentlicht? :) Ich sehe 4.0 in changelog aber 4.0 ist nicht zum Herunterladen verfügbar – oyatek

1

Während wir auf Mongoid 4.0 mit $ geoIntersects Unterstützung warten, habe ich es selbst hinzugefügt. Es ermöglicht Verkettung und alle anderen coolen Dinge. Finden Sie diese Datei (Ihr Weg ein bisschen anders aussehen):

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

Fügen Sie diese überall in der Datei:

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

Jetzt können Sie tun:

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

Ich habe eine Gabel [hier] (https://github.com/GovSciences/origin/tree/geo_interterects) erstellt, die diese Funktionalität hinzufügt. Sie können es in Ihrem Gemfile verwenden wie 'gem' Herkunft ', Git: "https://github.com/GovSciences/origin.git", Zweig: "geo_intersects" ' –

5

Ich war vor kurzem Suche nach diesem, und nach einer Weile fand ich folgendes. Vielleicht hat jemand anderen Gebrauch für diese haben wird ..

$ geoIntersects jetzt in mongoid 4.0.0.beta1 implementiert ist, aber nicht gut dokumentiert .. ich dies im Ursprung Changelog: 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 ]]) 

und ein commit: 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 ]]) 

In meinem Projekt habe ich mongoid (4.0.0.beta1) und Herkunft (2.1.0) ich habe ein Modell Polygon

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 

Und ein Modell 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 

Dieser Code gibt alle Polygone, die diesen Punkt nach innen hat.

Es könnte elegantere Möglichkeiten geben, dies zu tun.Wenn ja, würde ich es gerne hören :)

+1

Der Grund für das Format ist, dass es GeoJSON verwendet. Siehe https://docs.mongodb.com/manual/reference/geojson/#polygon –

Verwandte Themen