rails-geocoder 0.8.5 → 0.8.6
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.
- data/CHANGELOG.rdoc +5 -0
- data/README.rdoc +55 -24
- data/VERSION +1 -1
- data/lib/geocoder.rb +23 -20
- data/rails-geocoder.gemspec +3 -2
- data/tasks/geocoder_tasks.rake +15 -0
- data/test/geocoder_test.rb +0 -5
- data/test/test_helper.rb +4 -0
- metadata +3 -2
data/CHANGELOG.rdoc
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
Per-release changes to Geocoder.
|
4
4
|
|
5
|
+
== 0.8.6 (2009 Oct 27)
|
6
|
+
|
7
|
+
* The fetch_coordinates method now assigns coordinates to attributes (behaves like fetch_coordinates! used to) and fetch_coordinates! both assigns and saves the attributes.
|
8
|
+
* Added geocode:all rake task.
|
9
|
+
|
5
10
|
== 0.8.5 (2009 Oct 26)
|
6
11
|
|
7
12
|
* Avoid calling deprecated method from within Geocoder itself.
|
data/README.rdoc
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
= Geocoder
|
2
2
|
|
3
|
-
Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It
|
3
|
+
Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It's as simple as calling <tt>fetch_coordinates!</tt> on your objects, and then using a named scope like <tt>Venue.near("Billings, MT")</tt>.
|
4
|
+
|
5
|
+
Geocoder does not rely on proprietary database functions so finding geocoded objects in a given area is easily done using out-of-the-box MySQL or even SQLite.
|
6
|
+
|
4
7
|
|
5
8
|
== 1. Install
|
6
9
|
|
@@ -16,51 +19,53 @@ or as a gem:
|
|
16
19
|
# at command prompt:
|
17
20
|
sudo rake gems:install
|
18
21
|
|
22
|
+
|
19
23
|
== 2. Configure
|
20
24
|
|
21
|
-
|
25
|
+
A) Get a Google Maps API key (see http://code.google.com/apis/maps/signup.html) and store it in a constant:
|
22
26
|
|
27
|
+
# eg, in config/initializers/google_maps.rb
|
23
28
|
GOOGLE_MAPS_API_KEY = "..."
|
24
29
|
|
25
|
-
|
30
|
+
B) Add +latitude+ and +longitude+ columns to your model:
|
26
31
|
|
27
|
-
|
32
|
+
script/generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float
|
33
|
+
rake db:migrate
|
28
34
|
|
29
|
-
|
35
|
+
C) Tell geocoder where your model stores its address:
|
30
36
|
|
31
|
-
geocoded_by :address
|
37
|
+
geocoded_by :address
|
32
38
|
|
33
|
-
|
39
|
+
D) Optionally, auto-fetch coordinates every time your model is saved:
|
34
40
|
|
35
|
-
|
36
|
-
Eiffel Tower, Paris, FR
|
37
|
-
Paris, TX, US
|
41
|
+
after_validation :fetch_coordinates
|
38
42
|
|
39
|
-
|
43
|
+
<i>Note that you are not stuck with the +latitude+ and +longitude+ column names, or the +address+ method. See "More On Configuration" below for details.</i>
|
40
44
|
|
41
|
-
def location
|
42
|
-
[address, city, state, country].compact.join(', ')
|
43
|
-
end
|
44
45
|
|
45
46
|
== 3. Use
|
46
47
|
|
47
|
-
Assuming +
|
48
|
+
Assuming +obj+ is an instance of a geocoded class, you can get its coordinates:
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
Venue.geocoded # venues with coordinates
|
52
|
-
Venue.not_geocoded # venues without coordinates
|
50
|
+
obj.fetch_coordinates # fetches and assigns coordinates
|
51
|
+
obj.fetch_coordinates! # also saves lat, lon attributes
|
53
52
|
|
54
|
-
|
53
|
+
If you have a lot of objects you can use this Rake task to geocode them all:
|
55
54
|
|
56
|
-
|
57
|
-
obj.fetch_coordinates! # also writes coordinates to object
|
55
|
+
rake geocode:all CLASS=YourModel
|
58
56
|
|
59
|
-
|
57
|
+
Once +obj+ is geocoded you can do things like this:
|
60
58
|
|
61
59
|
obj.nearbys(30) # other objects within 30 miles
|
62
60
|
obj.distance_to(40.714, -100.234) # distance to arbitrary point
|
63
61
|
|
62
|
+
To find objects by location, use the following named scopes:
|
63
|
+
|
64
|
+
Venue.near('Omaha, NE, US', 20) # venues within 20 miles of Omaha
|
65
|
+
Venue.near([40.71, 100.23], 20) # venues within 20 miles of a point
|
66
|
+
Venue.geocoded # venues with coordinates
|
67
|
+
Venue.not_geocoded # venues without coordinates
|
68
|
+
|
64
69
|
Some utility methods are also available:
|
65
70
|
|
66
71
|
# distance (in miles) between Eiffel Tower and Empire State Building
|
@@ -70,7 +75,33 @@ Some utility methods are also available:
|
|
70
75
|
Geocoder.fetch_coordinates("25 Main St, Cooperstown, NY")
|
71
76
|
|
72
77
|
|
78
|
+
== More On Configuration
|
79
|
+
|
80
|
+
You are not stuck with using the +latitude+ and +longitude+ database column names for storing coordinates. For example, to use +lat+ and +lon+:
|
81
|
+
|
82
|
+
geocoded_by :address, :latitude => :lat, :longitude => :lon
|
83
|
+
|
84
|
+
The string to use for geocoding can be anything you'd use to search Google Maps. For example, any of the following are acceptable:
|
85
|
+
|
86
|
+
714 Green St, Big Town, MO
|
87
|
+
Eiffel Tower, Paris, FR
|
88
|
+
Paris, TX, US
|
89
|
+
|
90
|
+
If your model has +address+, +city+, +state+, and +country+ attributes you might do something like this:
|
91
|
+
|
92
|
+
geocoded_by :location
|
93
|
+
|
94
|
+
def location
|
95
|
+
[address, city, state, country].compact.join(', ')
|
96
|
+
end
|
97
|
+
|
98
|
+
|
73
99
|
Please see the code for more methods and detailed information about arguments (eg, working with kilometers).
|
74
100
|
|
75
|
-
|
101
|
+
|
102
|
+
== To-do List
|
103
|
+
|
104
|
+
* <tt>install.rb</tt> should do some setup when installed as a plugin
|
105
|
+
|
106
|
+
|
76
107
|
Copyright (c) 2009 Alex Reisner, released under the MIT license
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.6
|
data/lib/geocoder.rb
CHANGED
@@ -121,8 +121,8 @@ module Geocoder
|
|
121
121
|
end
|
122
122
|
|
123
123
|
##
|
124
|
-
# Calculate the distance from the object to a point (lat,lon).
|
125
|
-
# are defined in <tt>distance_between</tt> class method.
|
124
|
+
# Calculate the distance from the object to a point (lat,lon).
|
125
|
+
# Valid units are defined in <tt>distance_between</tt> class method.
|
126
126
|
#
|
127
127
|
def distance_to(lat, lon, units = :mi)
|
128
128
|
return nil unless geocoded?
|
@@ -131,34 +131,37 @@ module Geocoder
|
|
131
131
|
end
|
132
132
|
|
133
133
|
##
|
134
|
-
# Get other geocoded objects within a given radius.
|
135
|
-
#
|
134
|
+
# Get other geocoded objects within a given radius (in miles). Takes a
|
135
|
+
# radius (in miles) and options for passing to the +near+ named scope
|
136
|
+
# (<tt>:order</tt>, <tt>:limit</tt>, and <tt>:offset</tt>).
|
136
137
|
#
|
137
|
-
def nearbys(radius = 20)
|
138
|
+
def nearbys(radius = 20, options = {})
|
138
139
|
return [] unless geocoded?
|
139
|
-
|
140
|
-
|
140
|
+
coords = self.class._get_coordinates(self)
|
141
|
+
options = {:conditions => ["id != ?", id]}.merge(options)
|
142
|
+
self.class.near(coords, radius, options) - [self]
|
141
143
|
end
|
142
144
|
|
143
145
|
##
|
144
|
-
# Fetch coordinates
|
145
|
-
#
|
146
|
+
# Fetch coordinates and assign +latitude+ and +longitude+. Also returns
|
147
|
+
# coordinates as an array: <tt>[lat, lon]</tt>.
|
146
148
|
#
|
147
|
-
def fetch_coordinates
|
149
|
+
def fetch_coordinates(save = false)
|
148
150
|
location = send(self.class.geocoder_options[:method_name])
|
149
|
-
Geocoder.fetch_coordinates(location)
|
151
|
+
returning Geocoder.fetch_coordinates(location) do |c|
|
152
|
+
unless c.blank?
|
153
|
+
method = (save ? "update" : "write") + "_attribute"
|
154
|
+
send method, self.class.geocoder_options[:latitude], c[0]
|
155
|
+
send method, self.class.geocoder_options[:longitude], c[1]
|
156
|
+
end
|
157
|
+
end
|
150
158
|
end
|
151
|
-
|
159
|
+
|
152
160
|
##
|
153
|
-
# Fetch coordinates and
|
161
|
+
# Fetch coordinates and update (save) +latitude+ and +longitude+ data.
|
154
162
|
#
|
155
163
|
def fetch_coordinates!
|
156
|
-
|
157
|
-
unless c.blank?
|
158
|
-
write_attribute(self.class.geocoder_options[:latitude], c[0])
|
159
|
-
write_attribute(self.class.geocoder_options[:longitude], c[1])
|
160
|
-
end
|
161
|
-
end
|
164
|
+
fetch_coordinates(true)
|
162
165
|
end
|
163
166
|
|
164
167
|
##
|
@@ -184,7 +187,7 @@ module Geocoder
|
|
184
187
|
# Calculate the distance between two points on Earth (Haversine formula).
|
185
188
|
# Takes two sets of coordinates and an options hash:
|
186
189
|
#
|
187
|
-
#
|
190
|
+
# <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt>
|
188
191
|
#
|
189
192
|
def self.distance_between(lat1, lon1, lat2, lon2, options = {})
|
190
193
|
|
data/rails-geocoder.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rails-geocoder}
|
8
|
-
s.version = "0.8.
|
8
|
+
s.version = "0.8.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex Reisner"]
|
12
|
-
s.date = %q{2009-10-
|
12
|
+
s.date = %q{2009-10-27}
|
13
13
|
s.description = %q{Geocoder adds object geocoding and database-agnostic distance calculations to Ruby on Rails. It does not rely on proprietary database functions so finding geocoded objects in a given area is easily done using out-of-the-box MySQL or even SQLite.}
|
14
14
|
s.email = %q{alex@alexreisner.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
"init.rb",
|
28
28
|
"lib/geocoder.rb",
|
29
29
|
"rails-geocoder.gemspec",
|
30
|
+
"tasks/geocoder_tasks.rake",
|
30
31
|
"test/fixtures/madison_square_garden.xml",
|
31
32
|
"test/geocoder_test.rb",
|
32
33
|
"test/test_helper.rb"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def klass
|
2
|
+
class_name = ENV['CLASS'] || ENV['class']
|
3
|
+
raise "Please specify a CLASS (model)" unless class_name
|
4
|
+
Object.const_get(class_name)
|
5
|
+
end
|
6
|
+
|
7
|
+
namespace :geocode do
|
8
|
+
|
9
|
+
desc "Geocode all objects without coordinates."
|
10
|
+
task :all => :environment do
|
11
|
+
klass.not_geocoded.each do |obj|
|
12
|
+
obj.fetch_coordinates!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/test/geocoder_test.rb
CHANGED
@@ -5,11 +5,6 @@ class GeocoderTest < Test::Unit::TestCase
|
|
5
5
|
def test_fetch_coordinates
|
6
6
|
v = Venue.new(*venue_params(:msg))
|
7
7
|
assert_equal [40.7495760, -73.9916733], v.fetch_coordinates
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_fetch_coordinates!
|
11
|
-
v = Venue.new(*venue_params(:msg))
|
12
|
-
v.fetch_coordinates!
|
13
8
|
assert_equal [40.7495760, -73.9916733], [v.latitude, v.longitude]
|
14
9
|
end
|
15
10
|
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails-geocoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Reisner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-10-
|
12
|
+
date: 2009-10-27 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- init.rb
|
34
34
|
- lib/geocoder.rb
|
35
35
|
- rails-geocoder.gemspec
|
36
|
+
- tasks/geocoder_tasks.rake
|
36
37
|
- test/fixtures/madison_square_garden.xml
|
37
38
|
- test/geocoder_test.rb
|
38
39
|
- test/test_helper.rb
|