From 5c59ec46b69a85f33daa540b75d608202435dbd4 Mon Sep 17 00:00:00 2001 From: "Adam St. John" Date: Tue, 23 Dec 2014 09:12:47 -0500 Subject: [PATCH 1/2] Add circular geo_spacial queries. Added within_circle and within_sphere queries to geo_spacial selector to handle mongodb's respective $center and $centerSphere queries. --- lib/origin/selectable.rb | 10 +++++++-- spec/origin/selectable_spec.rb | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/lib/origin/selectable.rb b/lib/origin/selectable.rb index a7560ad..ff54fcc 100644 --- a/lib/origin/selectable.rb +++ b/lib/origin/selectable.rb @@ -138,8 +138,6 @@ def exists(criterion = nil) # @note The only valid geometry shapes for a $geoIntersects are: # :intersects_line, :intersects_point, and :intersects_polygon. # - # @note The only valid geometry shape for a $geoWithin is :within_polygon - # # @example Add a geo intersect criterion for a line. # query.geo_spacial(:location.intersects_line => [[ 1, 10 ], [ 2, 10 ]]) # @@ -152,6 +150,12 @@ def exists(criterion = nil) # @example Add a geo within criterion for a polygon. # query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]) # + # @example Add a geo within criterian for a circle. + # query.geo_spacial(:location.within_circle => [[x, y], radius]) + # + # @example Add a geo within criterian for a sphere. Radius specified in radians. + # query.geo_spacial(:location.within_sphere => [[x, y], radius]) + # # @param [ Hash ] criterion The criterion. # # @return [ Selectable ] The cloned selectable. @@ -172,6 +176,8 @@ def geo_spacial(criterion = nil) key :within_polygon, :override, "$geoWithin", "$geometry" do |value| { "type" => POLYGON, "coordinates" => value } end + key :within_circle, :override, "$geoWithin", "$center" + key :within_sphere, :override, "$geoWithin", "$centerSphere" # Add the $gt criterion to the selector. # diff --git a/spec/origin/selectable_spec.rb b/spec/origin/selectable_spec.rb index 6adc7ca..8059c1a 100644 --- a/spec/origin/selectable_spec.rb +++ b/spec/origin/selectable_spec.rb @@ -1075,6 +1075,46 @@ def localized? it_behaves_like "a cloning selection" end + + + context "when the geometry is a circle" do + + let(:selection) do + query.geo_spacial(:location.within_circle => [[ 1, 10 ], 200]) + end + + it "adds the $center expression" do + expect(selection.selector).to eq({ + "location" => { + "$geoWithin" => { + "$center" => [[1,10], 200] + } + } + }) + end + + it_behaves_like "a cloning selection" + end + + context "when the geometry is a spherical circle" do + + let(:selection) do + query.geo_spacial(:location.within_sphere => [[ 1, 10 ], 200]) + end + + it "adds the $center expression" do + expect(selection.selector).to eq({ + "location" => { + "$geoWithin" => { + "$centerSphere" => [[1,10], 200] + } + } + }) + end + + it_behaves_like "a cloning selection" + end + end end From 3aec3fd4f58e0cf3301107e9d1ba64a1fee17e39 Mon Sep 17 00:00:00 2001 From: "Adam St. John" Date: Tue, 23 Dec 2014 09:16:32 -0500 Subject: [PATCH 2/2] Adjust documentation syntax error for geo_spacial polygon selections. Fixes #102. The correct query is to use triple brackets as specified in the specs and in mongodb documentation. The example documentation for Origin was missing a set of brackets. --- lib/origin/selectable.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/origin/selectable.rb b/lib/origin/selectable.rb index ff54fcc..0022d9b 100644 --- a/lib/origin/selectable.rb +++ b/lib/origin/selectable.rb @@ -145,10 +145,10 @@ def exists(criterion = nil) # query.geo_spacial(:location.intersects_point => [[ 1, 10 ]]) # # @example Add a geo intersect criterion for a polygon. - # query.geo_spacial(:location.intersects_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]) + # query.geo_spacial(:location.intersects_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]) # # @example Add a geo within criterion for a polygon. - # query.geo_spacial(:location.within_polygon => [[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]) + # query.geo_spacial(:location.within_polygon => [[[ 1, 10 ], [ 2, 10 ], [ 1, 10 ]]]) # # @example Add a geo within criterian for a circle. # query.geo_spacial(:location.within_circle => [[x, y], radius])