// Angular // import { Injectable } from '@angular/core'; import { downgradeInjectable } from '@angular/upgrade/static'; declare const angular: angular.IAngularStatic; // Component // import { IMapElement, IMapOptions, ICoordinateSet } from './fb-google-maps.interface'; // Other // import * as statics from '@fb/statics'; // Services // import { TranslateService } from '@ngx-translate/core'; @Injectable() export class FbGoogleMapsService { private mapElementList: IMapElement[] = []; private maxNumberOfInstances: number = 3; private mapInitOptions: google.maps.MapOptions; // Todo create interface constructor(private readonly translateService: TranslateService) { this.setupMapOptions(); } private setupMapOptions(): void { this.mapInitOptions = { zoom: 12, streetViewControl: false, disableDefaultUI: false, draggable: true }; } getMapElement(centerCoordinates: ICoordinateSet, storlek: 'stor' | 'liten' = 'stor'): IMapElement { let availableMapElementInstance: IMapElement = this.mapElementList.find(x => !x.isInUse && x.storlek === storlek); if (statics.isUndefined(availableMapElementInstance)) { availableMapElementInstance = this.createNewMapsInstance(centerCoordinates, storlek); } availableMapElementInstance.isInUse = true; return availableMapElementInstance; } onMapResize(mapElement: IMapElement): void { google.maps.event.trigger(mapElement.mapsInstance, 'resize'); } setOptions(mapInstance: google.maps.Map, mapOptions: IMapOptions): void { const googleMapOptions: google.maps.MapOptions = { disableDefaultUI: mapOptions.disableDefaultUI, center: this.getLatLng(mapOptions.centerCoordinates) }; mapInstance.setOptions(googleMapOptions); } createMapMarker(mapElement: IMapElement, markerCoordinates: ICoordinateSet): void { const position: google.maps.LatLng = this.getLatLng(markerCoordinates); if (statics.isUndefined(mapElement.mapMarkerInstance)) { mapElement.mapMarkerInstance = new google.maps.Marker({ position: position, map: mapElement.mapsInstance, draggable: true, title: this.translateService.instant('KARTA.DRA_AENDRA_POSITION') }); } else { this.updateMapMarker(mapElement, markerCoordinates); } } updateMapMarker(mapElement: IMapElement, markerCoordinates: ICoordinateSet): void { const position: google.maps.LatLng = this.getLatLng(markerCoordinates); mapElement.mapMarkerInstance.setMap(mapElement.mapsInstance); mapElement.mapMarkerInstance.setPosition(position); } destroyMapMarker(mapElement: IMapElement): void { if (statics.isDefined(mapElement.mapMarkerInstance)) { mapElement.mapMarkerInstance.setMap(null); } } createDrawingManager(mapElement: IMapElement): void { if (statics.isUndefined(mapElement.drawingManagerInstance)) { mapElement.drawingManagerInstance = new google.maps.drawing.DrawingManager({ map: mapElement.mapsInstance, drawingControl: true, drawingControlOptions: { position: google.maps.ControlPosition.TOP_LEFT, drawingModes: [ google.maps.drawing.OverlayType.POLYGON ] }, polygonOptions: { fillColor: '#0097ed', strokeColor: '#0097ed' } }); } } destroyDrawingManager(mapElement: IMapElement): void { if (statics.isDefined(mapElement.drawingManagerInstance)) { mapElement.drawingManagerInstance.setMap(null); } } isValidCoordinates(coordinates: ICoordinateSet): boolean { return statics.isDefined(coordinates) && statics.isDefined(coordinates.Longitud) && statics.isDefined(coordinates.Longitud.value) && statics.isDefined(coordinates.Latitud) && statics.isDefined(coordinates.Latitud.value); } isValidCoordinatesAsLatLgn(coordinates: ICoordinateSet): boolean { return statics.isDefined(coordinates) && statics.isDefined(coordinates.Longitud) && statics.isDefined(coordinates.Latitud); } isGoogleMapsApiLoaded(): boolean { return typeof google !== 'undefined'; } getLatLng(coordinates: ICoordinateSet): google.maps.LatLng { return new google.maps.LatLng(coordinates.Latitud.value, coordinates.Longitud.value); } private createNewMapsInstance(centerCoordinates: ICoordinateSet, storlek: 'stor' | 'liten'): IMapElement { if (this.mapElementList.length >= this.maxNumberOfInstances) { throw new Error('Google maps is trying to create more instances than allowed by the application.'); } const mapElement: IMapElement = this.createNewMapElement(storlek); this.mapInitOptions.center = { lat: centerCoordinates.Latitud.value, lng: centerCoordinates.Longitud.value }; mapElement.mapsInstance = new google.maps.Map(mapElement.element, this.mapInitOptions); this.onMapResize(mapElement); this.mapElementList.push(mapElement); return mapElement; } private createNewMapElement(storlek: 'stor' | 'liten'): IMapElement { const elem: HTMLDivElement = (document.createElement('div')); const mapElement: IMapElement = { storlek, isInUse: false, element: elem, mapsInstance: undefined, mapMarkerInstance: undefined, drawingManagerInstance: undefined }; return mapElement; } } angular.module('fasit') .factory('fbGoogleMapsService', downgradeInjectable(FbGoogleMapsService));