UNPKG

geoip_from_cities

Version:

Find the lattitude and longitude from a locally cached cities.json as opposed to google geoip which has limits of 2500 requests per day.

110 lines (82 loc) 3.23 kB
/*! geoip_from_cities 2.2.0 (b884907) | https://gitlab.com/rioadvancement/geoip_from_cities */ var geoip_from_cities = (function () { 'use strict'; // Copyright 2018 Rio Advancement Inc const R = require('ramda'); const cities = require('cities.json'); const _fromCity = city => { return city.name + ", " + city.country; }; const _fromString = (city, country) => { return city + ", " + country; }; // Group function that groups the cities json by the format as below // 'City name, Country' : [{ its lattitue data }] // const byCityWithCountry = R.groupBy(function(city){ return _fromCity(city) }); // Apply the byCityWithCountry groupBy function with the cities data // The locations has the transformed data. // Examples // 'Delhi, IN': [{"country":"IN","name":"New Delhi","lat":"28.63576","lng":"77.22445"}] // const locations = byCityWithCountry(cities); // Only store the keys of the locations // const locationKeys = R.keys(locations); // A scoped cached, that stored the cached results. let cachedLocations = {}; class RioGeo { constructor () { } // Given a city and country name, return // multiple cities + countries combo found. // This is an opinionated function for Rio. // This works in the way that when an user types // "NEW" + US => The multiple cities starting with NEW + US // must be sent back. locateCity(city, country) { const uCity = city.toUpperCase(); const uCountry = country.toUpperCase(); const isLike = n => { const uN = n.toUpperCase(); let regex = new RegExp( '.*, '+uCountry, 'g' ); let res = uN.match(regex); return res != null && res.length > 0 && uN.indexOf(uCity) >=0 }; const composeFn = R.compose(R.filter(isLike)); return composeFn(locationKeys) } // Exported search function that does the following // When provided a city and a country name // Tries to get the latitude/longitude from the cache, // If not does a live search from the cities file fillWithGeoInfo(city, country, force=false) { let found = cachedLocations[_fromString(city, country)]; if (!found || force) { found = this._searchLive(city, country); cachedLocations[_fromString(city,country)] = found; } return found } // Does the following computations // 1. Filters the locationKey which is "city, country" from the locationsKey // 2. If multiple are found then takes the first // 3. Expands the locationKey to a location by finding it in the locations // object // 4. Flattens as the output from the above step is an [[]] // 5. If there are multiple matches, sorts the unique, usually the first one // is returned. _searchLive(city, country) { const isLike = n => { return n.indexOf(country) > 0 && n.indexOf(city) >=0 }; const expLocation = x => locations[x]; const countryEq = (a, b) => R.eqBy(e => a.country == b.country ); const composeFn = R.compose(R.uniqWith(countryEq), R.flatten , R.map(expLocation) , R.take(1), R.filter(isLike)); return composeFn(locationKeys) } } return RioGeo; }()); //# sourceMappingURL=bundle.js.map