Skip to content

Instantly share code, notes, and snippets.

@tagliala
Created January 6, 2013 15:06
Show Gist options
  • Save tagliala/4467820 to your computer and use it in GitHub Desktop.
Save tagliala/4467820 to your computer and use it in GitHub Desktop.
Random location near source
def random_close_location(max_dist = 0.5, km = true)
# http://www.geomidpoint.com/random/calculation.html
return unless source && source[:lat] != nil && source[:lng] != nil
deg_to_rad = Math::PI / 180
rad_to_deg = 180 / Math::PI
radius_earth_M = 3960.056052
radius_earth_Km = 6372.796924
rand1 = rand
rand2 = rand
# Convert all latitudes and longitudes to radians
start_lat = source[:lat] * deg_to_rad
start_lng = source[:lng] * deg_to_rad
# Convert maximum distance to radians.
max_dist_rad = max_dist / (km ? radius_earth_Km : radius_earth_M)
# Compute a random distance from 0 to maxdist scaled
# so that points on larger circles have a greater probability
# of being chosen than points on smaller circles as described earlier.
dist = Math::acos( rand1 * (Math::cos(max_dist_rad) - 1) + 1 )
# Compute a random bearing from 0 to 2*PI radians (0 to 360 degrees),
# with all bearings having an equal probability of being chosen.
brg = 2 * Math::PI * rand2
# Use the starting point, random distance and random bearing to calculate the coordinates of the final random point.
lat = Math::asin( Math::sin(start_lat) * Math::cos(dist) + Math::cos(start_lat) * Math::sin(dist) * Math::cos(brg) )
lng = start_lng + Math::atan2( Math::sin(brg) * Math::sin(dist) * Math::cos(start_lat), Math::cos(dist) - Math::sin(start_lat) * Math.sin(lat) )
if (lng < -1 * Math::PI)
lng = lng + 2 * Math::PI
elsif (lng > Math::PI)
lng = lng - 2 * Math::PI
end
[lat * rad_to_deg, lng * rad_to_deg]
end
@tagliala
Copy link
Author

tagliala commented Jan 6, 2013

TODO: pass source as argument

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment