I'm using the following function to generate random geo coordinates within a specified radius from a seed point:
function randomGeo(center, radius) {
var y0 = center.latitude;
var x0 = center.longitude;
var rd = radius / 111300;
var u = Math.random();
var v = Math.random();
var w = rd * Math.sqrt(u);
var t = 2 * Math.PI * v;
var x = w * Math.cos(t);
var y = w * Math.sin(t);
var xp = x / Math.cos(y0);
return {
'latitude': y + y0,
'longitude': xp + x0
};
}
I do this in a loop, several times, using a 2000m radius and the following seed point:
location: { // Oxford
latitude: 51.73213,
longitude: -1.20631
}
I'd expect all of these results to be within 2000m; instead, I'm seeing values upwards of 10000m:
[ { latitude: 51.73256540025445, longitude: -1.3358092771716716 }, // 3838.75070783092
{ latitude: 51.7214165686511, longitude: -1.1644147572878725 }, // 3652.1890457730474
{ latitude: 51.71721400063117, longitude: -1.2082082568884593 }, // 8196.861603477768
{ latitude: 51.73583824510363, longitude: -1.0940424351649711 }, // 5104.820455873758
{ latitude: 51.74017571473442, longitude: -1.3150742602532257 }, // 4112.3279147866215
{ latitude: 51.73496163915278, longitude: -1.0379454413532996 }, // 9920.01459343298
{ latitude: 51.73582333121239, longitude: -1.0939302282840453 }, // 11652.160906253064
{ latitude: 51.72145745285658, longitude: -1.2491630482776055 }, // 7599.550622138115
{ latitude: 51.73036335927129, longitude: -1.3516902043395063 }, // 8348.276271205428
{ latitude: 51.748104753808924, longitude: -1.2669212014250266 }, // 8880.760669882042
{ latitude: 51.72010719621805, longitude: -1.327161328951446 }, // 8182.466715589904
{ latitude: 51.725727610071125, longitude: -1.0691503599266818 } ] // 2026.3687763449955
Given that I (shamelessly!) plagiarized this solution from elsewhere (albeit I've seen several similar implementations), I can't seem to figure out where the math is going wrong.
(Also, in case you want it, this is how I'm calculating the distance. Pretty sure this is correct.)
function distance(lat1, lon1, lat2, lon2) {
var R = 6371000;
var a = 0.5 - Math.cos((lat2 - lat1) * Math.PI / 180) / 2 + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * (1 - Math.cos((lon2 - lon1) * Math.PI / 180)) / 2;
return R * 2 * Math.asin(Math.sqrt(a));
}