rails-geocoder 0.9.8 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/CHANGELOG.rdoc +16 -1
- data/README.rdoc +123 -55
- data/Rakefile +2 -33
- data/VERSION +1 -0
- data/lib/geocoder.rb +79 -5
- data/lib/geocoder/configuration.rb +11 -3
- data/lib/geocoder/lookups/base.rb +110 -0
- data/lib/geocoder/lookups/freegeoip.rb +40 -0
- data/lib/geocoder/lookups/google.rb +31 -0
- data/lib/geocoder/lookups/yahoo.rb +29 -0
- data/lib/geocoder/{active_record.rb → orms/active_record.rb} +27 -82
- data/lib/geocoder/orms/active_record_legacy.rb +58 -0
- data/lib/geocoder/orms/base.rb +96 -0
- data/lib/geocoder/railtie.rb +50 -38
- data/lib/geocoder/request.rb +17 -0
- data/lib/geocoder/results/base.rb +58 -0
- data/lib/geocoder/results/freegeoip.rb +37 -0
- data/lib/geocoder/{result.rb → results/google.rb} +26 -8
- data/lib/geocoder/results/yahoo.rb +40 -0
- data/lib/tasks/geocoder.rake +1 -1
- data/rails-geocoder.gemspec +15 -0
- data/test/fixtures/freegeoip_74_200_247_59.json +12 -0
- data/test/fixtures/google_garbage.json +456 -0
- data/test/fixtures/google_madison_square_garden.json +57 -0
- data/test/fixtures/google_no_results.json +4 -0
- data/test/fixtures/yahoo_garbage.json +50 -0
- data/test/fixtures/yahoo_madison_square_garden.json +46 -0
- data/test/fixtures/yahoo_no_results.json +10 -0
- data/test/geocoder_test.rb +185 -12
- data/test/test_helper.rb +84 -17
- metadata +51 -17
- data/lib/geocoder/lookup.rb +0 -90
@@ -1,8 +1,16 @@
|
|
1
1
|
module Geocoder
|
2
2
|
class Configuration
|
3
|
-
|
3
|
+
def self.timeout; @@timeout; end
|
4
|
+
def self.timeout=(obj); @@timeout = obj; end
|
5
|
+
|
6
|
+
def self.lookup; @@lookup; end
|
7
|
+
def self.lookup=(obj); @@lookup = obj; end
|
8
|
+
|
9
|
+
def self.yahoo_appid; @@yahoo_appid; end
|
10
|
+
def self.yahoo_appid=(obj); @@yahoo_appid = obj; end
|
4
11
|
end
|
5
12
|
end
|
6
13
|
|
7
|
-
Geocoder::Configuration.timeout
|
8
|
-
|
14
|
+
Geocoder::Configuration.timeout = 3
|
15
|
+
Geocoder::Configuration.lookup = :google
|
16
|
+
Geocoder::Configuration.yahoo_appid = ""
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
unless defined? ActiveSupport::JSON
|
3
|
+
begin
|
4
|
+
require 'json'
|
5
|
+
rescue LoadError
|
6
|
+
raise LoadError, "Please install the json gem to parse geocoder results."
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Geocoder
|
11
|
+
module Lookup
|
12
|
+
class Base
|
13
|
+
|
14
|
+
##
|
15
|
+
# Query the geocoding API and return a Geocoder::Result object.
|
16
|
+
# Returns +nil+ on timeout or error.
|
17
|
+
#
|
18
|
+
# Takes a search string (eg: "Mississippi Coast Coliseumf, Biloxi, MS",
|
19
|
+
# "205.128.54.202") for geocoding, or coordinates (latitude, longitude)
|
20
|
+
# for reverse geocoding.
|
21
|
+
#
|
22
|
+
def search(*args)
|
23
|
+
if res = result(args.join(","), args.size == 2)
|
24
|
+
result_class.new(res)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private # -------------------------------------------------------------
|
30
|
+
|
31
|
+
##
|
32
|
+
# Geocoder::Result object or nil on timeout or other error.
|
33
|
+
#
|
34
|
+
def result(query, reverse = false)
|
35
|
+
fail
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# URL to use for querying the geocoding engine.
|
40
|
+
#
|
41
|
+
def query_url(query, reverse = false)
|
42
|
+
fail
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Class of the result objects
|
47
|
+
#
|
48
|
+
def result_class
|
49
|
+
eval("Geocoder::Result::#{self.class.to_s.split(":").last}")
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Returns a parsed search result (Ruby hash).
|
54
|
+
#
|
55
|
+
def fetch_data(query, reverse = false)
|
56
|
+
begin
|
57
|
+
parse_raw_data fetch_raw_data(query, reverse)
|
58
|
+
rescue SocketError
|
59
|
+
warn "Geocoding API connection cannot be established."
|
60
|
+
rescue TimeoutError
|
61
|
+
warn "Geocoding API not responding fast enough " +
|
62
|
+
"(see Geocoder::Configuration.timeout to set limit)."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Parses a raw search result (returns hash or array).
|
68
|
+
#
|
69
|
+
def parse_raw_data(raw_data)
|
70
|
+
if defined?(JSON) and defined?(JSON.parse)
|
71
|
+
begin
|
72
|
+
JSON.parse(raw_data)
|
73
|
+
rescue
|
74
|
+
warn "Geocoding API's response was not valid JSON."
|
75
|
+
end
|
76
|
+
elsif defined?(ActiveSupport::JSON)
|
77
|
+
ActiveSupport::JSON.decode(raw_data)
|
78
|
+
else
|
79
|
+
raise Geocoder::Error, "No JSON-parsing library found. " +
|
80
|
+
"Please install either the 'json' or 'activesupport' gem."
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Fetches a raw search result (JSON string).
|
86
|
+
#
|
87
|
+
def fetch_raw_data(query, reverse = false)
|
88
|
+
url = query_url(query, reverse)
|
89
|
+
timeout(Geocoder::Configuration.timeout) do
|
90
|
+
Net::HTTP.get_response(URI.parse(url)).body
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Is the given string a loopback IP address?
|
96
|
+
#
|
97
|
+
def loopback_address?(ip)
|
98
|
+
!!(ip == "0.0.0.0" or ip.match(/^127/))
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# Simulate ActiveSupport's Object#to_query.
|
103
|
+
#
|
104
|
+
def hash_to_query(hash)
|
105
|
+
require 'cgi' unless defined?(CGI) && defined?(CGI.escape)
|
106
|
+
hash.collect{ |p| p.map{ |i| CGI.escape i.to_s } * '=' }.sort * '&'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require 'geocoder/results/freegeoip'
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Freegeoip < Base
|
6
|
+
|
7
|
+
private # ---------------------------------------------------------------
|
8
|
+
|
9
|
+
def result(query, reverse = false)
|
10
|
+
# don't look up a loopback address, just return the stored result
|
11
|
+
return reserved_result(query) if loopback_address?(query)
|
12
|
+
begin
|
13
|
+
if doc = fetch_data(query, reverse)
|
14
|
+
doc
|
15
|
+
end
|
16
|
+
rescue StandardError # Freegeoip.net returns HTML on bad request
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def reserved_result(ip)
|
22
|
+
{
|
23
|
+
"ip" => ip,
|
24
|
+
"city" => "",
|
25
|
+
"region_code" => "",
|
26
|
+
"region_name" => "",
|
27
|
+
"metrocode" => "",
|
28
|
+
"zipcode" => "",
|
29
|
+
"latitude" => "0",
|
30
|
+
"longitude" => "0",
|
31
|
+
"country_name" => "Reserved",
|
32
|
+
"country_code" => "RD"
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def query_url(query, reverse = false)
|
37
|
+
"http://freegeoip.net/json/#{query}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/google"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Google < Base
|
6
|
+
|
7
|
+
private # ---------------------------------------------------------------
|
8
|
+
|
9
|
+
def result(query, reverse = false)
|
10
|
+
doc = fetch_data(query, reverse)
|
11
|
+
case doc['status']; when "OK" # OK status implies >0 results
|
12
|
+
doc['results'].first
|
13
|
+
when "OVER_QUERY_LIMIT"
|
14
|
+
warn "Google Geocoding API error: over query limit."
|
15
|
+
when "REQUEST_DENIED"
|
16
|
+
warn "Google Geocoding API error: request denied."
|
17
|
+
when "INVALID_REQUEST"
|
18
|
+
warn "Google Geocoding API error: invalid request."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def query_url(query, reverse = false)
|
23
|
+
params = {
|
24
|
+
(reverse ? :latlng : :address) => query,
|
25
|
+
:sensor => "false"
|
26
|
+
}
|
27
|
+
"http://maps.google.com/maps/api/geocode/json?" + hash_to_query(params)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'geocoder/lookups/base'
|
2
|
+
require "geocoder/results/yahoo"
|
3
|
+
|
4
|
+
module Geocoder::Lookup
|
5
|
+
class Yahoo < Base
|
6
|
+
|
7
|
+
private # ---------------------------------------------------------------
|
8
|
+
|
9
|
+
def result(query, reverse = false)
|
10
|
+
doc = fetch_data(query, reverse)
|
11
|
+
if doc = doc['ResultSet'] and doc['Error'] == 0
|
12
|
+
doc['Results'].first if doc['Found'] > 0
|
13
|
+
else
|
14
|
+
warn "Yahoo Geocoding API error: #{doc['Error']} (#{doc['ErrorMessage']})."
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def query_url(query, reverse = false)
|
19
|
+
params = {
|
20
|
+
:location => query,
|
21
|
+
:flags => "JXTSR",
|
22
|
+
:gflags => "AC#{'R' if reverse}",
|
23
|
+
:appid => Geocoder::Configuration.yahoo_appid
|
24
|
+
}
|
25
|
+
"http://where.yahooapis.com/geocode?" + hash_to_query(params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
@@ -1,8 +1,13 @@
|
|
1
|
+
require 'geocoder/orms/base'
|
2
|
+
require 'geocoder/orms/active_record_legacy'
|
3
|
+
|
1
4
|
##
|
2
5
|
# Add geocoding functionality to any ActiveRecord object.
|
3
6
|
#
|
4
|
-
module Geocoder
|
7
|
+
module Geocoder::Orm
|
5
8
|
module ActiveRecord
|
9
|
+
include Base
|
10
|
+
include ActiveRecord::Legacy
|
6
11
|
|
7
12
|
##
|
8
13
|
# Implementation of 'included' hook method.
|
@@ -28,7 +33,7 @@ module Geocoder
|
|
28
33
|
#
|
29
34
|
scope :near, lambda{ |location, *args|
|
30
35
|
latitude, longitude = location.is_a?(Array) ?
|
31
|
-
location : Geocoder
|
36
|
+
location : Geocoder.coordinates(location)
|
32
37
|
if latitude and longitude
|
33
38
|
near_scope_options(latitude, longitude, *args)
|
34
39
|
else
|
@@ -112,7 +117,7 @@ module Geocoder
|
|
112
117
|
["#{lat_attr} BETWEEN ? AND ? AND #{lon_attr} BETWEEN ? AND ?"] +
|
113
118
|
coordinate_bounds(latitude, longitude, radius)
|
114
119
|
if obj = options[:exclude]
|
115
|
-
conditions[0] << " AND id != ?"
|
120
|
+
conditions[0] << " AND #{table_name}.id != ?"
|
116
121
|
conditions << obj.id
|
117
122
|
end
|
118
123
|
{
|
@@ -142,94 +147,34 @@ module Geocoder
|
|
142
147
|
end
|
143
148
|
|
144
149
|
##
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
def read_coordinates
|
149
|
-
[:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] }
|
150
|
-
end
|
151
|
-
|
152
|
-
##
|
153
|
-
# Is this object geocoded? (Does it have latitude and longitude?)
|
154
|
-
#
|
155
|
-
def geocoded?
|
156
|
-
read_coordinates.compact.size > 0
|
157
|
-
end
|
158
|
-
|
159
|
-
##
|
160
|
-
# Calculate the distance from the object to a point (lat,lon).
|
161
|
-
#
|
162
|
-
# <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt>
|
163
|
-
#
|
164
|
-
def distance_to(lat, lon, units = :mi)
|
165
|
-
return nil unless geocoded?
|
166
|
-
mylat,mylon = read_coordinates
|
167
|
-
Geocoder::Calculations.distance_between(mylat, mylon, lat, lon, :units => units)
|
168
|
-
end
|
169
|
-
|
170
|
-
##
|
171
|
-
# Get other geocoded objects within a given radius.
|
172
|
-
#
|
173
|
-
# <tt>:units</tt> :: <tt>:mi</tt> (default) or <tt>:km</tt>
|
150
|
+
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
|
151
|
+
# (or other as specified in +geocoded_by+). Returns coordinates (array).
|
174
152
|
#
|
175
|
-
def
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
# Fetch coordinates and assign +latitude+ and +longitude+. Also returns
|
183
|
-
# coordinates as an array: <tt>[lat, lon]</tt>.
|
184
|
-
#
|
185
|
-
def fetch_coordinates(save = false)
|
186
|
-
address_method = self.class.geocoder_options[:user_address]
|
187
|
-
unless address_method.is_a? Symbol
|
188
|
-
raise Geocoder::ConfigurationError,
|
189
|
-
"You are attempting to fetch coordinates but have not specified " +
|
190
|
-
"a method which provides an address for the object."
|
191
|
-
end
|
192
|
-
coords = Geocoder::Lookup.coordinates(send(address_method))
|
193
|
-
unless coords.blank?
|
194
|
-
method = (save ? "update" : "write") + "_attribute"
|
195
|
-
send method, self.class.geocoder_options[:latitude], coords[0]
|
196
|
-
send method, self.class.geocoder_options[:longitude], coords[1]
|
153
|
+
def geocode
|
154
|
+
do_lookup(false) do |o,r|
|
155
|
+
unless r.latitude.nil? or r.longitude.nil?
|
156
|
+
o.send :write_attribute, self.class.geocoder_options[:latitude], r.latitude
|
157
|
+
o.send :write_attribute, self.class.geocoder_options[:longitude], r.longitude
|
158
|
+
end
|
159
|
+
r.coordinates
|
197
160
|
end
|
198
|
-
coords
|
199
161
|
end
|
200
162
|
|
201
|
-
|
202
|
-
# Fetch coordinates and update (save) +latitude+ and +longitude+ data.
|
203
|
-
#
|
204
|
-
def fetch_coordinates!
|
205
|
-
fetch_coordinates(true)
|
206
|
-
end
|
163
|
+
#alias_method :fetch_coordinates, :geocode
|
207
164
|
|
208
165
|
##
|
209
|
-
#
|
210
|
-
#
|
166
|
+
# Look up address and assign to +address+ attribute (or other as specified
|
167
|
+
# in +reverse_geocoded_by+). Returns address (string).
|
211
168
|
#
|
212
|
-
def
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
"attributes which provide coordinates for the object."
|
219
|
-
end
|
220
|
-
address = Geocoder::Lookup.address(send(lat_attr), send(lon_attr))
|
221
|
-
unless address.blank?
|
222
|
-
method = (save ? "update" : "write") + "_attribute"
|
223
|
-
send method, self.class.geocoder_options[:fetched_address], address
|
169
|
+
def reverse_geocode
|
170
|
+
do_lookup(true) do |o,r|
|
171
|
+
unless r.address.nil?
|
172
|
+
o.send :write_attribute, self.class.geocoder_options[:fetched_address], r.address
|
173
|
+
end
|
174
|
+
r.address
|
224
175
|
end
|
225
|
-
address
|
226
176
|
end
|
227
177
|
|
228
|
-
|
229
|
-
# Fetch address and update (save) +address+ data.
|
230
|
-
#
|
231
|
-
def fetch_address!
|
232
|
-
fetch_address(true)
|
233
|
-
end
|
178
|
+
#alias_method :fetch_address, :reverse_geocode
|
234
179
|
end
|
235
180
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Geocoder::Orm::ActiveRecord
|
2
|
+
module Legacy
|
3
|
+
|
4
|
+
##
|
5
|
+
# Fetch coordinates and update (save) +latitude+ and +longitude+ data.
|
6
|
+
#
|
7
|
+
def fetch_coordinates!
|
8
|
+
warn "DEPRECATION WARNING: The 'fetch_coordinates!' method is deprecated and will be removed in geocoder v1.0. " +
|
9
|
+
"Please use 'geocode' instead and then save your objects manually."
|
10
|
+
do_lookup(false) do |o,r|
|
11
|
+
unless r.latitude.nil? or r.longitude.nil?
|
12
|
+
o.send :update_attribute, self.class.geocoder_options[:latitude], r.latitude
|
13
|
+
o.send :update_attribute, self.class.geocoder_options[:longitude], r.longitude
|
14
|
+
end
|
15
|
+
r.coordinates
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_coordinates(*args)
|
20
|
+
warn "DEPRECATION WARNING: The 'fetch_coordinates' method will cease taking " +
|
21
|
+
"an argument in geocoder v1.0. Please save your objects manually." if args.size > 0
|
22
|
+
do_lookup(false) do |o,r|
|
23
|
+
unless r.latitude.nil? or r.longitude.nil?
|
24
|
+
method = ((args.size > 0 && args.first) ? "update" : "write" ) + "_attribute"
|
25
|
+
o.send method, self.class.geocoder_options[:latitude], r.latitude
|
26
|
+
o.send method, self.class.geocoder_options[:longitude], r.longitude
|
27
|
+
end
|
28
|
+
r.coordinates
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Fetch address and update (save) +address+ data.
|
34
|
+
#
|
35
|
+
def fetch_address!
|
36
|
+
warn "DEPRECATION WARNING: The 'fetch_address!' method is deprecated and will be removed in geocoder v1.0. " +
|
37
|
+
"Please use 'reverse_geocode' instead and then save your objects manually."
|
38
|
+
do_lookup(true) do |o,r|
|
39
|
+
unless r.address.nil?
|
40
|
+
o.send :update_attribute, self.class.geocoder_options[:fetched_address], r.address
|
41
|
+
end
|
42
|
+
r.address
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def fetch_address(*args)
|
47
|
+
warn "DEPRECATION WARNING: The 'fetch_address' method will cease taking " +
|
48
|
+
"an argument in geocoder v1.0. Please save your objects manually." if args.size > 0
|
49
|
+
do_lookup(true) do |o,r|
|
50
|
+
unless r.latitude.nil? or r.longitude.nil?
|
51
|
+
method = ((args.size > 0 && args.first) ? "update" : "write" ) + "_attribute"
|
52
|
+
o.send method, self.class.geocoder_options[:fetched_address], r.address
|
53
|
+
end
|
54
|
+
r.address
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Geocoder
|
2
|
+
module Orm
|
3
|
+
module Base
|
4
|
+
|
5
|
+
##
|
6
|
+
# Is this object geocoded? (Does it have latitude and longitude?)
|
7
|
+
#
|
8
|
+
def geocoded?
|
9
|
+
read_coordinates.compact.size > 0
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Calculate the distance from the object to an arbitrary point.
|
14
|
+
# Takes two floats (latitude, longitude) and a symbol specifying the
|
15
|
+
# units to be used (:mi or :km; default is :mi).
|
16
|
+
#
|
17
|
+
def distance_to(lat, lon, units = :mi)
|
18
|
+
return nil unless geocoded?
|
19
|
+
mylat,mylon = read_coordinates
|
20
|
+
Geocoder::Calculations.distance_between(mylat, mylon, lat, lon, :units => units)
|
21
|
+
end
|
22
|
+
|
23
|
+
alias_method :distance_from, :distance_to
|
24
|
+
|
25
|
+
##
|
26
|
+
# Get nearby geocoded objects. Takes a radius (integer) and a symbol
|
27
|
+
# representing the units of the ratius (:mi or :km; default is :mi).
|
28
|
+
#
|
29
|
+
def nearbys(radius = 20, units = :mi)
|
30
|
+
return [] unless geocoded?
|
31
|
+
options = {:exclude => self, :units => units}
|
32
|
+
self.class.near(read_coordinates, radius, options)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Look up coordinates and assign to +latitude+ and +longitude+ attributes
|
37
|
+
# (or other as specified in +geocoded_by+). Returns coordinates (array).
|
38
|
+
#
|
39
|
+
def geocode
|
40
|
+
fail
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Look up address and assign to +address+ attribute (or other as specified
|
45
|
+
# in +reverse_geocoded_by+). Returns address (string).
|
46
|
+
#
|
47
|
+
def reverse_geocode
|
48
|
+
fail
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
private # --------------------------------------------------------------
|
53
|
+
|
54
|
+
##
|
55
|
+
# Look up geographic data based on object attributes (configured in
|
56
|
+
# geocoded_by or reverse_geocoded_by) and handle the result with the
|
57
|
+
# block (given to geocoded_by or reverse_geocoded_by). The block is
|
58
|
+
# given two-arguments: the object being geocoded and a
|
59
|
+
# Geocoder::Result object with the geocoding results).
|
60
|
+
#
|
61
|
+
def do_lookup(reverse = false)
|
62
|
+
options = self.class.geocoder_options
|
63
|
+
if reverse and options[:reverse_geocode]
|
64
|
+
args = [:latitude, :longitude]
|
65
|
+
elsif !reverse and options[:geocode]
|
66
|
+
args = [:user_address]
|
67
|
+
else
|
68
|
+
return
|
69
|
+
end
|
70
|
+
args.map!{ |a| send(options[a]) }
|
71
|
+
|
72
|
+
if result = Geocoder.search(*args)
|
73
|
+
|
74
|
+
# execute custom block, if specified in configuration
|
75
|
+
block_key = reverse ? :reverse_block : :geocode_block
|
76
|
+
if custom_block = options[block_key]
|
77
|
+
custom_block.call(self, result)
|
78
|
+
|
79
|
+
# else execute block passed directly to this method,
|
80
|
+
# which generally performs the "auto-assigns"
|
81
|
+
elsif block_given?
|
82
|
+
yield(self, result)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Read the coordinates [lat,lon] of the object.
|
89
|
+
# Looks at user config to determine attributes.
|
90
|
+
#
|
91
|
+
def read_coordinates
|
92
|
+
[:latitude, :longitude].map{ |i| send self.class.geocoder_options[i] }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|