Last active
August 29, 2015 14:04
-
-
Save tkh44/969105d7358072bbe818 to your computer and use it in GitHub Desktop.
Angular service for working with geoLocations using ngCordova
This file contains 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 characters
((angular, window) => { | |
/** | |
* GeoLocation Utility Service | |
* @param $localStorage | |
* @param $cordovaGeolocation | |
* @param $q | |
* @returns {{getCachedGeoLocation: getCachedGeoLocation, getDistance: getDistance}} | |
* @constructor | |
*/ | |
var GeoService = function($localStorage, $cordovaGeolocation, $q) { | |
var $storage = $localStorage, | |
cachedLocation = $storage.currentLocation, | |
isUS = navigator.language.match(/us/ig); | |
var isLocationExpired = () => | |
angular.isUndefined(cachedLocation) | |
|| cachedLocation.error | |
|| cachedLocation.lookupTime - +new Date() > 3E5; | |
/** | |
* Return the distance in miles if `navigator.language` is 'en-US' otherwise | |
* returns distance in kilometers | |
* | |
* @param {number} distance | |
* @returns {string} distance in either miles or km | |
*/ | |
var getLocaleDistance = (distance) => | |
isUS ? (distance / 1.609344).toFixed(1) + ' mi' : distance.toFixed(1) + ' km'; | |
/** | |
* Calculates the distance between two latitude-longitude points | |
* | |
* Taken from {@link http://stackoverflow.com/a/7179026} | |
* @param {number} lat1 | |
* @param {number} lon1 | |
* @param {number} lat2 | |
* @param {number} lon2 | |
* @returns {number} | |
*/ | |
var computeDistanceBetween = (lat1, lon1, lat2, lon2) => { | |
var toRad = (val) => val * Math.PI / 180; | |
var R = 6371 | 0, // Radius of the earth 6371 km | |
dLat = toRad(lat2 - lat1), | |
dLon = toRad(lon2 - lon1); | |
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); | |
var c = 2 * Math.atan(Math.sqrt(a), Math.sqrt(1 - a)); | |
return R * c; | |
}; | |
this.getCachedGeoLocation = function() { | |
var deferred = $q.defer(); | |
// Was the last lookup more than 5 min ago. | |
if (!isLocationExpired()) { | |
return $q.when(cachedLocation); | |
} else { | |
$cordovaGeolocation.getCurrentPosition().then((position) => { | |
console.log(position.timestamp); | |
var currentPosition = { | |
'latitude': position.coords.latitude, | |
'longitude': position.coords.longitude, | |
'accuracy': position.coords.accuracy , | |
'lookupTime': +new Date() | |
}; | |
$storage.currentLocation = currentPosition; | |
deferred.resolve(currentPosition); | |
}, (err) => { | |
cachedLocation['error'] = err; | |
deferred.reject(err) | |
}); | |
} | |
return deferred.promise; | |
}; | |
/** | |
* Get the distance of the building from the cached geolocation of user | |
* | |
* @param {number} latitude | |
* @param {number} longitude | |
* @returns {string} prettyDistance | |
*/ | |
this.getDistance = function(latitude, longitude) { | |
return getLocaleDistance(computeDistanceBetween(cachedLocation.latitude, cachedLocation.longitude, latitude, longitude)); | |
} | |
}; | |
angular.module('iOffice.geo', ['ngCordova']).service('GeoService', GeoService); | |
})(angular, window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment