Skip to content

Instantly share code, notes, and snippets.

@melito
Forked from thbar/haversine.rb
Created January 29, 2011 06:26
Show Gist options
  • Save melito/801601 to your computer and use it in GitHub Desktop.
Save melito/801601 to your computer and use it in GitHub Desktop.
# I cannot credit the original author
class Haversine
#EARTH_RADIUS = 3963.19 # miles
EARTH_RADIUS = 6371 # kilometers
RADIAN_PER_DEGREE = Math::PI / 180.0
def self.distance(lat1, lng1, lat2, lng2)
lat1_radians = lat1 * RADIAN_PER_DEGREE
lat2_radians = lat2 * RADIAN_PER_DEGREE
distance_lat = (lat2-lat1) * RADIAN_PER_DEGREE
distance_lng = (lng2-lng1) * RADIAN_PER_DEGREE
a = Math.sin(distance_lat/2)**2 + Math.cos(lat1_radians) * Math.cos(lat2_radians) * Math.sin(distance_lng/2) ** 2
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
EARTH_RADIUS * c
end
end
require 'haversine'
module LoGeek
module NearbyFinder
# achieve a nearby lookup then sort via the more accurate haversine distance
def self.nearby_search(database,collection_name,lat,lon,num=10,query={})
cmd = BSON::OrderedHash.new
cmd['geoNear'] = collection_name
cmd['near'] = [lat,lon]
cmd['num'] = num
cmd['query'] = query
database.command(cmd)['results'].sort_by do |r|
r['distance'] = Haversine.distance(lat,lon,r['obj']['loc'][0],r['obj']['loc'][1])
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment