UNPKG

angular-heremaps

Version:

Angular directive for working with Nokia Here Maps

1,599 lines (1,297 loc) 136 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ 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) { if (!coords) { return console.error('coords are not specified!'); } heremaps.map.setCenter(coords); }, 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(); } } } } }; },{}],2:[function(require,module,exports){ require('./providers/markers'); require('./providers/map-modules'); require('./providers/routes'); module.exports = angular.module('heremaps', [ 'heremaps-markers-module', 'heremaps-routes-module', 'heremaps-map-modules' ]) .provider('HereMapsConfig', require('./providers/mapconfig.provider')) .service('HereMapsUtilsService', require('./providers/maputils.service')) .service('HereMapsAPIService', require('./providers/api.service')) .constant('HereMapsCONSTS', require('./providers/consts')) .directive('heremaps', require('./heremaps.directive')); },{"./heremaps.directive":1,"./providers/api.service":3,"./providers/consts":4,"./providers/map-modules":7,"./providers/mapconfig.provider":9,"./providers/maputils.service":10,"./providers/markers":13,"./providers/routes":17}],3:[function(require,module,exports){ 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] = []; } }; },{}],4:[function(require,module,exports){ module.exports = { UPDATE_MAP_RESIZE_TIMEOUT: 500, ANIMATION_ZOOM_STEP: .05, MODULES: { UI: 'controls', EVENTS: 'events', PANO: 'pano' }, DEFAULT_MAP_OPTIONS: { height: 480, width: 640, zoom: 12, maxZoom: 2, resize: false, draggable: false, coords: { longitude: 0, latitude: 0 } }, MARKER_TYPES: { DOM: "DOM", SVG: "SVG" }, CONTROLS: { NAMES: { SCALE: 'scalebar', SETTINGS: 'mapsettings', ZOOM: 'zoom', USER: 'userposition' }, POSITIONS: [ 'top-right', 'top-center', 'top-left', 'left-top', 'left-middle', 'left-bottom', 'right-top', 'right-middle', 'right-bottom', 'bottom-right', 'bottom-center', 'bottom-left' ] }, INFOBUBBLE: { STATE: { OPEN: 'open', CLOSED: 'closed' }, DISPLAY_EVENT: { pointermove: 'onHover', tap: 'onClick' } }, USER_EVENTS: { tap: 'click', pointermove: 'mousemove', pointerleave: 'mouseleave', pointerenter: 'mouseenter', drag: 'drag', dragstart: 'dragstart', dragend: 'dragend', mapviewchange: 'mapviewchange', mapviewchangestart: 'mapviewchangestart', mapviewchangeend: 'mapviewchangeend' } } },{}],5:[function(require,module,exports){ module.exports = HereMapsEventsFactory; HereMapsEventsFactory.$inject = [ 'HereMapsUtilsService', 'HereMapsMarkerService', 'HereMapsCONSTS', 'HereMapsInfoBubbleFactory' ]; function HereMapsEventsFactory(HereMapsUtilsService, HereMapsMarkerService, HereMapsCONSTS, HereMapsInfoBubbleFactory) { function Events(platform, Injector, listeners) { this.map = platform.map; this.listeners = listeners; this.inject = new Injector(); this.events = platform.events = new H.mapevents.MapEvents(this.map); this.behavior = platform.behavior = new H.mapevents.Behavior(this.events); this.bubble = HereMapsInfoBubbleFactory.create(); this.setupEventListeners(); } var proto = Events.prototype; proto.setupEventListeners = setupEventListeners; proto.setupOptions = setupOptions; proto.triggerUserListener = triggerUserListener; proto.infoBubbleHandler = infoBubbleHandler; return { start: function(args) { if (!(args.platform.map instanceof H.Map)) return console.error('Missed required map instance'); var events = new Events(args.platform, args.injector, args.listeners); args.options && events.setupOptions(args.options); } } function setupEventListeners() { var self = this; HereMapsUtilsService.addEventListener(this.map, 'tap', this.infoBubbleHandler.bind(this)); HereMapsUtilsService.addEventListener(this.map, 'pointermove', this.infoBubbleHandler.bind(this)); HereMapsUtilsService.addEventListener(this.map, 'dragstart', function(e) { if (HereMapsMarkerService.isMarkerInstance(e.target)) { self.behavior.disable(); } self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); HereMapsUtilsService.addEventListener(this.map, 'drag', function(e) { var pointer = e.currentPointer, target = e.target; if (HereMapsMarkerService.isMarkerInstance(target)) { target.setPosition(self.map.screenToGeo(pointer.viewportX, pointer.viewportY)); } self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); HereMapsUtilsService.addEventListener(this.map, 'dragend', function(e) { if (HereMapsMarkerService.isMarkerInstance(e.target)) { self.behavior.enable(); } self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); HereMapsUtilsService.addEventListener(this.map, 'mapviewchangestart', function(e) { self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); HereMapsUtilsService.addEventListener(this.map, 'mapviewchange', function(e) { self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); HereMapsUtilsService.addEventListener(this.map, 'mapviewchangeend', function(e) { self.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); }); } function setupOptions(options) { if (!options) return; this.map.draggable = !!options.draggable; } function triggerUserListener(eventName, e) { if (!this.listeners) return; var callback = this.listeners[eventName]; callback && callback(e); } function infoBubbleHandler(e){ var ui = this.inject('ui'); if(ui) this.bubble.toggle(e, ui); this.triggerUserListener(HereMapsCONSTS.USER_EVENTS[e.type], e); } }; },{}],6:[function(require,module,exports){ module.exports = HereMapsInfoBubbleFactory; HereMapsInfoBubbleFactory.$inject = [ 'HereMapsMarkerService', 'HereMapsUtilsService', 'HereMapsCONSTS' ]; function HereMapsInfoBubbleFactory(HereMapsMarkerService, HereMapsUtilsService, HereMapsCONSTS) { function InfoBubble() {} var proto = InfoBubble.prototype; proto.create = create; proto.update = update; proto.toggle = toggle; proto.show = show; proto.close = close; return { create: function(){ return new InfoBubble(); } } function toggle(e, ui) { if (HereMapsMarkerService.isMarkerInstance(e.target)) this.show(e, ui); else this.close(e, ui); } function update(bubble, data) { bubble.display = data.display; bubble.setPosition(data.position); bubble.setContent(data.markup); bubble.setState(HereMapsCONSTS.INFOBUBBLE.STATE.OPEN); } function create(source) { var bubble = new H.ui.InfoBubble(source.position, { content: source.markup }); bubble.display = source.display; bubble.addClass(HereMapsCONSTS.INFOBUBBLE.STATE.OPEN) HereMapsUtilsService.addEventListener(bubble, 'statechange', function(e) { var state = this.getState(), el = this.getElement(); if (state === HereMapsCONSTS.INFOBUBBLE.STATE.CLOSED) { el.classList.remove(HereMapsCONSTS.INFOBUBBLE.STATE.OPEN); } else this.addClass(state) }); return bubble; } function show(e, ui, data) { var target = e.target, data = target.getData(), el = null; if (!data || !data.display || !data.markup || data.display !== HereMapsCONSTS.INFOBUBBLE.DISPLAY_EVENT[e.type]) return; var source = { position: target.getPosition(), markup: data.markup, display: data.display }; if (!ui.bubble) { ui.bubble = this.create(source); ui.addBubble(ui.bubble); return; } this.update(ui.bubble, source); } function close(e, ui) { if (!ui.bubble || ui.bubble.display !== HereMapsCONSTS.INFOBUBBLE.DISPLAY_EVENT[e.type]) { return; } ui.bubble.setState(HereMapsCONSTS.INFOBUBBLE.STATE.CLOSED); } } },{}],7:[function(require,module,exports){ angular.module('heremaps-events-module', []) .factory('HereMapsEventsFactory', require('./events/events.js')) .factory('HereMapsInfoBubbleFactory', require('./events/infobubble.js')); angular.module('heremaps-ui-module', []) .factory('HereMapsUiFactory', require('./ui/ui.js')) module.exports = angular.module('heremaps-map-modules', [ 'heremaps-events-module', 'heremaps-ui-module' ]); },{"./events/events.js":5,"./events/infobubble.js":6,"./ui/ui.js":8}],8:[function(require,module,exports){ module.exports = HereMapsUiFactory; HereMapsUiFactory.$inject = [ 'HereMapsAPIService', 'HereMapsMarkerService', 'HereMapsUtilsService', 'HereMapsCONSTS' ]; function HereMapsUiFactory(HereMapsAPIService, HereMapsMarkerService, HereMapsUtilsService, HereMapsCONSTS) { function UI(platform, alignment) { this.map = platform.map; this.layers = platform.layers; this.alignment = alignment; this.ui = platform.ui = H.ui.UI.createDefault(this.map, this.layers); this.setupControls(); } UI.isValidAlignment = isValidAlignment; var proto = UI.prototype; proto.setupControls = setupControls; proto.createUserControl = createUserControl; proto.setControlsAlignment = setControlsAlignment; return { start: function(args) { if (!(args.platform.map instanceof H.Map) && !(args.platform.layers)) return console.error('Missed ui module dependencies'); var ui = new UI(args.platform, args.alignment); } } function setupControls() { var NAMES = HereMapsCONSTS.CONTROLS.NAMES, userControl = this.createUserControl(); this.ui.getControl(NAMES.SETTINGS).setIncidentsLayer(false); this.ui.addControl(NAMES.USER, userControl); this.setControlsAlignment(NAMES); } function createUserControl() { var self = this, userControl = new H.ui.Control(), markup = '<svg class="H_icon" fill="#fff" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path class="middle_location_stroke" d="M8 12c-2.206 0-4-1.795-4-4 0-2.206 1.794-4 4-4s4 1.794 4 4c0 2.205-1.794 4-4 4M8 1.25a6.75 6.75 0 1 0 0 13.5 6.75 6.75 0 0 0 0-13.5"></path><path class="inner_location_stroke" d="M8 5a3 3 0 1 1 .001 6A3 3 0 0 1 8 5m0-1C5.794 4 4 5.794 4 8c0 2.205 1.794 4 4 4s4-1.795 4-4c0-2.206-1.794-4-4-4"></path><path class="outer_location_stroke" d="M8 1.25a6.75 6.75 0 1 1 0 13.5 6.75 6.75 0 0 1 0-13.5M8 0C3.59 0 0 3.59 0 8c0 4.411 3.59 8 8 8s8-3.589 8-8c0-4.41-3.59-8-8-8"></path></svg>'; var userControlButton = new H.ui.base.Button({ label: markup, onStateChange: function(evt) { if (userControlButton.getState() === H.ui.base.Button.State.DOWN) return; HereMapsAPIService.getPosition().then(function(response) { var position = { lng: response.coords.longitude, lat: response.coords.latitude }; self.map.setCenter(position); HereMapsUtilsService.zoom(self.map, 17, .08); if (self.userMarker) { self.userMarker.setPosition(position); return; } self.userMarker = HereMapsMarkerService.addUserMarker(self.map, { pos: position }); }); } }); userControl.addChild(userControlButton); return userControl; } function setControlsAlignment(NAMES) { if (!UI.isValidAlignment(this.alignment)) return; for (var id in NAMES) { var control = this.ui.getControl(NAMES[id]); if (!NAMES.hasOwnProperty(id) || !control) continue; control.setAlignment(this.alignment); } } function isValidAlignment(alignment) { return !!(HereMapsCONSTS.CONTROLS.POSITIONS.indexOf(alignment) + 1); } }; },{}],9:[function(require,module,exports){ module.exports = function() { var options = {}; var DEFAULT_API_VERSION = "3.0"; this.$get = function(){ return { app_id: options.app_id, app_code: options.app_code, apiVersion: options.apiVersion || DEFAULT_API_VERSION, useHTTPS: options.useHTTPS, useCIT: !!options.useCIT, mapTileConfig: options.mapTileConfig } }; this.setOptions = function(opts){ options = opts; }; }; },{}],10:[function(require,module,exports){ module.exports = HereMapsUtilsService; HereMapsUtilsService.$inject = [ '$rootScope', '$timeout', 'HereMapsCONSTS' ]; function HereMapsUtilsService($rootScope, $timeout, HereMapsCONSTS) { return { throttle: throttle, createScriptTag: createScriptTag, createLinkTag: createLinkTag, runScopeDigestIfNeed: runScopeDigestIfNeed, isValidCoords: isValidCoords, addEventListener: addEventListener, zoom: zoom, getBoundsRectFromPoints: getBoundsRectFromPoints, generateId: generateId, getMapFactory: getMapFactory }; //#region PUBLIC function throttle(fn, period) { var timeout = null; return function () { if ($timeout) $timeout.cancel(timeout); timeout = $timeout(fn, period); } } function addEventListener(obj, eventName, listener, useCapture) { obj.addEventListener(eventName, listener, !!useCapture); } function runScopeDigestIfNeed(scope, cb) { if (scope.$root && scope.$root.$$phase !== '$apply' && scope.$root.$$phase !== '$digest') { scope.$digest(cb || angular.noop); return true; } return false; } function createScriptTag(attrs) { var script = document.getElementById(attrs.src); if (script) return false; script = document.createElement('script'); script.type = 'text/javascript'; script.id = attrs.src; _setAttrs(script, attrs); return script; } function createLinkTag(attrs) { var link = document.getElementById(attrs.href); if (link) return false; link = document.createElement('link'); link.id = attrs.href; _setAttrs(link, attrs); return link; } function isValidCoords(coords) { return coords && (typeof coords.latitude === 'string' || typeof coords.latitude === 'number') && (typeof coords.longitude === 'string' || typeof coords.longitude === 'number') } function zoom(map, value, step) { var currentZoom = map.getZoom(), _step = step || HereMapsCONSTS.ANIMATION_ZOOM_STEP, factor = currentZoom >= value ? -1 : 1, increment = step * factor; return (function zoom() { if (!step || Math.floor(currentZoom) === Math.floor(value)) { map.setZoom(value); return; } currentZoom += increment; map.setZoom(currentZoom); requestAnimationFrame(zoom); })(); } function getMapFactory(){ return H; } /** * @method getBoundsRectFromPoints * * @param {Object} topLeft * @property {Number|String} lat * @property {Number|String} lng * @param {Object} bottomRight * @property {Number|String} lat * @property {Number|String} lng * * @return {H.geo.Rect} */ function getBoundsRectFromPoints(topLeft, bottomRight) { return H.geo.Rect.fromPoints(topLeft, bottomRight, true); } function generateId() { var mask = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', regexp = /[xy]/g, d = new Date().getTime(), uuid = mask.replace(regexp, function (c) { var r = (d + Math.random() * 16) % 16 | 0; d = Math.floor(d / 16); return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); }); return uuid; } //#endregion PUBLIC function _setAttrs(el, attrs) { if (!el || !attrs) throw new Error('Missed attributes'); for (var key in attrs) { if (!attrs.hasOwnProperty(key)) continue; el[key] = attrs[key]; } } }; },{}],11:[function(require,module,exports){ module.exports = HereMapsDefaultMarker; HereMapsDefaultMarker.$inject = ['HereMapsMarkerInterface']; function HereMapsDefaultMarker(HereMapsMarkerInterface){ function DefaultMarker(place){ this.place = place; this.setCoords(); } var proto = DefaultMarker.prototype = new HereMapsMarkerInterface(); proto.constructor = DefaultMarker; proto.create = create; return DefaultMarker; function create(){ var marker = new H.map.Marker(this.coords); this.addInfoBubble(marker); return marker; } } },{}],12:[function(require,module,exports){ module.exports = HereMapsDOMMarker; HereMapsDOMMarker.$inject = ['HereMapsMarkerInterface']; function HereMapsDOMMarker(HereMapsMarkerInterface){ function DOMMarker(place){ this.place = place; this.setCoords(); } var proto = DOMMarker.prototype = new HereMapsMarkerInterface(); proto.constructor = DOMMarker; proto.create = create; proto.getIcon = getIcon; proto.setupEvents = setupEvents; return DOMMarker; function create(){ var marker = new H.map.DomMarker(this.coords, { icon: this.getIcon() }); this.addInfoBubble(marker); return marker; } function getIcon(){ var icon = this.place.markup; if(!icon) throw new Error('markup missed'); return new H.map.DomIcon(icon); } function setupEvents(el, events, remove){ var method = remove ? 'removeEventListener' : 'addEventListener'; for(var key in events) { if(!events.hasOwnProperty(key)) continue; el[method].call(null, key, events[key]); } } } },{}],13:[function(require,module,exports){ module.exports = angular.module('heremaps-markers-module', []) .factory('HereMapsMarkerInterface', require('./marker.js')) .factory('HereMapsDefaultMarker', require('./default.marker.js')) .factory('HereMapsDOMMarker', require('./dom.marker.js')) .factory('HereMapsSVGMarker', require('./svg.marker.js')) .service('HereMapsMarkerService', require('./markers.service.js')); },{"./default.marker.js":11,"./dom.marker.js":12,"./marker.js":14,"./markers.service.js":15,"./svg.marker.js":16}],14:[function(require,module,exports){ module.exports = function(){ function MarkerInterface(){ throw new Error('Abstract class! The Instance should be created'); } var proto = MarkerInterface.prototype; proto.create = create; proto.setCoords = setCoords; proto.addInfoBubble = addInfoBubble; function Marker(){} Marker.prototype = proto; return Marker; function create(){ throw new Error('create:: not implemented'); } function setCoords(){ this.coords = { lat: this.place.pos.lat, lng: this.place.pos.lng } } function addInfoBubble(marker){ if(!this.place.popup) return; marker.setData(this.place.popup) } } },{}],15:[function(require,module,exports){ module.exports = HereMapsMarkerService; HereMapsMarkerService.$inject = [ 'HereMapsDefaultMarker', 'HereMapsDOMMarker', 'HereMapsSVGMarker', 'HereMapsCONSTS' ]; function HereMapsMarkerService(HereMapsDefaultMarker, HereMapsDOMMarker, HereMapsSVGMarker, HereMapsCONSTS) { var MARKER_TYPES = HereMapsCONSTS.MARKER_TYPES; return { addMarkersToMap: addMarkersToMap, addUserMarker: addUserMarker, updateMarkers: updateMarkers, isMarkerInstance: isMarkerInstance, setViewBounds: setViewBounds } function isMarkerInstance(target) { return target instanceof H.map.Marker || target instanceof H.map.DomMarker; } function addUserMarker(map, place) { if (map.userMarker) return map.userMarker; place.markup = '<svg width="35px" height="35px" viewBox="0 0 90 90" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">' + '<defs><circle id="path-1" cx="302" cy="802" r="15"></circle>' + '<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="-30" y="-30" width="90" height="90">' + '<rect x="257" y="757" width="90" height="90" fill="white"></rect><use xlink:href="#path-1" fill="black"></use>' + '</mask></defs><g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">' + '<g id="Service-Options---directions---map" transform="translate(-257.000000, -757.000000)"><g id="Oval-15">' + '<use fill="#FFFFFF" fill-rule="evenodd" xlink:href="#path-1"></use>' + '<use stroke-opacity="0.29613904" stroke="#3F34A0" mask="url(#mask-2)" stroke-width="60" xlink:href="#path-1"></use>' + '<use stroke="#3F34A0" stroke-width="5" xlink:href="#path-1"></use></g></g></g></svg>'; map.userMarker = new HereMapsSVGMarker(place).create(); map.addObject(map.userMarker); return map.userMarker; } function addMarkersToMap(map, places, refreshViewbounds) { if (!places || !places.length) return; if (!(map instanceof H.Map)) throw new Error('Unsupported map instance'); if (!map.markersGroup) map.markersGroup = new H.map.Group(); places.forEach(function (place, i) { var creator = _getMarkerCreator(place), marker = place.draggable ? _draggableMarkerMixin(creator.create()) : creator.create(); map.markersGroup.addObject(marker); }); map.addObject(map.markersGroup); if (refreshViewbounds) { setViewBounds(map, map.markersGroup.getBounds()); } } function setViewBounds(map, bounds, opt_animate) { map.setViewBounds(bounds, !!opt_animate); } function updateMarkers(map, places, refreshViewbounds) { if (map.markersGroup) { map.markersGroup.removeAll(); map.removeObject(map.markersGroup); map.markersGroup = null; } addMarkersToMap.apply(null, arguments); } function _getMarkerCreator(place) { var ConcreteMarker, type = place.type ? place.type.toUpperCase() : null; switch (type) { case MARKER_TYPES.DOM: ConcreteMarker = HereMapsDOMMarker; break; case MARKER_TYPES.SVG: ConcreteMarker = HereMapsSVGMarker; break; default: ConcreteMarker = HereMapsDefaultMarker; } return new ConcreteMarker(place); } function _draggableMarkerMixin(marker) { marker.draggable = true; return marker; } }; },{}],16:[function(require,module,exports){ module.exports = HereMapsSVGMarker; HereMapsSVGMarker.$inject = ['HereMapsMarkerInterface']; function HereMapsSVGMarker(HereMapsMarkerInterface){ function SVGMarker(place){ this.place = place; this.setCoords(); } var proto = SVGMarker.prototype = new HereMapsMarkerInterface(); proto.constructor = SVGMarker; proto.create = create; proto.getIcon = getIcon; return SVGMarker; function create(){ var marker = new H.map.Marker(this.coords, { icon: this.getIcon(), }); this.addInfoBubble(marker); return marker; } function getIcon(){ var icon = this.place.markup; if(!icon) throw new Error('markup missed'); return new H.map.Icon(icon); } } },{}],17:[function(require,module,exports){ module.exports = angular.module('heremaps-routes-module', []) .service('HereMapsRoutesService', require('./routes.service.js')); },{"./routes.service.js":18}],18:[function(require,module,exports){ module.exports = HereMapsRoutesService; HereMapsRoutesService.$inject = ['$q', 'HereMapsMarkerService']; function HereMapsRoutesService($q, HereMapsMarkerService) { return { calculateRoute: calculateRoute, addRouteToMap: addRouteToMap, cleanRoutes: cleanRoutes } function calculateRoute(heremaps, config) { var platform = heremaps.platform, map = heremaps.map, router = platform.getRoutingService(), dir = config.direction, waypoints = dir.waypoints; var mode = '{{MODE}};{{VECHILE}}' .replace(/{{MODE}}/, dir.mode || 'fastest') .replace(/{{VECHILE}}/, config.driveType); var routeRequestParams = { mode: mode, representation: dir.representation || 'display', language: dir.language || 'en-gb' }; waypoints.forEach(function (waypoint, i) { routeRequestParams["waypoint" + i] = [waypoint.lat, waypoint.lng].join(','); }); _setAttributes(routeRequestParams, dir.attrs); var deferred = $q.defer(); router.calculateRoute(routeRequestParams, function (result) { deferred.resolve(result); }, function (error) { deferred.reject(error); }); return deferred.promise; } function cleanRoutes(map) { var group = map.routesGroup; if (!group) return; group.removeAll(); map.removeObject(group); map.routesGroup = null; } function addRouteToMap(map, routeData, clean) { if (clean) cleanRoutes(map); var route = routeData.route; if (!map || !route || !route.shape) return; var strip = new H.geo.Strip(), polyline = null; route.shape.forEach(function (point) { var parts = point.split(','); strip.pushLatLngAlt(parts[0], parts[1]); }); var style = routeData.style || {}; polyline = new H.map.Polyline(strip, { style: { lineWidth: style.lineWidth || 4, strokeColor: style.color || 'rgba(0, 128, 255, 0.7)' } }); var group = map.routesGroup; if (!group) { group = map.routesGroup = new H.map.Group(); map.addObject(group); } group.addObject(polyline); if(routeData.zoomToBounds) { HereMapsMarkerService.setViewBounds(map, polyline.getBounds(), true); } } //#region PRIVATE function _setAttributes(params, attrs) { var _key = 'attributes'; for (var key in attrs) { if (!attrs.hasOwnProperty(key)) continue; params[key + _key] = attrs[key]; } } /** * Creates a series of H.map.Marker points from the route and adds them to the map. * @param {Object} route A route as received from the H.service.RoutingService */ function addManueversToMap(map, route) { var svgMarkup = '<svg width="18" height="18" ' + 'xmlns="http://www.w3.org/2000/svg">' + '<circle cx="8" cy="8" r="8" ' + 'fill="#1b468d" stroke="white" stroke-width="1" />' + '</svg>', dotIcon = new H.map.Icon(svgMarkup, { anchor: { x: 8, y: 8 } }), group = new H.map.Group(), i, j; // Add a marker for each maneuver for (i = 0; i < route.leg.length; i += 1) { for (j = 0; j < route.leg[i].maneuver.length; j += 1) { // Get the next maneuver. maneuver = route.leg[i].maneuver[j]; // Add a marker to the maneuvers group var marker = new H.map.Marker({ lat: maneuver.position.latitude, lng: maneuver.position.longitude }, { icon: dotIcon } ); marker.instruction = maneuver.instruction; group.addObject(marker); } } group.addEventListener('tap', function (evt) { map.setCenter(evt.target.getPosition()); openBubble(evt.target.getPosition(), evt.target.instruction); }, false); // Add the maneuvers group to the map map.addObject(group); } /** * Creates a series of H.map.Marker points from the route and adds them to the map. * @param {Object} route A route a