@@ -53,25 +53,25 @@ def find_near(location, radius = 20, options = {})
53
53
#
54
54
def find_near_options ( latitude , longitude , radius = 20 , options = { } )
55
55
56
- # Set defaults/clean up arguments.
56
+ # set defaults/clean up arguments
57
57
options [ :order ] ||= 'distance ASC'
58
58
radius = radius . to_i
59
59
60
- # Constrain search to a (radius x radius) square.
60
+ # constrain search to a (radius x radius) square
61
61
factor = ( Math ::cos ( latitude * Math ::PI / 180.0 ) * 69.0 ) . abs
62
62
lon_lo = longitude - ( radius / factor ) ;
63
63
lon_hi = longitude + ( radius / factor ) ;
64
64
lat_lo = latitude - ( radius / 69.0 ) ;
65
65
lat_hi = latitude + ( radius / 69.0 ) ;
66
66
67
- # Build limit clause.
67
+ # build limit clause
68
68
limit = nil
69
69
if options [ :limit ] or options [ :offset ]
70
70
options [ :offset ] ||= 0
71
71
limit = "#{ options [ :offset ] } ,#{ options [ :limit ] } "
72
72
end
73
73
74
- # Generate hash.
74
+ # generate hash
75
75
lat_attr = geocoder_options [ :latitude ]
76
76
lon_attr = geocoder_options [ :longitude ]
77
77
{
@@ -156,14 +156,14 @@ def fetch_coordinates!
156
156
def self . fetch_coordinates ( query )
157
157
return nil unless doc = self . search ( query )
158
158
159
- # Make sure search found a result.
159
+ # make sure search found a result
160
160
e = doc . elements [ 'kml/Response/Status/code' ]
161
161
return nil unless ( e and e . text == "200" )
162
162
163
- # Isolate the relevant part of the result.
163
+ # isolate the relevant part of the result
164
164
place = doc . elements [ 'kml/Response/Placemark' ]
165
165
166
- # If there are multiple results, blindly use the first.
166
+ # if there are multiple results, blindly use the first
167
167
coords = place . elements [ 'Point/coordinates' ] . text
168
168
coords . split ( ',' ) [ 0 ...2 ] . reverse . map { |i | i . to_f }
169
169
end
@@ -175,20 +175,23 @@ def self.fetch_coordinates(query)
175
175
# +units+ :: <tt>:mi</tt> for miles (default), <tt>:km</tt> for kilometers
176
176
#
177
177
def self . distance_between ( lat1 , lon1 , lat2 , lon2 , options = { } )
178
+
178
179
# set default options
179
180
options [ :units ] ||= :mi
180
- # define available units
181
+
182
+ # define conversion factors
181
183
units = { :mi => 3956 , :km => 6371 }
182
184
183
185
# convert degrees to radians
184
186
lat1 = to_radians ( lat1 )
185
187
lon1 = to_radians ( lon1 )
186
188
lat2 = to_radians ( lat2 )
187
189
lon2 = to_radians ( lon2 )
190
+
188
191
# compute distances
189
192
dlat = ( lat1 - lat2 ) . abs
190
193
dlon = ( lon1 - lon2 ) . abs
191
-
194
+
192
195
a = ( Math . sin ( dlat / 2 ) ) **2 + Math . cos ( lat1 ) *
193
196
( Math . sin ( dlon / 2 ) ) **2 * Math . cos ( lat2 )
194
197
c = 2 * Math . atan2 ( Math . sqrt ( a ) , Math . sqrt ( 1 -a ) )
@@ -230,3 +233,22 @@ def self.search(query)
230
233
REXML ::Document . new ( doc )
231
234
end
232
235
end
236
+
237
+ ##
238
+ # Add geocoded_by method to ActiveRecord::Base so Geocoder is accessible.
239
+ #
240
+ ActiveRecord ::Base . class_eval do
241
+
242
+ ##
243
+ # Set attribute names and include the Geocoder module.
244
+ #
245
+ def self . geocoded_by ( method_name = :location , options = { } )
246
+ class_inheritable_reader :geocoder_options
247
+ write_inheritable_attribute :geocoder_options , {
248
+ :method_name => method_name ,
249
+ :latitude => options [ :latitude ] || :latitude ,
250
+ :longitude => options [ :longitude ] || :longitude
251
+ }
252
+ include Geocoder
253
+ end
254
+ end
0 commit comments