2013-03-21 15 views
5

Sto usando Sinatra e mongoid conducente, ora sto cercando di eseguire questa query in mongoid, in realtà ho un geospaziale campo (Poligono) chiamato 'geometria':

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

In realtà questo la query funziona nella shell di mongodb.

Tuttavia, voglio trovare gli stati che si intersecano con il punto specificato (Punto-in-poligono) con mongoid o forse altro driver rubino.

Qualsiasi aiuto sarebbe molto apprezzato.

Grazie.

risposta

3

Ho cercato di fare la stessa cosa. Da quello che ho potuto vedere, questo non è ancora supportato in Mongoid, e non so quali siano i tempi in termini di implementazione.

Nel frattempo, è possibile utilizzare il driver Mongoide/Ciclomotore per eseguire la query, ma non si otterrà nessuna delle proprietà di mappatura dell'oggetto fornita da Mongoid: si otterranno solo gli array/hash. Esempio seguente sintassi:

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

Ciò restituisce in realtà un array di hash con un "_id" chiave e il valore del campo _id, ma si potrebbe configurare questo come si desidera.

+0

Secondo Durran, il supporto per $ geoIntersects sarà nella versione 4.0 di Mongoid. – chrishol

+0

4.0 è rilasciato ma non vedo '$ geoIntersects' in changelog :(https://github.com/mongoid/mongoid/blob/master/CHANGELOG.md – oyatek

+0

o non rilasciato? :) Vedo 4.0 in changelog ma 4.0 non è disponibile per il download – oyatek

1

Mentre stiamo aspettando Mongoid 4.0 con l'aggiunta del supporto $ geoIntersects, l'ho aggiunto da solo. Permette il concatenamento e tutte le altre cose interessanti. Trova questo file (il vostro percorso può sembrare un po 'diverso):

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

Aggiungere questo punto qualsiasi del file:

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

ora si può fare:

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

Ho creato un fork [qui] (https://github.com/GovSciences/origin/tree/geo_intersects) che aggiunge tale funzionalità. Puoi usarlo nel tuo Gemfile come 'gem 'origin', git:" https://github.com/GovSciences/origin.git ", branch:" geo_intersects "' –

5

Sono stato di recente cercando questo, e dopo un po 'ho trovato il seguente. Forse qualcun altro avrà l'uso di questo ..

$ geoIntersects è ora implementate in 4.0.0.beta1 mongoid, ma non ben documentati .. Ho trovato questo nel changelog origine: 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 ]]) 

e un 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 ]]) 

Nel mio progetto ho mongoid (4.0.0.beta1) e l'origine (2.1.0) ho un modello poligonale

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 

E un modello 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 

Questo codice restituisce tutti i poligoni che ha questo punto all'interno.

Ci potrebbero essere modi più eleganti per farlo.Se così mi piacerebbe sentirlo :)

+1

Il motivo per il formato è GeoJSON. Vedere https://docs.mongodb.com/manual/reference/geojson/#polygon –

Problemi correlati