ng2-heremaps
Version:
Here Maps for Angular 6
1,669 lines (1,647 loc) • 48.9 kB
JavaScript
/**
* @license ng2-heremaps
* MIT license
*/
import { InjectionToken, Injectable, Inject, Component, Input, forwardRef, ElementRef, Attribute, ContentChildren, Output, EventEmitter, Directive, NgModule } from '@angular/core';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
// unsupported: template constraints.
/**
* Base class used to implement map extensions, e.g. markers, directions ...
* @abstract
* @template T
*/
class BaseMapComponent {
constructor() {
this.proxy = new Promise(resolve => (this.proxyResolver = resolve));
}
/**
* Override this method to notify when map become available to component/directive.
* @return {?}
*/
hasMapComponent() {
return false;
}
/**
* Override this method to resolve your internal heremap objects
* @param {?} component instance of map component
* @param {?} map instance of heremap
* @param {?} ui instance of ui overlay that is instanciated during map initialization
* @return {?}
*/
setMapComponent(component, map, ui) {
// Placeholder for fixing circular dependency, if not extended is noop.
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ LAZY_LOADER_OPTIONS = new InjectionToken('_heremaps.LazyMapLoaderApiOptions');
/**
* Created by mjaric on 9/28/16.
* @abstract
*/
class BaseMapsApiLoader {
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ ScriptLoaderProtocol = {
AUTO: 'auto',
HTTP: 'http',
HTTPS: 'https'
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class LazyMapsApiLoader extends BaseMapsApiLoader {
/**
* @param {?} options
*/
constructor(options) {
super();
this.platformReady = new Promise((resolve, reject) => {
this._rejectPlatform = reject;
this._resolvePlatform = resolve;
});
this._initialized = false;
this._modules = new Map([
['core', ['js']],
['service', ['js']],
['mapevents', ['js']],
['ui', ['js', 'css']],
['clustering', ['js']],
['data', ['js']],
['places', ['js']],
['pano', ['js']]
]);
this._options = Object.assign({}, {
apiKey: '',
appId: '',
apiVersion: '3.0',
protocol: ScriptLoaderProtocol.AUTO,
libraries: []
}, options);
const /** @type {?} */ libs = this._options.libraries.filter(l => l !== 'core' && l !== 'service');
this._options.libraries = ['service', ...libs];
}
/**
* @return {?}
*/
load() {
if (this._initialized === false) {
this.loadModules()
.then(_ => {
const /** @type {?} */ platform = new H.service.Platform({
app_id: this._options.appId,
app_code: this._options.apiKey,
useHTTPS: (/** @type {?} */ (document.location)).protocol === 'https:'
});
this._resolvePlatform(platform);
})
.catch(error => {
this._rejectPlatform(error);
});
}
return this.platformReady;
}
/**
* @return {?}
*/
loadModules() {
// Load the Core first then the rest of the files
return this.loadModule('core').then(() => Promise.all(this._options.libraries
.reduce(this.distinct, [])
.map(moduleName => this.loadModule(moduleName))));
}
/**
* @param {?} moduleName
* @return {?}
*/
loadModule(moduleName) {
const /** @type {?} */ mod = this._modules.get(moduleName);
if (mod === void 0) {
const /** @type {?} */ error = new Error(`Unknown module ${moduleName}`);
return Promise.reject(error);
}
if (mod.indexOf('css') > -1) {
document.body.appendChild(this.createStylesheet(moduleName));
}
return new Promise((resolve, reject) => {
const /** @type {?} */ el = this.createScript(moduleName, resolve, reject);
document.body.appendChild(el);
});
}
/**
* @param {?} moduleName
* @return {?}
*/
createStylesheet(moduleName) {
const /** @type {?} */ element = document.createElement('link');
element.rel = 'stylesheet';
element.href = this.createModuleUrl(moduleName, 'css');
if (console !== void 0) {
element.onerror = console.error.bind(console);
}
return element;
}
/**
* @param {?} moduleName
* @param {?} onLoad
* @param {?} onError
* @return {?}
*/
createScript(moduleName, onLoad, onError) {
const /** @type {?} */ script = document.createElement('script');
script.type = 'text/javascript';
script.src = this.createModuleUrl(moduleName, 'js');
script.async = true;
script.defer = true;
script.addEventListener('error', onError);
script.addEventListener('load', onLoad);
return script;
}
/**
* @param {?} module
* @param {?=} ext
* @return {?}
*/
createModuleUrl(module, ext = 'js') {
const /** @type {?} */ protocol = 'https:', /** @type {?} */
// (document.location as any).protocol,
version = this._options.apiVersion;
return `${protocol}//js.api.here.com/v3/${version}/mapsjs-${module}.${ext}`;
}
/**
* @param {?} acc
* @param {?} next
* @return {?}
*/
distinct(acc, next) {
if (acc.indexOf(next) > -1) {
return acc;
}
return [...acc, next];
}
}
LazyMapsApiLoader.decorators = [
{ type: Injectable }
];
/** @nocollapse */
LazyMapsApiLoader.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [LAZY_LOADER_OPTIONS,] },] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
const /** @type {?} */ DefaultCoords = {
latitude: 40.73061,
longitude: -73.935242
};
/**
* @return {?}
*/
function noop() {
// noop
}
/**
* Service responsible to execute arbitrary functions in specific google map context
*/
class HereMapsManager {
/**
* @param {?} loader
*/
constructor(loader) {
this.loader = loader;
this._maps = new Map();
// check browser location
this.getBrowserLocation().then(noop);
// preload map immediately
this._loadPromise = this.loader.load();
}
/**
* @return {?}
*/
onApiLoad() {
return this.loader.platformReady;
}
/**
* @param {?} options
* @return {?}
*/
createMarker(options) {
return this.loader.platformReady.then(() => {
return new H.map.Marker(/** @type {?} */ (options.position));
});
}
/**
* @param {?} options
* @return {?}
*/
createBubble(options) {
return this.loader.platformReady.then(() => {
return new H.ui.InfoBubble(/** @type {?} */ (options.position));
});
}
/**
* @param {?} origin
* @param {?} destination
* @param {?=} intermediatePoints
* @return {?}
*/
getDirections(origin, destination, intermediatePoints = []) {
return this.loader.platformReady.then(platform => {
const /** @type {?} */ router = platform.getRoutingService();
return new Promise((resolve, reject) => {
const /** @type {?} */ params = {
mode: 'balanced;truck',
representation: 'navigation'
};
const /** @type {?} */ waypoints = [origin, ...intermediatePoints, destination];
waypoints.forEach((waypoint, index) => (params[`waypoint${index}`] = this.generateWaypointParam(waypoint, index === 0 || index === waypoints.length - 1)));
router.calculateRoute(params, (result) => resolve(result), (error) => {
console.error({
message: 'fail to get directions',
error
});
reject(error);
});
});
});
}
/**
* @param {?} el
* @param {?=} options
* @param {?=} controls
* @return {?}
*/
createMap(el, options, controls) {
return this.loader.platformReady.then(platform => {
const /** @type {?} */ defaultLayers = this._defaultLayers || platform.createDefaultLayers();
this._defaultLayers = defaultLayers;
const /** @type {?} */ map = new H.Map(el, defaultLayers.normal.map, options);
const /** @type {?} */ ui = H.ui.UI.createDefault(map, defaultLayers, 'en-US');
ui.setUnitSystem(H.ui.UnitSystem.IMPERIAL);
const /** @type {?} */ mapEvents = new H.mapevents.MapEvents(map);
const /** @type {?} */ behavior = new H.mapevents.Behavior(mapEvents);
if (controls) {
if (!controls.mapTypeControl) {
ui.removeControl('mapsettings');
}
if (!controls.zoomControl) {
ui.removeControl('zoom');
}
if (!controls.scaleControl) {
ui.removeControl('scalebar');
}
if (!controls.streetViewControl && (/** @type {?} */ (H)).PanoramaView) {
ui.removeControl('panorama');
}
if (!controls.scrollwheel) {
behavior.disable(H.mapevents.Behavior.WHEELZOOM);
}
if (!controls.enableDoubleClickZoom) {
behavior.disable(H.mapevents.Behavior.DBLTAPZOOM);
}
if (!controls.draggable) {
behavior.disable(H.mapevents.Behavior.DRAGGING);
}
}
return { map, ui, platform };
});
}
/**
* @param {?} name
* @return {?}
*/
getMap(name) {
return this._loadPromise.then(() => this._maps.get(name));
}
/**
* @param {?} name
* @param {?} map
* @return {?}
*/
addMap(name, map) {
this._maps.set(name, map);
}
/**
* @param {?} name
* @return {?}
*/
removeMap(name) {
return this._maps.delete(name);
}
/**
* @return {?}
*/
getBrowserLocation() {
if (this._browserLocationPromise) {
return this._browserLocationPromise;
}
return (this._browserLocationPromise = new Promise(resolve => {
if (location.protocol === 'https' && navigator.geolocation) {
navigator.geolocation.getCurrentPosition((success) => {
resolve(success.coords);
}, error => {
console.error(error);
if (error.code !== 1) {
console.warn(`Permission is accepted but error encounter with message: ${error.message}`);
}
// if user didn't answer return default
resolve(DefaultCoords);
});
}
else {
// if browser do not support location API return default (NYC)
resolve(DefaultCoords);
}
}));
}
/**
* @param {?=} points
* @return {?}
*/
calculateMapBounds(points = []) {
return this.loader.platformReady.then(_ => {
const /** @type {?} */ bounds = new H.map.Group().getBounds();
if (points && points.length > 1) {
points.forEach(m => {
if (m instanceof H.map.AbstractMarker) {
bounds.mergePoint(m.getPosition());
}
else {
bounds.mergePoint({
lat: (/** @type {?} */ (m)).latitude !== void 0
? (/** @type {?} */ (m)).latitude
: (/** @type {?} */ (m)).lat,
lng: (/** @type {?} */ (m)).longitude !== void 0
? (/** @type {?} */ (m)).longitude
: (/** @type {?} */ (m)).lng
});
}
});
return Promise.resolve(bounds);
}
return Promise.resolve(bounds);
});
}
/**
* @param {?} coordinates
* @param {?=} end
* @return {?}
*/
generateWaypointParam(coordinates, end = false) {
const /** @type {?} */ lat = (/** @type {?} */ (coordinates)).lat || (/** @type {?} */ (coordinates)).latitude || 0;
const /** @type {?} */ lng = (/** @type {?} */ (coordinates)).lng ||
(/** @type {?} */ (coordinates)).longitude ||
(/** @type {?} */ (coordinates)).lon ||
0;
return `geo!${end ? 'stopOver' : 'passThrough'}!${lat},${lng}`;
}
}
HereMapsManager.decorators = [
{ type: Injectable }
];
/** @nocollapse */
HereMapsManager.ctorParameters = () => [
{ type: LazyMapsApiLoader, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class MapUIService {
/**
* @param {?} mapManager
*/
constructor(mapManager) {
this.mapManager = mapManager;
this.ui = new Promise((resolve) => {
this.setUi = resolve;
});
}
}
MapUIService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
MapUIService.ctorParameters = () => [
{ type: HereMapsManager, },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Converts supported type of geo point to LatLong object.
* If geoPoint parameter is null or undefined then function will return geo center
* {lat: 0, lng: 0}
* @param {?} geoPoint Any supported type of geo point
* @return {?}
*/
function toLatLng(geoPoint) {
if (geoPoint) {
return {
lat: 'lat' in geoPoint
? (/** @type {?} */ (geoPoint)).lat
: (/** @type {?} */ (geoPoint)).latitude,
lng: 'lng' in geoPoint
? (/** @type {?} */ (geoPoint)).lng
: 'lon' in geoPoint
? (/** @type {?} */ (geoPoint)).lon
: (/** @type {?} */ (geoPoint)).longitude
};
}
return { lat: 0, lng: 0 };
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Component that should render and initialize map instance.
* Use it to define point in html document where map should be rendered
*/
class MapComponent {
/**
* @param {?} _name
* @param {?} _elem
* @param {?} _mapsManager
*/
constructor(_name, _elem, _mapsManager) {
this._name = _name;
this._elem = _elem;
this._mapsManager = _mapsManager;
this.ui = new Promise(resolve => (this._uiResolver = resolve));
/**
* Should map auto resize bounds to current set of markers
*/
this.autoFitMarkers = true;
/**
* Enables/disables zoom and center on double click. Enabled by default.
*/
this.enableDoubleClickZoom = true;
/**
* If false, prevents the map from being dragged.
* Dragging is enabled by default.
*/
this.draggable = true;
/**
* If false, prevents the map from being controlled by the keyboard.
* Keyboard shortcuts are enabled by default.
*/
this.keyboardShortcuts = true;
/**
* If false, disables scrollwheel zooming on the map.
* The scrollwheel is enabled by default.
*/
this.scrollwheel = true;
/**
* Map zoom level.
*/
this.zoom = 5;
/**
* Enables/disables all default UI.
*/
this.disableDefaultUI = false;
/**
* Enabled/Disabled state of the Map type control.
*/
this.mapTypeControl = false;
/**
* Enabled/Disabled state of the Rotate control.
*/
this.rotateControl = false;
/**
* Enabled/Disabled state of the Scale control.
*/
this.scaleControl = true;
/**
* Enabled/Disabled state of the Street View Pegman control.
*/
this.streetViewControl = false;
this.animateZoom = true;
/**
* Enabled/Disabled state of the Zoom control
*/
this.zoomControl = true;
/**
* Notifies subscribers that map is updated
*/
this.update = new EventEmitter();
/**
* Fires when user interacts with map by clicking on it
*/
this.clickMap = new EventEmitter();
this._id = MapComponent.counters++;
this._map = new Promise(resolve => (this._mapResolver = resolve));
}
/**
* Color used for the background of the Map div.
* This color will be visible when tiles have not yet loaded as the user pans.
* Note: This option can only be set when the map is initialized.
* @param {?} value
* @return {?}
*/
set backgroundColor(value) {
if (this._mapBackgroundColor) {
console.warn('Option "backgroundColor" can only be set when the map is initialized');
return;
}
this._mapBackgroundColor = value;
}
/**
* The initial Map center. Required.
* @param {?} value
* @return {?}
*/
set center(value) {
if (!value) {
return;
}
const /** @type {?} */ mapCenter = toLatLng(value);
this._map.then(map => {
if (mapCenter.lat && mapCenter.lng) {
map.setCenter(toLatLng(value));
}
});
if (mapCenter.lat && mapCenter.lng)
this._center = toLatLng(value);
}
/**
* @return {?}
*/
get center() {
return this._center;
}
/**
* When resolved, returns Heremap instance
* @return {?}
*/
getMap() {
return this._map;
}
/**
* @return {?}
*/
ngOnInit() {
this._mapsManager
.createMap(this._elem.nativeElement.querySelector('.heremap-container'), this.getOptions(), this.getControlOptions())
.then(({ map: map, ui: ui, platform: platform }) => {
this._mapsManager.addMap(this.toString(), map);
this._uiResolver(ui);
this._mapResolver(map);
this.attachEvents(map);
});
}
/**
* @return {?}
*/
ngOnDestroy() {
this._mapsManager.removeMap(this.toString());
this._mapComponentsSubscriptions.unsubscribe();
}
/**
* @return {?}
*/
ngAfterContentInit() {
this._mapComponentsSubscriptions = this.mapComponents.changes.subscribe(() => {
this.attachComponentsToMap();
});
this.attachComponentsToMap();
}
/**
* @return {?}
*/
toString() {
return this._name ? this._name : `fh.here-maps-${this._id}`;
}
/**
* Fits map to given bounds
* @param {?} bounds
* @return {?}
*/
fitBounds(bounds) {
this.resetMapBounds(bounds);
}
/**
* @return {?}
*/
attachComponentsToMap() {
this._map.then(map => {
this.ui.then(ui => {
this.mapComponents.filter(v => !v.hasMapComponent()).forEach(v => {
v.setMapComponent(this, map, ui);
});
});
});
}
/**
* @return {?}
*/
getOptions() {
return {
center: this.center ? this.latLngCenter() : { lat: 0, lng: 0 },
zoom: this.zoom || 5
};
}
/**
* @return {?}
*/
getControlOptions() {
return {
mapTypeControl: this.mapTypeControl,
rotateControl: this.rotateControl,
scaleControl: this.scaleControl,
streetViewControl: this.streetViewControl,
zoomControl: this.zoomControl,
enableDoubleClickZoom: this.enableDoubleClickZoom,
draggable: this.draggable,
keyboardShortcuts: this.keyboardShortcuts,
scrollwheel: this.scrollwheel
};
}
/**
* @param {?} bounds
* @return {?}
*/
resetMapBounds(bounds) {
this._map.then(map => {
map.setViewBounds(bounds, this.animateZoom);
});
}
/**
* @param {?} map
* @return {?}
*/
attachEvents(map) {
map.addEventListener('mapviewchangeend', () => {
this.update.emit(map);
});
map.addEventListener('tap', (e) => {
const /** @type {?} */ pointer = e.currentPointer;
const /** @type {?} */ coordinates = map.screenToGeo(pointer.viewportX, pointer.viewportY);
this.clickMap.emit(Object.assign({}, e, { coordinates }));
});
}
/**
* @return {?}
*/
latLngCenter() {
const /** @type {?} */ lat = (/** @type {?} */ (this.center)).lat
? (/** @type {?} */ (this.center)).lat
: (/** @type {?} */ (this.center)).latitude;
const /** @type {?} */ lng = (/** @type {?} */ (this.center)).lng
? (/** @type {?} */ (this.center)).lng
: (/** @type {?} */ (this.center)).longitude;
return { lat, lng };
}
}
MapComponent.counters = 0;
MapComponent.decorators = [
{ type: Component, args: [{
selector: 'heremap',
template: `
<div class="heremap-container" style="width: inherit; height: inherit"></div>
<ng-content></ng-content>
`,
providers: [{ provide: MapUIService, useClass: MapUIService }],
styles: [':host {width: 100%; height: 100%}']
}] }
];
/** @nocollapse */
MapComponent.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Attribute, args: ['name',] },] },
{ type: ElementRef, },
{ type: HereMapsManager, },
];
MapComponent.propDecorators = {
"mapComponents": [{ type: ContentChildren, args: [forwardRef(() => BaseMapComponent), {},] },],
"autoFitMarkers": [{ type: Input },],
"backgroundColor": [{ type: Input },],
"center": [{ type: Input },],
"enableDoubleClickZoom": [{ type: Input },],
"draggable": [{ type: Input },],
"keyboardShortcuts": [{ type: Input },],
"scrollwheel": [{ type: Input },],
"zoom": [{ type: Input },],
"minZoom": [{ type: Input },],
"maxZoom": [{ type: Input },],
"disableDefaultUI": [{ type: Input },],
"mapTypeControl": [{ type: Input },],
"rotateControl": [{ type: Input },],
"scaleControl": [{ type: Input },],
"streetViewControl": [{ type: Input },],
"animateZoom": [{ type: Input },],
"zoomControl": [{ type: Input },],
"update": [{ type: Output },],
"clickMap": [{ type: Output },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Renders directions on heremap. Please note that directive must be placed inside
* map component, otherwise it will never be rendered.
*/
class MapDirectionsDirective extends BaseMapComponent {
/**
* @param {?} _mapsManager
*/
constructor(_mapsManager) {
super();
this._mapsManager = _mapsManager;
/**
* This event is fired when the directions route changes.
*/
this.directions_changed = new EventEmitter();
/**
* By default, the input map is centered and zoomed to the bounding box of this set of directions.
* If this option is set to true, the viewport is left unchanged, unless the map's center and zoom were never set.
*/
this.preserveViewport = true;
this._intermediatePoints = [];
this._mapsManager.onApiLoad().then(() => {
const /** @type {?} */ lineString = new H.geo.LineString([
44.09,
-116.9,
3000,
44.082305,
-116.776059,
2000
]);
const /** @type {?} */ route = new H.map.Polyline(lineString);
this.proxyResolver(route);
});
}
/**
* @param {?} value
* @return {?}
*/
set route(value) {
if (this._route !== value) {
this._route = value;
this.tryShowRoute();
}
}
/**
* @return {?}
*/
get route() {
return this._route;
}
/**
* Origin of directions
* @param {?} value can be google.maps.LatLngLiteral or Coordinates or {latitude: number, longitude: number}
* @return {?}
*/
set origin(value) {
if (this._origin !== value) {
this._origin = value;
this.tryShowRoute();
}
}
/**
* @return {?}
*/
get origin() {
return this._origin;
}
/**
* Destination of directions
* @param {?} value can be google.maps.LatLngLiteral or Coordinates or {latitude: number, longitude: number}
* @return {?}
*/
set destination(value) {
if (this._destination !== value) {
this._destination = value;
this.tryShowRoute();
}
}
/**
* @return {?}
*/
get destination() {
return this._destination;
}
/**
* Destination of directions
* @param {?} value can be google.maps.LatLngLiteral or Coordinates or {latitude: number, longitude: number}
* @return {?}
*/
set intermediatePoints(value) {
if (this._intermediatePoints !== value) {
this._intermediatePoints = value;
this.tryShowRoute();
}
}
/**
* @return {?}
*/
get intermediatePoints() {
return this._intermediatePoints;
}
/**
* @param {?} value
* @return {?}
*/
set lineWidth(value) {
if (this._lineWidth !== value) {
this._lineWidth = value;
this.proxy.then(route => {
let /** @type {?} */ style = route.getStyle();
style = new H.map.SpatialStyle();
style.lineWidth = this._lineWidth;
route.setStyle(style);
});
}
}
/**
* @return {?}
*/
get lineWidth() {
return this._lineWidth;
}
/**
* @param {?} value
* @return {?}
*/
set strokeColor(value) {
if (this._strokeColor !== value) {
this._strokeColor = value;
this.proxy.then(route => {
let /** @type {?} */ style = route.getStyle();
style = new H.map.SpatialStyle();
style.strokeColor = value;
route.setStyle(style);
});
}
}
/**
* @return {?}
*/
get strokeColor() {
return this._strokeColor;
}
/**
* @param {?} value
* @return {?}
*/
set fillColor(value) {
if (this._fillColor !== value) {
this._fillColor = value;
this.proxy.then(route => {
let /** @type {?} */ style = route.getStyle();
style = new H.map.SpatialStyle();
style.fillColor = value;
route.setStyle(style);
});
}
}
/**
* @return {?}
*/
get fillColor() {
return this._fillColor;
}
/**
* @return {?}
*/
hasMapComponent() {
return !!this.mapComponent;
}
/**
* @param {?} component
* @param {?} map
* @param {?} ui
* @return {?}
*/
setMapComponent(component, map, ui) {
this.mapComponent = component;
this.proxy.then((mapObject) => setTimeout(() => {
if (mapObject instanceof H.map.Object) {
map.addObject(mapObject);
}
}, this.delay || 0));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.mapComponent.getMap().then(map => {
this.proxy.then(polyline => {
polyline.dispose();
});
});
}
/**
* @return {?}
*/
tryShowRoute() {
const /** @type {?} */ route = this._route || [];
if (route instanceof Array && route.length > 0) {
this.renderRoute(route);
}
else if (this.origin && this.destination) {
this.renderRoute([]);
this._mapsManager
.getDirections(toLatLng(this.origin), toLatLng(this.destination), this.intermediatePoints || [])
.then(r => {
if (r && r.response && r.response.route) {
const /** @type {?} */ newRoute = r.response.route[0].shape.map(str => {
const /** @type {?} */ parts = str.split(',');
return { lat: parseFloat(parts[0]), lng: parseFloat(parts[1]) };
});
this.renderRoute(newRoute || []);
}
else {
this.renderRoute([]);
}
})
.catch(e => {
this.renderRoute([]);
});
}
else {
this.renderRoute([]);
}
}
/**
* @param {?} route
* @return {?}
*/
renderRoute(route) {
this.proxy.then(polyline => {
if (route instanceof Array && route.length > 0) {
const /** @type {?} */ lineString = new H.geo.LineString([]);
route.forEach(point => {
lineString.pushPoint(toLatLng(point));
});
polyline.setGeometry(lineString);
polyline.setVisibility(route.length > 0);
}
else {
polyline.setVisibility(false);
return;
}
});
}
/**
* @return {?}
*/
bindEvents() {
// this.proxy.then()
// directions.addListener('directions_changed', (e) => this.directions_changed.emit(e));
}
}
MapDirectionsDirective.decorators = [
{ type: Directive, args: [{
selector: 'map-directions',
providers: [
{
provide: BaseMapComponent,
useExisting: forwardRef(() => MapDirectionsDirective)
}
]
},] }
];
/** @nocollapse */
MapDirectionsDirective.ctorParameters = () => [
{ type: HereMapsManager, },
];
MapDirectionsDirective.propDecorators = {
"route": [{ type: Input },],
"origin": [{ type: Input },],
"destination": [{ type: Input },],
"intermediatePoints": [{ type: Input },],
"directions_changed": [{ type: Output },],
"preserveViewport": [{ type: Input },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Holds instance of the heremap marker. Please note that directive must be placed inside
* map component, otherwise it will never be rendered.
*/
class MapMakerDirective extends BaseMapComponent {
/**
* @param {?} _mapsManager
*/
constructor(_mapsManager) {
super();
this._mapsManager = _mapsManager;
/**
* This event is fired when the marker icon was clicked.
*/
this.click = new EventEmitter();
/**
* This event is fired when the marker icon was double clicked.
*/
this.dblclick = new EventEmitter();
/**
* This event is fired for a rightclick on the marker.
*/
this.rightclick = new EventEmitter();
/**
* This event is fired when the marker position property changes.
*/
this.position_changed = new EventEmitter();
/**
* This event is fired when the marker icon property changes.
*/
this.icon_changed = new EventEmitter();
/**
* This event is fired when the marker title property changes.
*/
this.title_changed = new EventEmitter();
/**
* This event is fired when the marker visible property changes.
*/
this.visible_changed = new EventEmitter();
this._clickable = true;
}
/**
* Marker position
* @param {?} point
* @return {?}
*/
set position(point) {
const /** @type {?} */ position = toLatLng(point);
this._mapsManager
.createMarker({ position })
.then((marker) => {
this.bindEvents(marker);
this.proxyResolver(marker);
});
this.proxy.then(marker => {
marker.setPosition(toLatLng(point));
});
}
/**
* If true, the marker receives mouse and touch events.
* Default value is true.
* @param {?} mode
* @return {?}
*/
set clickable(mode) {
// this.proxy.then(marker => marker.setClickable(mode));
this._clickable = mode;
}
/**
* Icon for the foreground. If a string is provided,
* it is treated as though it were an Icon with the string as url.
* @param {?} value
* @return {?}
*/
set icon(value) {
this.proxy.then(marker => {
if (typeof value === 'string') {
value = new H.map.Icon(value, {
size: { w: 20, h: 20 },
crossOrigin: false
});
}
marker.setIcon(value);
});
}
/**
* The marker's opacity between 0.0 and 1.0.
* @param {?} value
* @return {?}
*/
set opacity(value) {
// this.proxy.then(marker => marker.setOpacity(value));
}
/**
* Rollover text
* @param {?} value
* @return {?}
*/
set title(value) {
// this.proxy.then(marker => marker.setTitle(value));
}
/**
* If true, the marker is visible
* @param {?} mode
* @return {?}
*/
set visible(mode) {
this.proxy.then(marker => marker.setVisibility(mode));
}
/**
* Set marker zIndex for displayed on the map
* @param {?} value
* @return {?}
*/
set zIndex(value) {
this.proxy.then(marker => marker.setZIndex(value));
}
/**
* @param {?} value
* @return {?}
*/
set setDelay(value) {
this.delay = value;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.proxy.then(marker => {
marker.dispose();
this.mapComponent.getMap().then(map => {
if (map.getObjects().indexOf(marker) >= 0) {
map.removeObject(marker);
}
});
});
}
/**
* @return {?}
*/
hasMapComponent() {
return !!this.mapComponent;
}
/**
* @param {?} component
* @param {?} map
* @param {?} ui
* @return {?}
*/
setMapComponent(component, map, ui) {
this.mapComponent = component;
this.proxy.then((mapObject) => setTimeout(() => {
if (mapObject instanceof H.map.Object) {
map.addObject(mapObject);
}
}, this.delay || 0));
}
/**
* @param {?} marker
* @return {?}
*/
bindEvents(marker) {
marker.addEventListener('tap', e => {
if (this._clickable) {
this.click.emit(e);
}
});
marker.addEventListener('dbltap', e => {
if (this._clickable) {
this.dblclick.emit(e);
}
});
// marker.addEventListener('position_changed', e => this.position_changed.emit(e));
// marker.addEventListener('title_changed', e => this.title_changed.emit(e));
// marker.addEventListener('icon_changed', e => this.icon_changed.emit(e));
marker.addEventListener('visibilitychange', e => this.visible_changed.emit(e));
}
}
MapMakerDirective.decorators = [
{ type: Directive, args: [{
selector: 'map-marker',
providers: [
{
provide: BaseMapComponent,
useExisting: forwardRef(() => MapMakerDirective)
}
]
},] }
];
/** @nocollapse */
MapMakerDirective.ctorParameters = () => [
{ type: HereMapsManager, },
];
MapMakerDirective.propDecorators = {
"click": [{ type: Output },],
"dblclick": [{ type: Output },],
"rightclick": [{ type: Output },],
"position_changed": [{ type: Output },],
"icon_changed": [{ type: Output },],
"title_changed": [{ type: Output },],
"visible_changed": [{ type: Output },],
"position": [{ type: Input },],
"clickable": [{ type: Input },],
"icon": [{ type: Input },],
"opacity": [{ type: Input },],
"title": [{ type: Input },],
"visible": [{ type: Input },],
"zIndex": [{ type: Input },],
"setDelay": [{ type: Input, args: ['delay',] },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Directive that will render plyline to map. Please note that directive must be placed inside
* map component, otherwise it will never render polyline.
*/
class MapPolylineDirective extends BaseMapComponent {
/**
* @param {?} mapsManager
*/
constructor(mapsManager) {
super();
this._lineWidth = 4;
mapsManager
.onApiLoad()
.then(() => {
const /** @type {?} */ strip = new H.geo.Strip();
this.polyline = new H.map.Polyline(strip);
this.proxyResolver(this.polyline);
});
}
/**
* Fill color that should be used when polyline is rendered on map
* @return {?}
*/
get fillColor() {
return this._fillColor;
}
/**
* @param {?} color
* @return {?}
*/
set fillColor(color) {
if (this._fillColor !== color) {
this._fillColor = color;
this.proxy.then(p => {
const /** @type {?} */ style = Object.assign({}, p.getStyle());
style.fillColor = color;
p.setStyle(style);
});
}
}
/**
* Stroke color that should be used when polyline is rendered on map
* @return {?}
*/
get strokeColor() {
return this._strokeColor;
}
/**
* @param {?} color
* @return {?}
*/
set strokeColor(color) {
if (this._strokeColor !== color) {
this._strokeColor = color;
this.proxy.then(p => {
const /** @type {?} */ style = Object.assign({}, p.getStyle());
style.strokeColor = color;
p.setStyle(style);
});
}
}
/**
* Gives plyline with
* @return {?}
*/
get lineWidth() {
return this._lineWidth;
}
/**
* @param {?} lineWidth
* @return {?}
*/
set lineWidth(lineWidth) {
if (this._lineWidth !== lineWidth) {
this._lineWidth = lineWidth;
this.proxy.then(p => {
const /** @type {?} */ style = Object.assign({}, p.getStyle());
style.lineWidth = lineWidth;
p.setStyle(style);
});
}
}
/**
* @param {?} opts
* @return {?}
*/
set options(opts) {
this.proxy.then((polyline) => {
const /** @type {?} */ style = {
strokeColor: opts.strokeColor || this.strokeColor,
fillColor: opts.fillColor || this.fillColor,
lineWidth: opts.lineWidth || this.lineWidth
}, /** @type {?} */
strip = new H.geo.Strip();
(opts.path || [])
.forEach(point => {
strip.pushPoint({
lat: point.lat,
lng: point.lng
});
});
polyline.setStrip(strip);
polyline.setStyle(style);
});
}
/**
* Checks if map is set to directive
* @return {?}
*/
hasMapComponent() {
return !!this.mapComponent;
}
/**
* Sets heremap to polyline. This is called by map component so you don't need to call it manually.
* @param {?} component map component
* @param {?} map here map instance
* @return {?}
*/
setMapComponent(component, map) {
this.mapComponent = component;
this.proxy
.then((mapObject) => setTimeout(() => {
if (mapObject instanceof H.map.Object) {
map.addObject(mapObject);
}
}, this.delay || 0));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.proxy
.then(p => {
this.mapComponent
.getMap()
.then((map) => {
map.removeObject(this.polyline);
this.polyline.dispose();
delete this.polyline;
});
});
}
}
MapPolylineDirective.decorators = [
{ type: Directive, args: [{
selector: 'map-polyline',
providers: [{ provide: BaseMapComponent, useExisting: forwardRef(() => MapPolylineDirective) }]
},] }
];
/** @nocollapse */
MapPolylineDirective.ctorParameters = () => [
{ type: HereMapsManager, },
];
MapPolylineDirective.propDecorators = {
"fillColor": [{ type: Input },],
"strokeColor": [{ type: Input },],
"lineWidth": [{ type: Input },],
"options": [{ type: Input },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class NoopMapsApiLoader {
constructor() {
this.platformReady = new Promise((resolve, reject) => {
this._rejectPlatform = reject;
this._resolvePlatform = resolve;
});
}
/**
* @return {?}
*/
load() {
if (!(H && H.service && H.service.Platform)) {
return Promise.reject(new Error('Here Maps API not loaded on page. Make sure window.H.service.Platform is available!'));
}
else {
return Promise.resolve();
}
}
}
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* The following list shows the approximate level of detail
* you can expect to see at each zoom level
*/
const /** @type {?} */ ZoomLevel = {
World: 1,
Continent: 5,
City: 10,
Streets: 15,
Buildings: 20
};
/**
* Animations that can be played on a marker.
* @see https://developers.google.com/maps/documentation/javascript/reference?hl=ru#Animation
*/
const /** @type {?} */ Animation = {
/**
* Marker bounces until animation is stopped.
*/
BOUNCE: 1,
/**
* Marker falls from the top of the map ending with a small bounce.
*/
DROP: 2
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* Renders buble on map. Please note that directive must be placed inside
* map component, otherwise it will never be rendered.
*/
class MapBubbleDirective extends BaseMapComponent {
/**
* @param {?} _mapsManager
*/
constructor(_mapsManager) {
super();
this._mapsManager = _mapsManager;
/**
* This event is fired when the marker icon was clicked.
*/
this.click = new EventEmitter();
this._clickable = true;
}
/**
* Bubble position
* @param {?} point
* @return {?}
*/
set position(point) {
const /** @type {?} */ position = toLatLng(point);
this._mapsManager
.createBubble({ position })
.then((bubble) => {
this.bindEvents(bubble);
this.proxyResolver(bubble);
});
this.proxy.then(bubble => {
bubble.setPosition(toLatLng(point));
});
}
/**
* If true, the marker receives mouse and touch events.
* Default value is true.
* @param {?} mode
* @return {?}
*/
set clickable(mode) {
// this.proxy.then(marker => marker.setClickable(mode));
this._clickable = mode;
}
/**
* Rollover text
* @param {?} value
* @return {?}
*/
set contentElement(value) {
this.proxy.then(bubble => bubble.setContent(value));
}
/**
* @return {?}
*/
hasMapComponent() {
return !!this.mapComponent;
}
/**
* @param {?} component
* @param {?} map
* @param {?} ui
* @return {?}
*/
setMapComponent(component, map, ui) {
this.mapComponent = component;
this.proxy.then((mapObject) => setTimeout(() => {
if (mapObject instanceof H.ui.InfoBubble) {
ui.addBubble(mapObject);
}
}, this.delay || 0));
}
/**
* @param {?} marker
* @return {?}
*/
bindEvents(marker) {
marker.addEventListener('tap', e => {
if (this._clickable) {
this.click.emit(e);
}
});
}
}
MapBubbleDirective.decorators = [
{ type: Directive, args: [{
selector: 'map-bubble',
providers: [
{
provide: BaseMapComponent,
useExisting: forwardRef(() => MapBubbleDirective)
}
]
},] }
];
/** @nocollapse */
MapBubbleDirective.ctorParameters = () => [
{ type: HereMapsManager, },
];
MapBubbleDirective.propDecorators = {
"click": [{ type: Output },],
"position": [{ type: Input },],
"clickable": [{ type: Input },],
"contentElement": [{ type: Input },],
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
class HereMapsModule {
/**
* Used to register in top level or shared module in your application. Loader Options are mandatory.
* {\@expample
* import {NgModule} from '\@angular/core';
*
* \@NgModule({
* declarations: [...],
* imports: [
* ...
* HereMapsModule.forRoot(<LoaderOptions>{
* apiKey: "your heremaps API key
* libraries: ["places", "geometry"]
* }),
* ...
* ],
* // optional, you can import module like below if your module depends only on component and directives
* exports: [
* HereMapsModule
* ]
* })
* export class MySharedModule { }
* }
*
* @param {?} loaderOptions
* @return {?}
*/
static forRoot(loaderOptions) {
return {
ngModule: HereMapsModule,
providers: [
{
provide: LAZY_LOADER_OPTIONS,
useValue: loaderOptions
},
LazyMapsApiLoader,
HereMapsManager
]
};
}
}
HereMapsModule.decorators = [
{ type: NgModule, args: [{
declarations: [
MapComponent,
MapDirectionsDirective,
MapMakerDirective,
MapPolylineDirective,
MapBubbleDirective
],
exports: [
MapComponent,
MapDirectionsDirective,
MapMakerDirective,
MapPolylineDirective,
MapBubbleDirective
]
},] }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
// This file only reexports content of the `src` folder. Keep it that way.
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
export { BaseMapComponent, MapComponent, MapDirectionsDirective, MapMakerDirective, MapPolylineDirective, BaseMapsApiLoader, LAZY_LOADER_OPTIONS, LazyMapsApiLoader, HereMapsManager, NoopMapsApiLoader, Animation, ZoomLevel, MapUIService, HereMapsModule, MapBubbleDirective as ɵa };
//# sourceMappingURL=ng2-heremaps.js.map