activerecord-postgres-earthdistance 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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