src/heremaps.directive.js
module.exports = HereMapsDirective;
HereMapsDirective.$inject = [
'$timeout',
'$window',
'$rootScope',
'$filter',
'HereMapsConfig',
'HereMapsAPIService',
'HereMapsUtilsService',
'HereMapsMarkerService',
'HereMapsRoutesService',
'HereMapsCONSTS',
'HereMapsEventsFactory',
'HereMapsUiFactory'
];
function HereMapsDirective(
$timeout,
$window,
$rootScope,
$filter,
HereMapsConfig,
HereMapsAPIService,
HereMapsUtilsService,
HereMapsMarkerService,
HereMapsRoutesService,
HereMapsCONSTS,
HereMapsEventsFactory,
HereMapsUiFactory) {
HereMapsDirectiveCtrl.$inject = ['$scope', '$element', '$attrs'];
return {
restrict: 'EA',
template: "<div ng-style=\"{'width': mapWidth, 'height': mapHeight}\"></div>",
replace: true,
scope: {
opts: '&options',
places: '&',
onMapReady: "&mapReady",
events: '&'
},
controller: HereMapsDirectiveCtrl
}
function HereMapsDirectiveCtrl($scope, $element, $attrs) {
var CONTROL_NAMES = HereMapsCONSTS.CONTROLS.NAMES,
places = $scope.places(),
opts = $scope.opts(),
listeners = $scope.events();
var options = angular.extend({}, HereMapsCONSTS.DEFAULT_MAP_OPTIONS, opts),
position = HereMapsUtilsService.isValidCoords(options.coords) ?
options.coords : HereMapsCONSTS.DEFAULT_MAP_OPTIONS.coords;
var heremaps = { id: HereMapsUtilsService.generateId() },
mapReady = $scope.onMapReady(),
_onResizeMap = null;
$timeout(function () {
return _setMapSize();
}).then(function () {
HereMapsAPIService.loadApi().then(_apiReady);
});
options.resize && addOnResizeListener();
$scope.$on('$destroy', function () {
$window.removeEventListener('resize', _onResizeMap);
});
function addOnResizeListener() {
_onResizeMap = HereMapsUtilsService.throttle(_resizeHandler, HereMapsCONSTS.UPDATE_MAP_RESIZE_TIMEOUT);
$window.addEventListener('resize', _onResizeMap);
}
function _apiReady() {
_setupMapPlatform();
_setupMap();
}
function _setupMapPlatform() {
if (!HereMapsConfig.app_id || !HereMapsConfig.app_code)
throw new Error('app_id or app_code were missed. Please specify their in HereMapsConfig');
heremaps.platform = new H.service.Platform(HereMapsConfig);
heremaps.layers = heremaps.platform.createDefaultLayers();
}
function _getLocation(enableHighAccuracy, maximumAge) {
var _enableHighAccuracy = !!enableHighAccuracy,
_maximumAge = maximumAge || 0;
return HereMapsAPIService.getPosition({
enableHighAccuracy: _enableHighAccuracy,
maximumAge: _maximumAge
});
}
function _locationFailure() {
console.error('Can not get a geo position');
}
function _setupMap() {
_initMap(function () {
HereMapsAPIService.loadModules($attrs.$attr, {
"controls": _uiModuleReady,
"events": _eventsModuleReady
});
});
}
function _initMap(cb) {
var map = heremaps.map = new H.Map($element[0], heremaps.layers.normal.map, {
zoom: HereMapsUtilsService.isValidCoords(position) ? options.zoom : options.maxZoom,
center: new H.geo.Point(position.latitude, position.longitude)
});
HereMapsMarkerService.addMarkersToMap(map, places, true);
if (HereMapsConfig.mapTileConfig)
_setCustomMapStyles(map, HereMapsConfig.mapTileConfig);
mapReady && mapReady(MapProxy());
cb && cb();
}
function _uiModuleReady() {
HereMapsUiFactory.start({
platform: heremaps,
alignment: $attrs.controls
});
}
function _eventsModuleReady() {
HereMapsEventsFactory.start({
platform: heremaps,
listeners: listeners,
options: options,
injector: _moduleInjector
});
}
function _moduleInjector() {
return function (id) {
return heremaps[id];
}
}
function _resizeHandler(height, width) {
_setMapSize.apply(null, arguments);
heremaps.map.getViewPort().resize();
}
function _setMapSize(height, width) {
var height = height || $element[0].parentNode.offsetHeight || options.height,
width = width || $element[0].parentNode.offsetWidth || options.width;
$scope.mapHeight = height + 'px';
$scope.mapWidth = width + 'px';
HereMapsUtilsService.runScopeDigestIfNeed($scope);
}
function _setCustomMapStyles(map, config) {
// Create a MapTileService instance to request base tiles (i.e. base.map.api.here.com):
var mapTileService = heremaps.platform.getMapTileService({ 'type': 'base' });
// Create a tile layer which requests map tiles
var newStyleLayer = mapTileService.createTileLayer(
'maptile',
config.scheme || 'normal.day',
config.size || 256,
config.format || 'png8',
config.metadataQueryParams || {}
);
// Set new style layer as a base layer on the map:
map.setBaseLayer(newStyleLayer);
}
function MapProxy() {
return {
refresh: function () {
var currentBounds = this.getViewBounds();
this.setMapSizes();
this.setViewBounds(currentBounds);
},
setMapSizes: function (height, width) {
_resizeHandler.apply(null, arguments);
},
getPlatform: function () {
return heremaps;
},
calculateRoute: function (driveType, direction) {
return HereMapsRoutesService.calculateRoute(heremaps, {
driveType: driveType,
direction: direction
});
},
addRouteToMap: function (routeData, clean) {
HereMapsRoutesService.addRouteToMap(heremaps.map, routeData, clean);
},
setZoom: function (zoom, step) {
HereMapsUtilsService.zoom(heremaps.map, zoom || 10, step);
},
getZoom: function () {
return heremaps.map.getZoom();
},
getCenter: function () {
return heremaps.map.getCenter();
},
getViewBounds: function () {
return heremaps.map.getViewBounds();
},
setViewBounds: function (boundingRect, opt_animate) {
HereMapsMarkerService.setViewBounds(heremaps.map, boundingRect, opt_animate);
},
getBoundsRectFromPoints: function (topLeft, bottomRight) {
return HereMapsUtilsService.getBoundsRectFromPoints.apply(null, arguments);
},
setCenter: function (coords, opt_animate) {
if (!coords) {
return console.error('coords are not specified!');
}
heremaps.map.setCenter(coords, opt_animate);
},
cleanRoutes: function () {
HereMapsRoutesService.cleanRoutes(heremaps.map);
},
/**
* @param {Boolean} enableHighAccuracy
* @param {Number} maximumAge - the maximum age in milliseconds of a possible cached position that is acceptable to return. If set to 0, it means that the device cannot use a cached position and must attempt to retrieve the real current position
* @return {Promise}
*/
getUserLocation: function (enableHighAccuracy, maximumAge) {
return _getLocation.apply(null, arguments).then(function (position) {
var coords = position.coords;
return {
lat: coords.latitude,
lng: coords.longitude
};
})
},
geocodePosition: function (coords, options) {
return HereMapsAPIService.geocodePosition(heremaps.platform, {
coords: coords,
radius: options && options.radius,
lang: options && options.lang
});
},
geocodeAddress: function (address) {
return HereMapsAPIService.geocodeAddress(heremaps.platform, {
searchtext: address && address.searchtext,
country: address && address.country,
city: address && address.city,
street: address && address.street,
housenumber: address && address.housenumber
});
},
geocodeAutocomplete: function (query, options) {
return HereMapsAPIService.geocodeAutocomplete({
query: query,
beginHighlight: options && options.beginHighlight,
endHighlight: options && options.endHighlight,
maxresults: options && options.maxresults
});
},
findLocationById: function (locationId) {
return HereMapsAPIService.findLocationById(locationId);
},
updateMarkers: function (places, refreshViewbounds) {
HereMapsMarkerService.updateMarkers(heremaps.map, places, refreshViewbounds);
},
getMapFactory: function (){
return HereMapsUtilsService.getMapFactory();
}
}
}
}
};