diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/address.js | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/address.js b/lib/address.js index 21e14ff6..e7cc053a 100644 --- a/lib/address.js +++ b/lib/address.js @@ -289,6 +289,58 @@ function Address (faker) { "sampleResults": ["Northwest", "Southeast", "SW", "NE"] }; + this.nearbyGPSCoordinate = function(coordinate, radius, isMetric) { + function randomFloat(min, max) { + return Math.random() * (max-min) + min; + } + function degreesToRadians(degrees) { + return degrees * (Math.PI/180.0); + } + function radiansToDegrees(radians) { + return radians * (180.0/Math.PI); + } + function kilometersToMiles(miles) { + return miles * 0.621371; + } + function coordinateWithOffset(coordinate, bearing, distance, isMetric) { + var R = 6378.137; // Radius of the Earth (http://nssdc.gsfc.nasa.gov/planetary/factsheet/earthfact.html) + var d = isMetric ? distance : kilometersToMiles(distance); // Distance in km + + var lat1 = degreesToRadians(coordinate[0]); //Current lat point converted to radians + var lon1 = degreesToRadians(coordinate[1]); //Current long point converted to radians + + var lat2 = Math.asin(Math.sin(lat1) * Math.cos(d/R) + + Math.cos(lat1) * Math.sin(d/R) * Math.cos(bearing)); + + var lon2 = lon1 + Math.atan2( + Math.sin(bearing) * Math.sin(d/R) * Math.cos(lat1), + Math.cos(d/R) - Math.sin(lat1) * Math.sin(lat2)); + + // Keep longitude in range [-180, 180] + if (lon2 > degreesToRadians(180)) { + lon2 = lon2 - degreesToRadians(360); + } else if (lon2 < degreesToRadians(-180)) { + lon2 = lon2 + degreesToRadians(360); + } + + return [radiansToDegrees(lat2), radiansToDegrees(lon2)]; + } + + // If there is no coordinate, the best we can do is return a random GPS coordinate. + if (coordinate === undefined) { + return [this.latitude(), this.longitude()] + } + radius = radius || 10.0; + isMetric = isMetric || false; + + // TODO: implement either a gaussian/uniform distribution of points in cicular region. + // Possibly include param to function that allows user to choose between distributions. + + // This approach will likely result in a higher density of points near the center. + var randomCoord = coordinateWithOffset(coordinate, degreesToRadians(Math.random() * 360.0), radius, isMetric); + return [randomCoord[0].toFixed(4), randomCoord[1].toFixed(4)]; + } + return this; } |
