Created
March 26, 2019 22:54
Revisions
-
bmcminn created this gist
Mar 26, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,127 @@ const ZIPCODES = require('./zipcodes.js') const sqlite = require('sqlite') const Promise = require('bluebird') // http://www.zipcodeapi.com/API /** * Calculates distance between two ZIPCODES * @sauce: https://www.movable-type.co.uk/scripts/latlong.html * @param {object} zip1 Object containing zip, lat, lng * @param {object} zip2 Object containing zip, lat, lng * @param {integer} PRECISION Flag to return the result in kilometers or miles * @return {double} A double representing the distance between the two points */ function zipDistance(zip1, zip2, PRECISION=3) { const R = 6371 // const R = 6371e3 // meters // const M = R / 1.609 const φ1 = degressToRadians(zip1.lat) const φ2 = degressToRadians(zip2.lat) const Δφ = degressToRadians((zip2.lat-zip1.lat)) const Δλ = degressToRadians((zip2.lng-zip1.lng)) let a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2) let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) return (R * c).toFixed(PRECISION) } /** * Calculate the lat and lng ranges for a given "radius" * @param {[type]} zip1 [description] * @param {[type]} radius [description] * @return {[type]} [description] */ function getZipRadius(zip1, radius) { let DIST = 0.01035 * radius return { latMin: zip1.lat - DIST, latMax: zip1.lat + DIST, lngMin: zip1.lng - DIST, lngMax: zip1.lng + DIST, } } /** * [degressToRadians description] * @param {[type]} degrees [description] * @return {[type]} [description] */ function degressToRadians(degrees) { return degrees * (Math.PI/180) } /** * Converts Km to miles * @param {float} km distance in kilometers * @return {double} miles distance in miles */ function kmToMiles(km, PRECISION=3) { return (km / 1.609).toFixed(PRECISION) } /** * [getZipsInRadius description] * @param {[type]} zip [description] * @param {[type]} zips [description] * @param {[type]} radius [description] * @return {[type]} [description] */ function getZipsInRadius(zip, zips, radius) { const RADIUS = getZipRadius(zip, radius) return zips.filter(el => { if (RADIUS.latMin <= el.lat && el.lat <= RADIUS.latMax && RADIUS.lngMin <= el.lng && el.lng <= RADIUS.lngMax ) { let distance = zipDistance(zip, el) if (distance <= radius) { return el } } }) } // const TARGET = ZIPCODES[0] const RADIUS = 100 const TARGET = { lat: 30.3, lng: -97.6, zip_code: '???', } // let res = getZipsInRadius(TARGET, ZIPCODES, RADIUS) // res.map(el => { // console.log(`distance from ${TARGET.zip_code} to ${el.zip_code} is`, kmToMiles(zipDistance(TARGET, el)), 'miles') // }) getZipsInRadius(TARGET, ZIPCODES, RADIUS) .map(el => { console.log(`distance from ${TARGET.zip_code} to ${el.zip_code} is`, kmToMiles(zipDistance(TARGET, el)), 'miles') })