Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #49 from mattvv/master

Add Support for GeoKit Queries
  • Loading branch information...
commit d8cf43468e8842f7ebc0e682b659b8b2f03aa34f 2 parents cb371c0 + 7e5dd01
@adelevie authored
View
43 README.md
@@ -206,27 +206,36 @@ If you want to use parse_resource to back a simple authentication system for a R
GeoPoints
```ruby
- class Place < ParseResource::Base
- fields :location
- end
+class Place < ParseResource::Base
+ fields :location
+end
+
+place = Place.new
+place.location = ParseGeoPoint.new :latitude => 34.09300844216167, :longitude => -118.3780094460731
+place.save
+place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
- place = Place.new
- place.location = ParseGeoPoint.new :latitude => 34.09300844216167, :longitude => -118.3780094460731
- place.save
- place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
+place = Place.new
+place.location = ParseGeoPoint.new
+place.location.latitude = 34.09300844216167
+place.location.longitude = -118.3780094460731
+place.save
+place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
- place = Place.new
- place.location = ParseGeoPoint.new
- place.location.latitude = 34.09300844216167
- place.location.longitude = -118.3780094460731
- place.save
- place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
+server_place = Place.find(place.objectId)
+server_place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
+server_place.location.latitude #=> 34.09300844216167
+server_place.location.longitude #=> -118.3780094460731
+```
+
+Querying by GeoPoints
- server_place = Place.find(place.objectId)
- server_place.location.inspect #=> #<ParseGeoPoint:0x007fb4f39c7de0 @latitude=34.09300844216167, @longitude=-118.3780094460731>
- server_place.location.latitude #=> 34.09300844216167
- server_place.location.longitude #=> -118.3780094460731
+```ruby
+Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInMiles => 10).all
+Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInKilometers => 10).all
+Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInRadians => 10/3959).all
+Place.within_box(:location, [33.81637559726026, -118.3783150233789], [34.09300844216167, -118.3780094460731]).all
```
DEPRECATED
View
32 lib/parse_resource/query.rb
@@ -43,6 +43,38 @@ def count(count=1)
all
end
+ def near(klass, geo_point, options)
+ if geo_point.is_a? Array
+ geo_point = ParseGeoPoint.new :latitude => geo_point[0], :longitude => geo_point[1]
+ end
+
+ query = { "$nearSphere" => geo_point.to_pointer }
+ if options[:maxDistanceInMiles]
+ query["$maxDistanceInMiles"] = options[:maxDistanceInMiles]
+ elsif options[:maxDistanceInRadians]
+ query["$maxDistanceInRadians"] = options[:maxDistanceInRadians]
+ elsif options[:maxDistanceInKilometers]
+ query["$maxDistanceInKilometers"] = options[:maxDistanceInKilometers]
+ end
+
+ criteria[:conditions].merge!({ klass => query })
+ self
+ end
+
+ def within_box(klass, geo_point_south, geo_point_north)
+ if geo_point_south.is_a? Array
+ geo_point_south = ParseGeoPoint.new :latitude => geo_point_south[0], :longitude => geo_point_south[1]
+ end
+
+ if geo_point_north.is_a? Array
+ geo_point_north = ParseGeoPoint.new :latitude => geo_point_north[0], :longitude => geo_point_north[1]
+ end
+
+ query = { "$within" => { "$box" => [geo_point_south.to_pointer, geo_point_north.to_pointer]}}
+ criteria[:conditions].merge!({ klass => query })
+ self
+ end
+
def execute
params = {}
params.merge!({:where => criteria[:conditions].to_json}) if criteria[:conditions]
View
10 lib/parse_resource/query_methods.rb
@@ -46,7 +46,15 @@ def skip(n)
def order(attr)
Query.new(self).order(attr)
- end
+ end
+
+ def near(near, geo_point, options={})
+ Query.new(self).near(near, geo_point, options)
+ end
+
+ def within_box(near, geo_point_south, geo_point_north)
+ Query.new(self).within_box(near, geo_point_south, geo_point_north)
+ end
end
def self.included(base)
View
4 parse_resource.yml
@@ -3,8 +3,8 @@ development:
master_key: <%= ENV["PARSE_RESOURCE_MASTER_KEY"] %>
test:
- app_id: <%= ENV["PARSE_RESOURCE_APPLICATION_ID"] %>
- master_key: <%= ENV["PARSE_RESOURCE_MASTER_KEY"] %>
+ app_id: tIcrV2dwbkT7AqjU8Cn8FZFU60hk5qCnMXlJnJQq
+ master_key: H6xYlZzvwBZHUBjoyrFKXkWZoCVfqrmC3ARXMZjq
production:
View
17 test/test_parse_resource.rb
@@ -64,6 +64,7 @@ def test_count
end
def test_initialize_with_args
+ Spoon.destroy_all
@spoon = Spoon.new(:length => "title1", :width => "ipso")
assert @spoon.is_a?(Spoon)
assert_equal @spoon.length, "title1"
@@ -71,6 +72,7 @@ def test_initialize_with_args
end
def test_create
+ Spoon.destroy_all
VCR.use_cassette('test_create', :record => :new_episodes) do
s = Spoon.create(:length => "1234567890created!")
assert s.is_a?(Spoon)
@@ -80,6 +82,7 @@ def test_create
end
def test_find
+ Spoon.destroy_all
VCR.use_cassette('test_find', :record => :new_episodes) do
p1 = Spoon.create(:length => "Welcome")
p2 = Spoon.find(p1.id)
@@ -96,6 +99,7 @@ def test_find_should_throw_an_exception_if_object_is_nil
end
def test_first
+ Fork.destroy_all
VCR.use_cassette('test_first', :record => :new_episodes) do
f = Fork.create(:points => "firsttt")
p = Fork.first
@@ -141,6 +145,7 @@ def test_destroy_all
end
def test_chained_wheres
+ Straw.destroy_all
VCR.use_cassette('test_chained_wheres', :record => :new_episodes) do
p1 = Straw.create(:title => "chained_wheres", :body => "testing")
p2 = Straw.create(:title => "chained_wheres", :body => "testing_2")
@@ -152,6 +157,7 @@ def test_chained_wheres
end
def test_limit
+ Post.destroy_all
VCR.use_cassette('test_limit', :record => :new_episodes) do
15.times do |i|
Post.create(:title => "foo_"+i.to_s)
@@ -194,6 +200,7 @@ def test_order_no_field
#end
def test_all
+ Post.destroy_all
VCR.use_cassette('test_all', :record => :new_episodes) do
Post.create(:title => "11222")
Post.create(:title => "112ssd22")
@@ -204,6 +211,7 @@ def test_all
end
def test_attribute_getters
+ Post.destroy_all
VCR.use_cassette('test_attribute_getters', :record => :new_episodes) do
@post = Post.create(:title => "title1")
assert_equal @post.attributes['title'], "title1"
@@ -212,6 +220,7 @@ def test_attribute_getters
end
def test_attribute_setters
+ Post.destroy_all
VCR.use_cassette('test_attribute_setters', :record => :new_episodes) do
@post = Post.create(:title => "1")
@post.body = "newerbody"
@@ -220,6 +229,7 @@ def test_attribute_setters
end
def test_save
+ Post.destroy_all
VCR.use_cassette('test_save', :record => :new_episodes) do
@post = Post.create(:title => "testing save")
@post.save
@@ -230,6 +240,7 @@ def test_save
end
def test_each
+ Post.destroy_all
VCR.use_cassette('test_each', :record => :new_episodes) do
#Post.destroy_all
4.times do |i|
@@ -244,6 +255,7 @@ def test_each
end
def test_map
+ Post.destroy_all
VCR.use_cassette('test_map', :record => :new_episodes) do
#Post.destroy_all
4.times do |i|
@@ -255,6 +267,7 @@ def test_map
end
def test_id
+ Post.destroy_all
VCR.use_cassette('test_id', :record => :new_episodes) do
@post = Post.create(:title => "testing id")
assert @post.respond_to?(:id)
@@ -264,6 +277,7 @@ def test_id
end
def test_created_at
+ Post.destroy_all
VCR.use_cassette('test_created_at', :record => :new_episodes) do
@post = Post.create(:title => "testing created_at")
assert @post.respond_to?(:created_at)
@@ -273,6 +287,7 @@ def test_created_at
end
def test_updated_at
+ Post.destroy_all
VCR.use_cassette('test_updated_at', :record => :new_episodes) do
@post = Post.create(:title => "testing updated_at")
@post.title = "something else"
@@ -282,6 +297,7 @@ def test_updated_at
end
def test_update
+ Post.destroy_all
VCR.use_cassette('test_update', :record => :new_episodes) do
@post = Post.create(:title => "stale title")
updated_once = @post.updated_at
@@ -294,6 +310,7 @@ def test_update
end
def test_destroy
+ Post.destroy_all
VCR.use_cassette('test_destroy', :record => :new_episodes) do
p = Post.create(:title => "hello1234567890abc!")
id = p.id
View
3  test/test_parse_user.rb
@@ -29,7 +29,7 @@ class TestParseUser < Test::Unit::TestCase
#end
def test_username_should_be_unique
- #User.destroy_all
+ User.destroy_all
VCR.use_cassette('test_username_should_be_unique', :record => :new_episodes) do
u = User.create(:username => "alan", :password => "12345")
u2 = User.new(:username => "alan", :password => "56789")
@@ -40,6 +40,7 @@ def test_username_should_be_unique
end
def test_authenticate
+ User.destroy_all
VCR.use_cassette('test_authenticate', :record => :new_episodes) do
user = "fake_person"
pass = "fake_pass"
View
1  test/test_query_options.rb
@@ -19,6 +19,7 @@ class TestQueryOptions < Test::Unit::TestCase
#end
def test_skip
+ Event.destroy_all
VCR.use_cassette('test_skip', :record => :new_episodes) do
num_to_test = 10
num_to_test.times do |i|
View
127 test/test_types.rb
@@ -8,7 +8,6 @@ class Place < ParseResource::Base
end
class TestParseResource < Test::Unit::TestCase
-
def test_saving_geopoint_with_coords
Place.destroy_all
place = Place.new
@@ -40,4 +39,130 @@ def test_fetching_geopoint_field
assert_equal server_place.location.longitude, -118.3780094460731
end
+ def test_fetching_closest_10
+ Place.destroy_all
+ [[34.09300844216167, -118.3780094460731],
+ [34.09297074516132, -118.3779001235962],
+ [34.09291733023489, -118.3780601208767],
+ [34.09291733023489, -118.3780601208767],
+ [34.10020829969745, -118.2852727109533 ],
+ [33.81637559726026, -118.3783150233789 ],
+ [36.11837535750446, -115.1759274967512],
+ [48.0284736030277, 37.79059904775168 ],
+ [48.02790593385819, 37.78864582772938 ],
+ [48.02776282648577, 37.78850555419922 ],
+ [48.02750452121758, 37.78846263885498 ]
+ ].each do |location|
+ place = Place.new
+ place.location = ParseGeoPoint.new :latitude => location[0], :longitude => location[1]
+ place.save
+ end
+ assert_equal Place.count, 11
+ assert_equal Place.near(:location, [34.09300844216167, -118.3780094460731]).limit(10).all.count, 10
+ end
+
+ def test_fetching_closest_by_miles
+ Place.destroy_all
+ [[34.09300844216167, -118.3780094460731],
+ [34.09297074516132, -118.3779001235962],
+ [34.09291733023489, -118.3780601208767],
+ [34.09291733023489, -118.3780601208767],
+ [34.10020829969745, -118.2852727109533 ],
+ [33.81637559726026, -118.3783150233789 ],
+ [36.11837535750446, -115.1759274967512],
+ [48.0284736030277, 37.79059904775168 ],
+ [48.02790593385819, 37.78864582772938 ],
+ [48.02776282648577, 37.78850555419922 ],
+ [48.02750452121758, 37.78846263885498 ]
+ ].each do |location|
+ place = Place.new
+ place.location = ParseGeoPoint.new :latitude => location[0], :longitude => location[1]
+ place.save
+ end
+ assert_equal Place.count, 11
+ within_10_miles = Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInMiles => 10).all
+ assert_equal within_10_miles.count, 5
+ within_10_miles.map(&:location).each do |local|
+ assert_equal local.longitude > -119 && local.longitude < -118, true
+ assert_equal local.latitude > 34 && local.latitude < 35, true
+ end
+ end
+
+ def test_fetching_closest_by_kilometers
+ Place.destroy_all
+ [[34.09300844216167, -118.3780094460731],
+ [34.09297074516132, -118.3779001235962],
+ [34.09291733023489, -118.3780601208767],
+ [34.09291733023489, -118.3780601208767],
+ [34.10020829969745, -118.2852727109533 ],
+ [33.81637559726026, -118.3783150233789 ],
+ [36.11837535750446, -115.1759274967512],
+ [48.0284736030277, 37.79059904775168 ],
+ [48.02790593385819, 37.78864582772938 ],
+ [48.02776282648577, 37.78850555419922 ],
+ [48.02750452121758, 37.78846263885498 ]
+ ].each do |location|
+ place = Place.new
+ place.location = ParseGeoPoint.new :latitude => location[0], :longitude => location[1]
+ place.save
+ end
+ assert_equal Place.count, 11
+ within_10_kms = Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInKilometers => 10).all
+ assert_equal within_10_kms.count, 5
+ within_10_kms.map(&:location).each do |local|
+ assert_equal local.longitude > -119 && local.longitude < -118, true
+ assert_equal local.latitude > 34 && local.latitude < 35, true
+ end
+ end
+
+ def test_fetching_closest_by_radians
+ Place.destroy_all
+ [[34.09300844216167, -118.3780094460731],
+ [34.09297074516132, -118.3779001235962],
+ [34.09291733023489, -118.3780601208767],
+ [34.09291733023489, -118.3780601208767],
+ [34.10020829969745, -118.2852727109533 ],
+ [33.81637559726026, -118.3783150233789 ],
+ [36.11837535750446, -115.1759274967512],
+ [48.0284736030277, 37.79059904775168 ],
+ [48.02790593385819, 37.78864582772938 ],
+ [48.02776282648577, 37.78850555419922 ],
+ [48.02750452121758, 37.78846263885498 ]
+ ].each do |location|
+ place = Place.new
+ place.location = ParseGeoPoint.new :latitude => location[0], :longitude => location[1]
+ place.save
+ end
+ assert_equal Place.count, 11
+ within_10_radians = Place.near(:location, [34.09300844216167, -118.3780094460731], :maxDistanceInRadians => 10/3959).all
+ assert_equal within_10_radians.count, 1
+ within_10_radians.map(&:location).each do |local|
+ assert_equal local.longitude > -119 && local.longitude < -118, true
+ assert_equal local.latitude > 34 && local.latitude < 35, true
+ end
+ end
+
+ def test_fetching_cloest_within_box
+ Place.destroy_all
+ [[34.09300844216167, -118.3780094460731],
+ [34.09297074516132, -118.3779001235962],
+ [34.09291733023489, -118.3780601208767],
+ [34.09291733023489, -118.3780601208767],
+ [34.10020829969745, -118.2852727109533 ],
+ [33.81637559726026, -118.3783150233789 ],
+ [36.11837535750446, -115.1759274967512],
+ [48.0284736030277, 37.79059904775168 ],
+ [48.02790593385819, 37.78864582772938 ],
+ [48.02776282648577, 37.78850555419922 ],
+ [48.02750452121758, 37.78846263885498 ]
+ ].each do |location|
+ place = Place.new
+ place.location = ParseGeoPoint.new :latitude => location[0], :longitude => location[1]
+ place.save
+ end
+ assert_equal Place.count, 11
+ within_box = Place.within_box(:location, [33.81637559726026, -118.3783150233789], [34.09300844216167, -118.3780094460731]).all
+ assert_equal within_box.count, 4
+ end
+
end
Please sign in to comment.
Something went wrong with that request. Please try again.