activerecord-postgres-earthdistance 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c055653d6b3f2dd1175e0a366c93db6e0ec9399f
4
- data.tar.gz: 4eda09c2594bd9bc93bbf8b0ca12c6871931391f
3
+ metadata.gz: f9458af5bee1a6c5416b450109d62aa9888f37d7
4
+ data.tar.gz: 52a8f7eb26951d8c77f3b1332b630ed5978f560f
5
5
  SHA512:
6
- metadata.gz: ecb1b7bc206b06d3b576d85ad2b68df5314a42ab6e83841e2ae75bc30f6a05d19c634af18d0d9a96fbce4bddd6bfd7593d0279b62623c1a475e7502d899655a3
7
- data.tar.gz: b41cf665cc0fc78ebe6cd4e763fd3291c069b12c89531f160cf79b17f8097d9b64c95f3229cc77f1e49c6baec6f7a89f49570026bce0411475bb5d29ccd77a11
6
+ metadata.gz: 7e53a9aa32535c9ffd538d28221f99618f7497add3a8b6f4f63b38c4fee66e05feb6d0ae420c0ecec8bf8f4dbb7271564b586751a139c49be7f39d06e9e7642c
7
+ data.tar.gz: 895a6791fdd7d3a6ed3b73b70254a136cb119517f0dc5ba341c0e7a1f02aee61aa34d3915ee68412cfeaa06cc42a2c192d9bded4600e2fdb6edf2a12d2c382d5
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- activerecord-postgres-earthdistance (0.3.2)
4
+ activerecord-postgres-earthdistance (0.4.0)
5
5
  pg
6
6
  rails (>= 3.1)
7
7
  rake
@@ -9,88 +9,88 @@ PATH
9
9
  GEM
10
10
  remote: http://rubygems.org/
11
11
  specs:
12
- actionmailer (4.0.4)
13
- actionpack (= 4.0.4)
14
- mail (~> 2.5.4)
15
- actionpack (4.0.4)
16
- activesupport (= 4.0.4)
17
- builder (~> 3.1.0)
18
- erubis (~> 2.7.0)
12
+ actionmailer (4.1.8)
13
+ actionpack (= 4.1.8)
14
+ actionview (= 4.1.8)
15
+ mail (~> 2.5, >= 2.5.4)
16
+ actionpack (4.1.8)
17
+ actionview (= 4.1.8)
18
+ activesupport (= 4.1.8)
19
19
  rack (~> 1.5.2)
20
20
  rack-test (~> 0.6.2)
21
- activemodel (4.0.4)
22
- activesupport (= 4.0.4)
23
- builder (~> 3.1.0)
24
- activerecord (4.0.4)
25
- activemodel (= 4.0.4)
26
- activerecord-deprecated_finders (~> 1.0.2)
27
- activesupport (= 4.0.4)
28
- arel (~> 4.0.0)
29
- activerecord-deprecated_finders (1.0.3)
30
- activesupport (4.0.4)
21
+ actionview (4.1.8)
22
+ activesupport (= 4.1.8)
23
+ builder (~> 3.1)
24
+ erubis (~> 2.7.0)
25
+ activemodel (4.1.8)
26
+ activesupport (= 4.1.8)
27
+ builder (~> 3.1)
28
+ activerecord (4.1.8)
29
+ activemodel (= 4.1.8)
30
+ activesupport (= 4.1.8)
31
+ arel (~> 5.0.0)
32
+ activesupport (4.1.8)
31
33
  i18n (~> 0.6, >= 0.6.9)
32
- minitest (~> 4.2)
33
- multi_json (~> 1.3)
34
+ json (~> 1.7, >= 1.7.7)
35
+ minitest (~> 5.1)
34
36
  thread_safe (~> 0.1)
35
- tzinfo (~> 0.3.37)
36
- arel (4.0.2)
37
- builder (3.1.4)
38
- diff-lcs (1.1.3)
37
+ tzinfo (~> 1.1)
38
+ arel (5.0.1.20140414130214)
39
+ builder (3.2.2)
40
+ diff-lcs (1.2.5)
39
41
  erubis (2.7.0)
40
42
  hike (1.2.3)
41
- i18n (0.6.9)
42
- json (1.7.6)
43
- mail (2.5.4)
44
- mime-types (~> 1.16)
45
- treetop (~> 1.4.8)
46
- mime-types (1.25.1)
47
- minitest (4.7.5)
48
- multi_json (1.9.2)
43
+ i18n (0.6.11)
44
+ json (1.8.1)
45
+ mail (2.6.3)
46
+ mime-types (>= 1.16, < 3)
47
+ mime-types (2.4.3)
48
+ minitest (5.4.3)
49
+ multi_json (1.10.1)
49
50
  pg (0.17.1)
50
- polyglot (0.3.4)
51
51
  rack (1.5.2)
52
52
  rack-test (0.6.2)
53
53
  rack (>= 1.0)
54
- rails (4.0.4)
55
- actionmailer (= 4.0.4)
56
- actionpack (= 4.0.4)
57
- activerecord (= 4.0.4)
58
- activesupport (= 4.0.4)
54
+ rails (4.1.8)
55
+ actionmailer (= 4.1.8)
56
+ actionpack (= 4.1.8)
57
+ actionview (= 4.1.8)
58
+ activemodel (= 4.1.8)
59
+ activerecord (= 4.1.8)
60
+ activesupport (= 4.1.8)
59
61
  bundler (>= 1.3.0, < 2.0)
60
- railties (= 4.0.4)
61
- sprockets-rails (~> 2.0.0)
62
- railties (4.0.4)
63
- actionpack (= 4.0.4)
64
- activesupport (= 4.0.4)
62
+ railties (= 4.1.8)
63
+ sprockets-rails (~> 2.0)
64
+ railties (4.1.8)
65
+ actionpack (= 4.1.8)
66
+ activesupport (= 4.1.8)
65
67
  rake (>= 0.8.7)
66
68
  thor (>= 0.18.1, < 2.0)
67
- rake (10.2.2)
68
- rdoc (3.12)
69
+ rake (10.4.2)
70
+ rdoc (4.2.0)
69
71
  json (~> 1.4)
70
- rspec (2.12.0)
71
- rspec-core (~> 2.12.0)
72
- rspec-expectations (~> 2.12.0)
73
- rspec-mocks (~> 2.12.0)
74
- rspec-core (2.12.2)
75
- rspec-expectations (2.12.1)
76
- diff-lcs (~> 1.1.3)
77
- rspec-mocks (2.12.2)
78
- sprockets (2.12.0)
72
+ rspec (2.99.0)
73
+ rspec-core (~> 2.99.0)
74
+ rspec-expectations (~> 2.99.0)
75
+ rspec-mocks (~> 2.99.0)
76
+ rspec-core (2.99.2)
77
+ rspec-expectations (2.99.2)
78
+ diff-lcs (>= 1.1.3, < 2.0)
79
+ rspec-mocks (2.99.2)
80
+ sprockets (2.12.3)
79
81
  hike (~> 1.2)
80
82
  multi_json (~> 1.0)
81
83
  rack (~> 1.0)
82
84
  tilt (~> 1.1, != 1.3.0)
83
- sprockets-rails (2.0.1)
85
+ sprockets-rails (2.2.2)
84
86
  actionpack (>= 3.0)
85
87
  activesupport (>= 3.0)
86
- sprockets (~> 2.8)
88
+ sprockets (>= 2.8, < 4.0)
87
89
  thor (0.19.1)
88
- thread_safe (0.3.3)
90
+ thread_safe (0.3.4)
89
91
  tilt (1.4.1)
90
- treetop (1.4.15)
91
- polyglot
92
- polyglot (>= 0.3.1)
93
- tzinfo (0.3.39)
92
+ tzinfo (1.2.2)
93
+ thread_safe (~> 0.1)
94
94
 
95
95
  PLATFORMS
96
96
  ruby
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  #ActiveRecord + PostgreSQL Earthdistance [![Build Status](https://travis-ci.org/diogob/activerecord-postgres-earthdistance.png?branch=master)](https://travis-ci.org/diogob/activerecord-postgres-earthdistance)
2
2
 
3
3
  Check distances with latitude and longitude using PostgreSQL special indexes.
4
- This gem enables your model to query the database using the earthdistance extension. This should be much faster than using trigonometry functions over standart indexs.
4
+ This gem enables your model to query the database using the earthdistance extension. This should be much faster than using trigonometry functions over standard indexes.
5
5
 
6
6
  ##Requirements
7
7
 
@@ -30,7 +30,7 @@ And run your bundler:
30
30
  Now you need to create a migration that adds earthdistance support for your
31
31
  PostgreSQL database:
32
32
 
33
- `rails g earthdistance:setup`
33
+ `rails g earth_distance:setup`
34
34
 
35
35
  Run it:
36
36
 
@@ -84,14 +84,28 @@ end
84
84
 
85
85
  ###Querying the database
86
86
 
87
- To query for all places within a given radius of 100 meters from the origin 30,50 just use:
87
+ To query for all places within a given radius of 100 meters from the origin -22.951916,-43.210487 just use:
88
88
  ```ruby
89
- Place.within_radius(500, 30, 50).all
89
+ Place.within_radius(100, -22.951916, -43.210487).all
90
90
  ```
91
91
 
92
92
  You can also order the records based on the distance from a point
93
93
  ```ruby
94
- Place.within_radius(500, 30, 50).order_by_distance(20,30)
94
+ Place.within_radius(100, -22.951916,-43.210487).order_by_distance(-22.951916,-43.210487)
95
+ ```
96
+
97
+ The `within_radius` query performs two checks: first against the *bounding box*, followed by computing the exact distance for
98
+ all contained elements. The latter might be computationally expensive for big ranges.
99
+ So if precision is not an issue but query speed is, you might want to query against the bounding box only:
100
+ ```ruby
101
+ Place.within_box(1_000_000, -22.951916,-43.210487)
102
+ ```
103
+
104
+ Select the distance from a point:
105
+ ```ruby
106
+ point = [-22.951916, -43.210487]
107
+ closest = Place.within_radius(100, *point).order_by_distance(*point).selecting_distance_from(*point).first
108
+ closest.distance
95
109
  ```
96
110
 
97
111
  ##Test Database
@@ -4,7 +4,7 @@ $:.unshift lib unless $:.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "activerecord-postgres-earthdistance"
7
- s.version = "0.3.2"
7
+ s.version = "0.4.0"
8
8
 
9
9
  s.platform = Gem::Platform::RUBY
10
10
  s.license = "MIT"
@@ -14,18 +14,32 @@ module ActiveRecordPostgresEarthdistance
14
14
  end
15
15
  end
16
16
 
17
+ def within_box radius, lat, lng
18
+ where("ll_to_earth(#{self.latitude_column}, #{self.longitude_column}) <@ earth_box(ll_to_earth(?, ?), ?)", lat, lng, radius)
19
+ end
20
+
17
21
  def within_radius radius, lat, lng
18
- where(["ll_to_earth(#{self.latitude_column}, #{self.longitude_column}) <@ earth_box(ll_to_earth(?, ?), ?)" +
19
- "AND earth_distance(ll_to_earth(#{self.latitude_column}, #{self.longitude_column}), ll_to_earth(?, ?)) <= ?",
20
- lat, lng, radius, lat, lng, radius])
22
+ within_box(radius, lat, lng).where("earth_distance(ll_to_earth(#{self.latitude_column}, #{self.longitude_column}), ll_to_earth(?, ?)) <= ?", lat, lng, radius)
21
23
  end
22
24
 
23
25
  def order_by_distance lat, lng, order= "ASC"
24
26
  order("earth_distance(ll_to_earth(#{self.latitude_column}, #{self.longitude_column}), ll_to_earth(#{lat}, #{lng})) #{order}")
25
27
  end
28
+ end
29
+ end
26
30
 
31
+ module QueryMethods
32
+ def selecting_distance_from lat, lng, name="distance", include_default_columns=true
33
+ clone.tap do |relation|
34
+ values = []
35
+ values << relation.arel_table[Arel.star] if relation.select_values.empty? && include_default_columns
36
+ values << "earth_distance(ll_to_earth(#{self.latitude_column}, #{self.longitude_column}), ll_to_earth(#{lat}, #{lng})) as #{name}"
37
+ relation.select_values = values
38
+ end
27
39
  end
28
40
  end
41
+
29
42
  end
30
43
 
31
44
  ActiveRecord::Base.send :include, ActiveRecordPostgresEarthdistance::ActsAsGeolocated
45
+ ActiveRecord::Relation.send :include, ActiveRecordPostgresEarthdistance::QueryMethods
@@ -1,6 +1,46 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "ActiveRecord::Base.act_as_geolocated" do
4
+ describe "#within_box" do
5
+ let(:test_data) { { lat: nil, lng: nil, radius: nil } }
6
+
7
+ subject { Place.within_box(test_data[:radius], test_data[:lat], test_data[:lng]) }
8
+
9
+ before(:all) { @place = Place.create!(:lat => -30.0277041, :lng => -51.2287346) }
10
+ after(:all) { @place.destroy }
11
+
12
+ context "when query with null data" do
13
+ it { should be_empty }
14
+ end
15
+
16
+ context "when query for the exact same point with radius 0" do
17
+ let(:test_data) { { lat: -30.0277041, lng: -51.2287346 , radius: 0 } }
18
+
19
+ it { should == [@place] }
20
+ end
21
+
22
+ context "when query for place within the box" do
23
+ let(:test_data) { { radius: 4000000, lat: -27.5969039, lng: -48.5494544 } }
24
+
25
+ it { should == [@place] }
26
+ end
27
+
28
+ context "when query for place within the box, but outside the radius" do
29
+ let(:test_data) { { radius: 300000, lat: -27.5969039, lng: -48.5494544 } }
30
+
31
+ it "the place shouldn't be within the radius" do
32
+ Place.within_radius(test_data[:radius], test_data[:lat], test_data[:lng]).should be_empty
33
+ end
34
+
35
+ it { should == [@place] }
36
+ end
37
+
38
+ context "when query for place outside the box" do
39
+ let(:test_data) { { radius: 1000, lat: -27.5969039, lng: -48.5494544 } }
40
+ it { should be_empty }
41
+ end
42
+ end
43
+
4
44
  describe "#within_radius" do
5
45
  let(:test_data){ {lat: nil, lng: nil, radius: nil} }
6
46
  subject{ Place.within_radius(test_data[:radius], test_data[:lat], test_data[:lng]) }
@@ -28,6 +68,7 @@ describe "ActiveRecord::Base.act_as_geolocated" do
28
68
 
29
69
  context "when query for place outside the radius" do
30
70
  let(:test_data){ {radius: 1000, lat: -27.5969039, lng: -48.5494544} }
71
+ it{ should == [] }
31
72
  end
32
73
  end
33
74
 
@@ -53,4 +94,25 @@ describe "ActiveRecord::Base.act_as_geolocated" do
53
94
  it{ should == [@place_2, @place_1] }
54
95
  end
55
96
  end
97
+
98
+ describe "#selecting_distance_from" do
99
+ let(:current_location){ {lat: nil, lng: nil, radius: nil} }
100
+ subject do
101
+ Place.
102
+ order_by_distance(current_location[:lat], current_location[:lng]).
103
+ selecting_distance_from(current_location[:lat], current_location[:lng]).
104
+ first.
105
+ try{|p| [p.data, p.distance.to_f] }
106
+ end
107
+ before(:all) do
108
+ @place = Place.create!(:data => 'Amsterdam', :lat => 52.370216, :lng => 4.895168) #Amsterdam
109
+ end
110
+ after(:all) do
111
+ @place.destroy
112
+ end
113
+ context "when selecting distance" do
114
+ let(:current_location){{lat: 52.229676, lng: 21.012229}} #Warsaw
115
+ it{ should == ["Amsterdam", 1095013.87438311] }
116
+ end
117
+ end
56
118
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-postgres-earthdistance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Diogo Biazus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-16 00:00:00.000000000 Z
11
+ date: 2014-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -142,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
142
142
  version: 1.3.6
143
143
  requirements: []
144
144
  rubyforge_project:
145
- rubygems_version: 2.2.0
145
+ rubygems_version: 2.2.2
146
146
  signing_key:
147
147
  specification_version: 4
148
148
  summary: Check distances with latitude and longitude using PostgreSQL special indexes