Skip to content

Instantly share code, notes, and snippets.

@shwoodard
Created September 15, 2009 15:58
Show Gist options
  • Save shwoodard/187406 to your computer and use it in GitHub Desktop.
Save shwoodard/187406 to your computer and use it in GitHub Desktop.
module ZipCodes
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def find_zip_codes_by_radius(zip, radius)
zip_code = ZipCode.find_by_zip_code(zip)
return [] unless zip_code
radius = radius.to_f
latitude_miles = 69.172
longitude_miles = (latitude_miles * Math.cos(zip_code.latitude * (Math::PI/180))).abs
latitude_degrees = radius/latitude_miles
longitude_degrees = radius/longitude_miles
min_latitude = zip_code.latitude - latitude_degrees
max_latitude = zip_code.latitude + latitude_degrees
min_longitude = zip_code.longitude - longitude_degrees
max_longitude = zip_code.longitude + longitude_degrees
ZipCode.find(:all,
:select => "zip_code, sqrt( pow(#{latitude_miles} * (latitude-#{zip_code.latitude}),2) + pow(#{longitude_miles} * (longitude-#{zip_code.longitude}),2)) as distance",
:conditions => "(latitude BETWEEN #{min_latitude} AND #{max_latitude}) AND (longitude BETWEEN #{min_longitude} AND #{max_longitude}) AND sqrt(pow(#{latitude_miles} * (latitude-#{zip_code.latitude}),2) + pow(#{longitude_miles} * (longitude-#{zip_code.longitude}),2)) <= #{radius}",
:order => "distance").uniq
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment