benedictify
9/19/2017 - 4:29 AM

find_locals.js

// Spidergap question 2

// Reads list of partners from JSON file, 
// selects names and addresses of company locations that are within 100km radius
// of the center of London (per provided coordinates), 
// outputs those names and addresses, in alphabetical order by company name

const LONDON_CENTER_COORDINATES = [51.515419, -0.141099];

function radiansOf(number) { 
  // convert degrees to radians
  return (number * (Math.PI / 180));
}

const LONDON_LAT = radiansOf(51.515419);
const LONDON_LONG = radiansOf(-0.141099);

const EARTH_RADIUS = 6371; // mean Earth radius in kilometres, per https://en.wikipedia.org/wiki/Earth_radius

const PARTNERS_LIST_SOURCE = ( require("./partners") );

function getLocalPartners(partnersObjArr) {
  var localPartners = [];

  for(var i = 0; i < partnersObjArr.length; i++) {
    var companyName = partnersObjArr[i]["organization"];

    for(var j = 0; j < partnersObjArr[i]["offices"].length; j++) {
      var office = partnersObjArr[i]["offices"][j];

      var coords = office["coordinates"];
      var lat = latOf(coords);
      var long = longOf(coords);

      if (isWithinRange(lat, long)) {
        localPartners.push({"organization": companyName, "address": office["address"]});
      }
    }
  }

  return localPartners;
}

function isWithinRange(lat, long, range = 100) {
  return distanceFromLondonCenter(lat, long) <= range;
} 

function distanceFromLondonCenter(latDeg, longDeg) {
  // computes the distance from our London Center coordinates
  var latRad = radiansOf(latDeg);
  var longRad = radiansOf(longDeg);

  return EARTH_RADIUS * angularDistance(latRad, longRad, LONDON_LAT, LONDON_LONG);
}

function angularDistance(lat1, long1, lat2, long2) {
  return Math.acos( ( Math.sin(lat1) * Math.sin(lat2) ) + 
    ( Math.cos(lat1) * Math.cos(lat2) * Math.cos(long1 - long2) ) );
}

function latOf(coordinates) {
  // takes coordinates string and returns latitude value in degrees as a number

  return parseFloat(coordinates.split(',')[0]);
}

function longOf(coordinates) {
  // takes coordinates string and returns longitude value in degrees as a number

  return parseFloat(coordinates.split(',')[1]);
}

function sortListByCompany(listArray) {
  return listArray.sort(function (a, b){
    return a["organization"] - b["organization"];
  });
}

function findLocals(partnersArray) {
  // which partners are local (within 100km)
  var localsNamesAddressesArray = getLocalPartners(partnersArray); 

  // sort the list by company name
  var sortedNamesAddressesArray = sortListByCompany(localsNamesAddressesArray);

  // return the sorted list
  return sortedNamesAddressesArray; 
}

console.log(findLocals(PARTNERS_LIST_SOURCE));