Skip to content

Instantly share code, notes, and snippets.

@riyadhalnur
Created August 11, 2015 17:08
Show Gist options
  • Save riyadhalnur/2ec76e24bbfec3fe8bcb to your computer and use it in GitHub Desktop.
Save riyadhalnur/2ec76e24bbfec3fe8bcb to your computer and use it in GitHub Desktop.
Generate list of customers within 100km of GPS coordinates 53.3381985, -6.2592576. Program reads the full list of customers and outputs the names and user ids of matching customers (within 100km), sorted by user id (ascending).
var should = require('should');
var Invitations = require('./Invitations');
describe('Customers to invite to office', function () {
var invite;
beforeEach(function () {
invite = new Invitations(53.3381985, -6.2592576);
});
describe('degrees to radians', function () {
it('should throw an error if number is not valid', function () {
should.throws(invite.degreesToRadians('hello'), Error);
});
it('should convert a number in degrees to radians', function () {
var numberInDegrees = 52.986375;
(invite.degreesToRadians(numberInDegrees)).should.be.approximately(0.9247, 0.01);
});
});
describe('distance between two points', function () {
it('should return the distance the reference point and supplied point', function () {
(invite.distanceTo(52.986375, -6.043701)).should.be.approximately(41.676, 0.01);
});
});
describe('read customer list from file', function () {
it('should return a list of customers from a JSON file', function (done) {
invite.readCustomerList('file.json', function (err, data) {
should.not.exist(err);
data.should.be.an.Array;
data[0].name.should.equal('Christina McArdle');
data[0].user_id.should.equal(12);
done();
});
});
});
describe('generate list of customers to invite', function () {
it('should return a list of customers to invite', function (done) {
var testFile = 'file.json';
invite.customerInviteList(testFile, function (err, list) {
should.not.exist(err);
list.should.be.an.Array;
done();
});
});
});
});
var fs = require('fs');
var _ = require('lodash');
var EARTH_RADIUS = 6371.01; // Earth's radius in km
var Invitations = function (baseLat, baseLon) {
this.baseLat = baseLat;
this.baseLon = baseLon;
};
Invitations.prototype.degreesToRadians = function (value) {
if (!_.isNumber(value)) {
throw new Error('Not a valid number');
}
return value * (Math.PI / 180);
};
Invitations.prototype.distanceTo = function (lat, lon) {
var lat1 = this.degreesToRadians(this.baseLat),
lat2 = this.degreesToRadians(lat),
lon1 = this.degreesToRadians(this.baseLon),
lon2 = this.degreesToRadians(lon);
return Math.acos(Math.sin(lat1) * Math.sin(lat2) +
Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2)) * EARTH_RADIUS;
};
Invitations.prototype.readCustomerList = function (list, callback) {
fs.readFile(list, 'utf8', function (err, data) {
if (err) { return callback(err); }
var dataObj = JSON.parse(data);
return callback(null, dataObj);
});
};
Invitations.prototype.customerInviteList = function (file, callback) {
this.readCustomerList(file, function (err, data) {
if (err) { return callback(err); }
var list = _.chain(data)
.sortBy('user_id')
.map(function (obj) {
if (this.distanceTo(obj.latitude, obj.longitude) <= 100) {
return {
user_id: obj.user_id,
name: obj.name
};
}
})
.compact()
.value();
return callback(null, list);
});
};
module.exports = Invitations;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment