diff --git a/lib/geomUtils.js b/lib/geomUtils.js index 273b67c..a7795fe 100644 --- a/lib/geomUtils.js +++ b/lib/geomUtils.js @@ -11,6 +11,13 @@ if (!Number.prototype.toRad) { } +if (!Number.prototype.toDeg) { + Number.prototype.toDeg = function() { + return this * 180/ Math.PI; + }; + +} + var greatCircleRadius = { miles: 3956, km: 6367 @@ -22,9 +29,10 @@ var greatCircleRadius = { * @param {number} lon1 The longtitude of the first point. * @param {number} lat2 The latitude of the first point. * @param {number} lon2 The longtitude of the first point. - * @returns {number} The distance in miles between the two points. + * @param {boolean} [inMiles=False] Specifies if result should be in miles. + * @returns {number} The distance in kilometers (or miles) between the two points. **/ -exports.calculateDistance = function(lat1, lon1, lat2, lon2) { +exports.calculateDistance = function(lat1, lon1, lat2, lon2, inMiles) { var dLat = (lat2 - lat1).toRad(), dLon = (lon2 - lon1).toRad(); @@ -34,7 +42,7 @@ exports.calculateDistance = function(lat1, lon1, lat2, lon2) { var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - return greatCircleRadius.km * c; + return (inMiles ? greatCircleRadius.miles : greatCircleRadius.km) * c; }; /** @@ -43,17 +51,18 @@ exports.calculateDistance = function(lat1, lon1, lat2, lon2) { * @param {number} lon1 The longtitude of the first point. * @param {number} lat2 The latitude of the first point. * @param {number} lon2 The longtitude of the first point. + * @returns {Array} An array of latitude and longtitude values of the midpoint. */ exports.calculateMidpoint = function(lat1, lon1, lat2, lon2) { - var dLat = (lat2 - lat1).toRad(), - dLon = (lon2 - lon1).toRad(); - - lat1 = lat1.toRad(); + var dLon = (lon2 - lon1).toRad(); + + lat1 = lat1.toRad(); lat2 = lat2.toRad(); - - var Bx = Math.cos(lat2) * Math.cos(dLon); + + var Bx = Math.cos(lat2) * Math.cos(dLon); var By = Math.cos(lat2) * Math.sin(dLon); - var lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), - Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By)); - var lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx); + var lat3 = (Math.atan2(Math.sin(lat1) + Math.sin(lat2), + Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By))).toDeg(); + var lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx).toDeg(); + return [lat3,lon3]; }; diff --git a/tests/utils-tests.js b/tests/utils-tests.js index 494f45f..78f8a12 100644 --- a/tests/utils-tests.js +++ b/tests/utils-tests.js @@ -11,13 +11,19 @@ module.exports = { }, "Should calculate the distance between two points": function(test) { - var distance = geomUtils.calculateDistance(4.367, 5.6745, -40.4556, 39.34345); - test.equal(distance, 6045.97811789512); + var distanceInKm = geomUtils.calculateDistance(4.367, 5.6745, -40.4556, 39.34345); + var distanceInMiles = geomUtils.calculateDistance(4.367, 5.6745, -40.4556, 39.34345, true); + + test.equal(distanceInKm, 6045.97811789512); + test.equal(distanceInMiles, distanceInKm/1.609453993933266 ); test.done(); }, "Should calculate the midpoint between two points" : function(test) { - geomUtils.calculateMidpoint(4.367, 5.6745, -40.4556, 39.34345); + var midpoint = geomUtils.calculateMidpoint(4.367, 5.6745, -40.4556, 39.34345); + + test.deepEqual(midpoint, [ -18.7821348599706, 20.181135926320035] ); test.done(); } }; +