davglass / zipcodes

Zipcode lookup node module
Other
157 stars 83 forks source link

distance(10036, 10036) returns NaN #40

Open MariaEbling opened 5 years ago

MariaEbling commented 5 years ago

The problem is that the intermediate distance calculation returns a value outside the valid range for acos so acos returns NaN. Attached please find code that shows the NaN result from zipcodes.distance as well as a suggested fix.

var zipcodes = require('zipcodes');

// No change to this method
var deg2rad = function(value) {
    return value * 0.017453292519943295;
};

var dist = function(zipA, zipB) {
    zipA = zipcodes.lookup(zipA);
    zipB = zipcodes.lookup(zipB);
    if (!zipA || !zipB) {
        return null;
    }

    var zipALatitudeRadians = deg2rad(zipA.latitude);
    var zipBLatitudeRadians = deg2rad(zipB.latitude);

    var distance = Math.sin(zipALatitudeRadians)
                * Math.sin(zipBLatitudeRadians)
                + Math.cos(zipALatitudeRadians)
                * Math.cos(zipBLatitudeRadians)
                * Math.cos(deg2rad(zipA.longitude - zipB.longitude));

// BEGIN CHANGES
    console.log("  Distance inside dist function: " + distance);

    /*
     * The valid range for Math.acos is -1 <= x <= 1
     *
     * In the event that the distance calculation above results in small errors that take the distance
     * value outside the valid range of Math.acos, we need to bring it back within the valid range
     * of -1 to 1. Otherwise, Math.acos returns NaN.
     */
    if (distance > 1) {
        distance = 1;
    } else if (distance < -1) {
        distance = -1;
    }
// END CHANGES

    distance = Math.acos(distance) * 3958.56540656;
    return Math.round(distance);
};

console.log("Original zipcodes distance function:")
console.log("  Distance calculated by zipcodes package = " + zipcodes.distance(10036, 10036));
console.log("  Distance calculated by zipcodes package = " + zipcodes.distance(12518, 12518) + "\n");

console.log("Revised zipcodes distance function:");
console.log("  Distance calculated by revised dist function in this file = " + dist(10036, 10036));
console.log("  Distance calculated by revised dist function in this file = " + dist(12518, 12518));

When run, this code produces the following output:

$ node testZipcodeDistance.js 
Original zipcodes distance function:
  Distance calculated by zipcodes package = NaN
  Distance calculated by zipcodes package = 0

Revised zipcodes distance function:
  Distance inside dist function: 1.0000000000000002
  Distance calculated by revised dist function in this file = 0
  Distance inside dist function: 0.9999999999999999
  Distance calculated by revised dist function in this file = 0