Skip to content

Instantly share code, notes, and snippets.

@koonuf
Created January 6, 2016 21:20
Show Gist options
  • Save koonuf/fb60617ad603df37934d to your computer and use it in GitHub Desktop.
Save koonuf/fb60617ad603df37934d to your computer and use it in GitHub Desktop.
var kmPerDegree = 110; // approximate distance in km per latitude degree and longitude degree on equator
var roundingMask = Math.pow(10, 6); // rounding coordinates to 6 digits after decimal point
export interface ICoordinates {
lon: number;
lat: number;
}
export function toRadians(degrees: number): number {
return (degrees / 180) * Math.PI;
}
// returns a random point anywhere around source point, but not further away than maxDistanceKm
// both input and output points are expressed as latitude/longitude in degrees
export function getRandomPointAround(sourcePoint: ICoordinates, maxDistanceKm: number): ICoordinates {
if (!sourcePoint || !sourcePoint.lat || !sourcePoint.lon) {
return undefined;
}
maxDistanceKm = maxDistanceKm || 1;
var degreeVariationLat = maxDistanceKm / kmPerDegree;
// distance per longitude degree depends on how far away we are from equator (source point latitude)
// the futher away we are, the shorter longitude "rings" become, so less distance per degree
// Math.cos determines this ratio
var degreeVariationLon = degreeVariationLat * Math.cos(toRadians(sourcePoint.lat));
// random from -1 to +1
var randomLat = (Math.random() - 0.5) * 2;
var randomLon = (Math.random() - 0.5) * 2;
var lat = sourcePoint.lat + (degreeVariationLat * randomLat);
var lon = sourcePoint.lon + (degreeVariationLon * randomLon);
lat = lat % 90; // latitude has -90 to +90 degree range
lon = lon % 180; // longitude has -180 to +180 degree range
return {
lon: Math.round(lon * roundingMask) / roundingMask,
lat: Math.round(lat * roundingMask) / roundingMask
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment