Skip to content

Commit

Permalink
Move geocoded_by method from init.rb to lib/geocoder.rb.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreisner committed Oct 1, 2009
1 parent 6267b19 commit 2753a11
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
16 changes: 1 addition & 15 deletions init.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1 @@
ActiveRecord::Base.class_eval do

##
# Include the Geocoder module and set attribute names.
#
def self.geocoded_by(method_name = :location, options = {})
class_inheritable_reader :geocoder_options
write_inheritable_attribute :geocoder_options, {
:method_name => method_name,
:latitude => options[:latitude] || :latitude,
:longitude => options[:longitude] || :longitude
}
include Geocoder
end
end
require 'geocoder'
40 changes: 31 additions & 9 deletions lib/geocoder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,25 @@ def find_near(location, radius = 20, options = {})
#
def find_near_options(latitude, longitude, radius = 20, options = {})

# Set defaults/clean up arguments.
# set defaults/clean up arguments
options[:order] ||= 'distance ASC'
radius = radius.to_i

# Constrain search to a (radius x radius) square.
# constrain search to a (radius x radius) square
factor = (Math::cos(latitude * Math::PI / 180.0) * 69.0).abs
lon_lo = longitude - (radius / factor);
lon_hi = longitude + (radius / factor);
lat_lo = latitude - (radius / 69.0);
lat_hi = latitude + (radius / 69.0);

# Build limit clause.
# build limit clause
limit = nil
if options[:limit] or options[:offset]
options[:offset] ||= 0
limit = "#{options[:offset]},#{options[:limit]}"
end

# Generate hash.
# generate hash
lat_attr = geocoder_options[:latitude]
lon_attr = geocoder_options[:longitude]
{
Expand Down Expand Up @@ -156,14 +156,14 @@ def fetch_coordinates!
def self.fetch_coordinates(query)
return nil unless doc = self.search(query)

# Make sure search found a result.
# make sure search found a result
e = doc.elements['kml/Response/Status/code']
return nil unless (e and e.text == "200")

# Isolate the relevant part of the result.
# isolate the relevant part of the result
place = doc.elements['kml/Response/Placemark']

# If there are multiple results, blindly use the first.
# if there are multiple results, blindly use the first
coords = place.elements['Point/coordinates'].text
coords.split(',')[0...2].reverse.map{ |i| i.to_f }
end
Expand All @@ -175,20 +175,23 @@ def self.fetch_coordinates(query)
# +units+ :: <tt>:mi</tt> for miles (default), <tt>:km</tt> for kilometers
#
def self.distance_between(lat1, lon1, lat2, lon2, options = {})

# set default options
options[:units] ||= :mi
# define available units

# define conversion factors
units = { :mi => 3956, :km => 6371 }

# convert degrees to radians
lat1 = to_radians(lat1)
lon1 = to_radians(lon1)
lat2 = to_radians(lat2)
lon2 = to_radians(lon2)

# compute distances
dlat = (lat1 - lat2).abs
dlon = (lon1 - lon2).abs

a = (Math.sin(dlat / 2))**2 + Math.cos(lat1) *
(Math.sin(dlon / 2))**2 * Math.cos(lat2)
c = 2 * Math.atan2( Math.sqrt(a), Math.sqrt(1-a))
Expand Down Expand Up @@ -230,3 +233,22 @@ def self.search(query)
REXML::Document.new(doc)
end
end

##
# Add geocoded_by method to ActiveRecord::Base so Geocoder is accessible.
#
ActiveRecord::Base.class_eval do

##
# Set attribute names and include the Geocoder module.
#
def self.geocoded_by(method_name = :location, options = {})
class_inheritable_reader :geocoder_options
write_inheritable_attribute :geocoder_options, {
:method_name => method_name,
:latitude => options[:latitude] || :latitude,
:longitude => options[:longitude] || :longitude
}
include Geocoder
end
end

0 comments on commit 2753a11

Please sign in to comment.