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 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 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.
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
- First, you must get a Google Maps API key (to get one go to http://code.google.com/apis/maps/signup.html) and store it in a constant:
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
- To add geocoding features to a class:
30
+ B) Add +latitude+ and +longitude+ columns to your model:
26
31
 
27
- geocoded_by :location
32
+ script/generate migration AddLatitudeAndLongitudeToYourModel latitude:float longitude:float
33
+ rake db:migrate
28
34
 
29
- Be sure your class defines attributes for storing latitude and longitude (use +float+ or +double+ database columns) and a location (human-readable address to be geocoded). These attribute names are all configurable; for example, to use +address+, +lat+, and +lon+ respectively:
35
+ C) Tell geocoder where your model stores its address:
30
36
 
31
- geocoded_by :address, :latitude => :lat, :longitude => :lon
37
+ geocoded_by :address
32
38
 
33
- A geocodable string is anything you'd use to search Google Maps. Any of the following are acceptable:
39
+ D) Optionally, auto-fetch coordinates every time your model is saved:
34
40
 
35
- 714 Green St, Big Town, MO
36
- Eiffel Tower, Paris, FR
37
- Paris, TX, US
41
+ after_validation :fetch_coordinates
38
42
 
39
- If your model has +address+, +city+, +state+, and +country+ attributes your +location+ method might look something like this:
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 +Venue+ is a geocoded model, it has the following named scopes:
48
+ Assuming +obj+ is an instance of a geocoded class, you can get its coordinates:
48
49
 
49
- Venue.near('Omaha, NE, US', 20) # venues within 20 miles of Omaha
50
- Venue.near([40.71, 100.23], 20) # venues within 20 miles of a point
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
- Assuming +obj+ has a valid string for its +location+:
53
+ If you have a lot of objects you can use this Rake task to geocode them all:
55
54
 
56
- obj.fetch_coordinates # returns coordinates [lat, lon]
57
- obj.fetch_coordinates! # also writes coordinates to object
55
+ rake geocode:all CLASS=YourModel
58
56
 
59
- Assuming +obj+ is geocoded (has latitude and longitude):
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.5
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). Valid units
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
- # The object must be geocoded before this method is called.
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
- lat,lon = self.class._get_coordinates(self)
140
- self.class.near([lat, lon], radius) - [self]
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 based on the object's location.
145
- # Returns an array <tt>[lat,lon]</tt>.
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 assign +latitude+ and +longitude+.
161
+ # Fetch coordinates and update (save) +latitude+ and +longitude+ data.
154
162
  #
155
163
  def fetch_coordinates!
156
- returning fetch_coordinates do |c|
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
- # +units+ :: <tt>:mi</tt> for miles (default), <tt>:km</tt> for kilometers
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
 
@@ -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.5"
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-26}
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
@@ -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
@@ -24,6 +24,10 @@ module ActiveRecord
24
24
  @attributes[attr_name] = value
25
25
  end
26
26
 
27
+ def update_attribute(attr_name, value)
28
+ write_attribute(attr_name, value)
29
+ end
30
+
27
31
  def self.named_scope(*args); end
28
32
  end
29
33
  end
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.5
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-26 00:00:00 -04:00
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