Skip to content

Instantly share code, notes, and snippets.

@nbering
Forked from Wsiegenthaler/geocoder-service.js
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nbering/2bbba86bfc8de42900b9 to your computer and use it in GitHub Desktop.
Save nbering/2bbba86bfc8de42900b9 to your computer and use it in GitHub Desktop.
/******************
* Code originally written by Ben Jacobs (benmj)
* Modified by Weston Siegenthaler (Wsiengenthaler) and Nicholas Bering (Balrog30)
* Of GitHub Community.
******************/
/*global angular: true, google: true, _ : true */
'use strict';
angular.module('geocoder', ['uiGmapgoogle-maps']).factory('geocoderPromise', ['$q', '$timeout', 'uiGmapGoogleMapApi', function ($q, $timeout, GoogleMapApi) {
var deferredService = $q.defer();
var locations = {};
var queue = [];
// Amount of time (in milliseconds) to pause between each trip to the
// Geocoding API, which places limits on frequency.
var queryPause = 250;
/**
* executeNext() - execute the next function in the queue.
* If a result is returned, fulfill the promise.
* If we get an error, reject the promise (with message).
* If we receive OVER_QUERY_LIMIT, increase interval and try again.
*/
var executeNext = function () {
var task = queue[0],
geocoder = new google.maps.Geocoder();
geocoder.geocode({ address: task.address }, function (result, status) {
if (status === google.maps.GeocoderStatus.OK) {
queue.shift();
locations[task.address] = result;
task.d.resolve(result);
if (queue.length) {
$timeout(executeNext, queryPause);
}
} else if (status === google.maps.GeocoderStatus.ZERO_RESULTS) {
queue.shift();
task.d.reject({
type: 'zero',
message: 'Zero results for geocoding address ' + task.address
});
} else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
queryPause += 250;
$timeout(executeNext, queryPause);
} else if (status === google.maps.GeocoderStatus.REQUEST_DENIED) {
queue.shift();
task.d.reject({
type: 'denied',
message: 'Request denied for geocoding address ' + task.address
});
} else if (status === google.maps.GeocoderStatus.INVALID_REQUEST) {
queue.shift();
task.d.reject({
type: 'invalid',
message: 'Invalid request for geocoding address ' + task.address
});
}
});
};
GoogleMapApi.then(function () {
deferredService.resolve({
geocode: function (address) {
var d = $q.defer();
if (_.has(locations, address)) {
$timeout(function () {
d.resolve(locations[address]);
});
} else {
queue.push({
address: address,
d: d
});
if (queue.length === 1) {
executeNext();
}
}
return d.promise;
}
});
});
return deferredService.promise;
}]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment