src/providers/api.service.js
module.exports = HereMapsAPIService;
HereMapsAPIService.$inject = [
'$q',
'$http',
'HereMapsConfig',
'HereMapsUtilsService',
'HereMapsCONSTS'
];
function HereMapsAPIService($q, $http, HereMapsConfig, HereMapsUtilsService, HereMapsCONSTS) {
var version = HereMapsConfig.apiVersion,
protocol = HereMapsConfig.useHTTPS ? 'https' : 'http';
var API_VERSION = {
V: parseInt(version),
SUB: version
};
var CONFIG = {
BASE: "://js.api.here.com/v",
CORE: "mapsjs-core.js",
SERVICE: "mapsjs-service.js",
UI: {
src: "mapsjs-ui.js",
href: "mapsjs-ui.css"
},
EVENTS: "mapsjs-mapevents.js",
AUTOCOMPLETE_URL: "://autocomplete.geocoder.cit.api.here.com/6.2/suggest.json",
LOCATION_URL: "://geocoder.cit.api.here.com/6.2/geocode.json"
};
var API_DEFERSQueue = {};
API_DEFERSQueue[CONFIG.CORE] = [];
API_DEFERSQueue[CONFIG.SERVICE] = [];
API_DEFERSQueue[CONFIG.UI.src] = [];
API_DEFERSQueue[CONFIG.PANO] = [];
API_DEFERSQueue[CONFIG.EVENTS] = [];
var head = document.getElementsByTagName('head')[0];
return {
loadApi: loadApi,
loadModules: loadModules,
getPosition: getPosition,
geocodePosition: geocodePosition,
geocodeAddress: geocodeAddress,
geocodeAutocomplete: geocodeAutocomplete,
findLocationById: findLocationById
};
//#region PUBLIC
function loadApi() {
return _getLoader(CONFIG.CORE)
.then(function () {
return _getLoader(CONFIG.SERVICE);
});
}
function loadModules(attrs, handlers) {
for (var key in handlers) {
if (!handlers.hasOwnProperty(key) || !attrs[key])
continue;
var loader = _getLoaderByAttr(key);
loader()
.then(handlers[key]);
}
}
function getPosition(options) {
var deferred = $q.defer();
if (options && HereMapsUtilsService.isValidCoords(options.coords)) {
deferred.resolve({ coords: options.coords });
} else {
navigator.geolocation.getCurrentPosition(function (response) {
deferred.resolve(response);
}, function (error) {
deferred.reject(error);
}, options);
}
return deferred.promise;
}
function geocodePosition(platform, params) {
if (!params.coords)
return console.error('Missed required coords');
var geocoder = platform.getGeocodingService(),
deferred = $q.defer(),
_params = {
prox: [params.coords.lat, params.coords.lng, params.radius || 250].join(','),
mode: 'retrieveAddresses',
maxresults: '1',
gen: '8',
language: params.lang || 'en-gb'
};
geocoder.reverseGeocode(_params, function (response) {
deferred.resolve(response)
}, function (error) {
deferred.reject(error)
});
return deferred.promise;
}
function geocodeAddress(platform, params) {
if (!params)
return console.error('Missed required parameters');
var geocoder = platform.getGeocodingService(),
deferred = $q.defer(),
_params = { gen: 8 };
for (var key in params) { _params[key] = params[key]; }
geocoder.geocode(_params, function (response) {
deferred.resolve(response)
}, function (error) {
deferred.reject(error)
});
return deferred.promise;
}
function geocodeAutocomplete(params) {
if (!params)
return console.error('Missing required parameters');
var autocompleteUrl = protocol + CONFIG.AUTOCOMPLETE_URL,
deferred = $q.defer(),
_params = {
query: "",
beginHighlight: "<mark>",
endHighlight: "</mark>",
maxresults: "5"
};
for (var key in _params) {
if (angular.isDefined(params[key])) {
_params[key] = params[key];
}
}
_params.app_id = HereMapsConfig.app_id;
_params.app_code = HereMapsConfig.app_code;
$http.get(autocompleteUrl, { params: _params })
.success(function(response) {
deferred.resolve(response);
})
.error(function(error) {
deferred.reject(error);
});
return deferred.promise;
}
/**
* Finds location by HERE Maps Location identifier.
*/
function findLocationById(locationId) {
if (!locationId)
return console.error('Missing Location Identifier');
var locationUrl = protocol + CONFIG.LOCATION_URL,
deferred = $q.defer(),
_params = {
locationid: locationId,
gen: 9,
app_id: HereMapsConfig.app_id,
app_code: HereMapsConfig.app_code
};
$http.get(locationUrl, { params: _params })
.success(function(response) {
deferred.resolve(response);
})
.error(function(error) {
deferred.reject(error);
});
return deferred.promise;
}
//#endregion PUBLIC
function _getLoaderByAttr(attr) {
var loader;
switch (attr) {
case HereMapsCONSTS.MODULES.UI:
loader = _loadUIModule;
break;
case HereMapsCONSTS.MODULES.EVENTS:
loader = _loadEventsModule;
break;
default:
throw new Error('Unknown module', attr);
}
return loader;
}
function _loadUIModule() {
if (!_isLoaded(CONFIG.UI.src)) {
var link = HereMapsUtilsService.createLinkTag({
rel: 'stylesheet',
type: 'text/css',
href: _getURL(CONFIG.UI.href)
});
link && head.appendChild(link);
}
return _getLoader(CONFIG.UI.src);
}
function _loadEventsModule() {
return _getLoader(CONFIG.EVENTS);
}
/**
* @param {String} sourceName
* return {String} e.g http://js.api.here.com/v{VER}/{SUBVERSION}/{SOURCE}
*/
function _getURL(sourceName) {
return [
protocol,
CONFIG.BASE,
API_VERSION.V,
"/",
API_VERSION.SUB,
"/",
sourceName
].join("");
}
function _getLoader(sourceName) {
var defer = $q.defer(), src, script;
if (_isLoaded(sourceName)) {
defer.resolve();
} else {
src = _getURL(sourceName);
script = HereMapsUtilsService.createScriptTag({ src: src });
script && head.appendChild(script);
API_DEFERSQueue[sourceName].push(defer);
script.onload = _onLoad.bind(null, sourceName);
script.onerror = _onError.bind(null, sourceName);
}
return defer.promise;
}
function _isLoaded(sourceName) {
var checker = null;
switch (sourceName) {
case CONFIG.CORE:
checker = _isCoreLoaded;
break;
case CONFIG.SERVICE:
checker = _isServiceLoaded;
break;
case CONFIG.UI.src:
checker = _isUILoaded;
break;
case CONFIG.EVENTS:
checker = _isEventsLoaded;
break;
default:
checker = function () { return false };
}
return checker();
}
function _isCoreLoaded() {
return !!window.H;
}
function _isServiceLoaded() {
return !!(window.H && window.H.service);
}
function _isUILoaded() {
return !!(window.H && window.H.ui);
}
function _isEventsLoaded() {
return !!(window.H && window.H.mapevents);
}
function _onLoad(sourceName) {
var deferQueue = API_DEFERSQueue[sourceName];
for (var i = 0, l = deferQueue.length; i < l; ++i) {
var defer = deferQueue[i];
defer.resolve();
}
API_DEFERSQueue[sourceName] = [];
}
function _onError(sourceName) {
var deferQueue = API_DEFERSQueue[sourceName];
for (var i = 0, l = deferQueue.length; i < l; ++i) {
var defer = deferQueue[i];
defer.reject();
}
API_DEFERSQueue[sourceName] = [];
}
};