I need to generate a spec for my search engine to test that results away from my source are not included in results, while radius within the given radius in kilometers are included.
Whatever the origin I am given, I want to test two "extreme" cases where I create two test data points,
- one within: on the exact radius minus an epsilon (radius - e away from the origin)
- one outside: on the exact radius plus an epsilon (radius + e away from origin)
For instance if my radius is 10km, I'd like to generate a point 10.1km away and 9.9 km away from the source.
I am checking the code actually works with Geocoder.distance_between
before do
# Ensure our example is correct
expect(
Geocoder::Calculations.distance_between(origin, point_outside_radius_of_origin)
).to be > radius_in_km
expect(
Geocoder::Calculations.distance_between(origin, point_within_radius_of_origin)
).to be < radius_in_km
end
For instance the following fixed example passes
Using a fixed example of Paris
let(:origin) { [48.856614, 2.3522219] } # Geocoder.coordinates('Paris')
let(:radius_in_km) { 10 }
let(:point_within_radius_of_origin) { [48.801148, 2.429443] } # Geocoder.coordinates('Maisons-Alfort')
let(:point_outside_radius_of_origin) { [48.790367, 2.455572] } # Geocoder.coordinates('Créteil')
I'm struggling to write code to generate such random points. From https://stackoverflow.com/a/43202522/2832282 I was somehow able to generate a point within the given radius :
# Thanks to https://stackoverflow.com/a/43202522/2832282
#
# @param lon [Float]
# @param lat [Float]
# @param max_radius [FLoat] in km
#
# @return [Pair<Float>] [Lng, lat]
def random_point_within_radius_of_origin(lng:, lat:, max_radius:)
dx, dy = Utility.random_point_in_disk(max_radius)
random_lat = lat + dy / OneDegree
random_lng = lng + dx / ( OneDegree * Math::cos(lat * Math::PI / 180) )
[random_lng, random_lat]
end
# @param max_radius [Float] Distance in km
#
# @return [Pair<Float>]
def random_point_in_disk(max_radius)
r = max_radius * rand**0.5
theta = rand * 2 * Math::PI
[r * Math.cos(theta), r * Math.sin(theta)]
end
I need some equivalent code to generate a random point outside the radius from the origin (I don't really care whether uniformly distributed or not) outside the given disk. I guess I could generate a fake point and retry until I hit the goal off.
And I don't believe the earth is flat, so if I take a point at the Poles, well the shape of Earth should be taken into account.
Aucun commentaire:
Enregistrer un commentaire