UNPKG

@ng-maps/google

Version:

**@ng-maps/google** is a simple, modular and tree-shakable library for displaying google-maps inside an angular application

1,062 lines (1,045 loc) 41 kB
import * as i0 from '@angular/core'; import { Injectable, Component, InjectionToken, Optional, Inject, NgModule } from '@angular/core'; import { Observable, ReplaySubject, firstValueFrom } from 'rxjs'; import * as i1 from '@ng-maps/core'; import { MapsApiWrapper, MarkerManager, CircleManager, PolygonManager, PolylineManager, RectangleManager, InfoWindowManager, FitBoundsService, NgMapsViewComponent, MapsAPILoader, MAP_PROVIDER } from '@ng-maps/core'; import { DOCUMENT } from '@angular/common'; /** * Wrapper class that handles the communication with the Google Maps Javascript * API v3 */ class GoogleMapsAPIWrapper extends MapsApiWrapper { constructor(_loader, _zone) { super(_loader, _zone); } createMap(el, center, options) { return this._zone.runOutsideAngular(async () => { await this._loader.load(); if (this._mapResolver) { this._mapResolver(new google.maps.Map(el, { center, ...options })); } return; }); } async setMapOptions(options) { const map = await this._api; map?.setOptions(options); } /** * Creates a google map drawing manager with the map context */ async createDrawingManager(options = {}, addToMap = true) { const map = await this._api; if (addToMap) { options.map = map; } return new google.maps.drawing.DrawingManager(options); } /** * Creates a google map marker with the map context */ async createMarker(position, options, addToMap = true) { const map = addToMap ? await this._api : null; return new google.maps.Marker({ position, map, ...options }); } async createInfoWindow(position, options) { await this._api; if (position === null) { return new google.maps.InfoWindow({ ...options }); } else { return new google.maps.InfoWindow({ position: position, ...options }); } } /** * Creates a google.map.Circle for the current map. * * @todo check how to improve type casting */ async createCircle(center, options) { const opt = { ...options, center, map: await this._api, }; if (typeof opt.strokePosition === 'string') { opt.strokePosition = google.maps.StrokePosition[opt.strokePosition]; } return new google.maps.Circle(opt); } /** * Creates a google.map.Rectangle for the current map. */ async createRectangle(bounds, options) { const map = await this._api; return new google.maps.Rectangle({ ...options, bounds, map, }); } async createPolyline(options) { return this.getNativeMap().then((map) => { const line = new google.maps.Polyline(options); if (map) { line.setMap(map); } return line; }); } createPolygon(options) { return this.getNativeMap().then((map) => { const polygon = new google.maps.Polygon(options); if (map) { polygon.setMap(map); } return polygon; }); } /** * Creates a new google.map.Data layer for the current map */ async createDataLayer(options) { return this._api?.then((m) => { const data = new google.maps.Data(options); data.setMap(m); return data; }); } /** * Determines if given coordinates are insite a Polygon path. */ containsLocation(latLng, polygon) { return google.maps.geometry.poly.containsLocation(latLng, polygon); } /** * @fixme typings */ subscribeToMapEvent(eventName) { return new Observable((observer) => { this._api?.then((m) => m.addListener(eventName, (...evArgs) => this._zone.run(() => observer.next(evArgs)))); }); } clearInstanceListeners() { this._api?.then((map) => { google.maps.event.clearInstanceListeners(map); }); } async setCenter(latLng) { return this._api?.then((map) => map.setCenter(latLng)); } async getZoom() { const map = await this._api; return map?.getZoom(); } async getBounds() { const map = await this._api; return map?.getBounds()?.toJSON(); } async getMapTypeId() { return this._api?.then((map) => map.getMapTypeId()); } async setZoom(zoom) { this._api?.then((map) => map.setZoom(zoom)); } async getCenter() { const map = await this._api; return map?.getCenter()?.toJSON(); } async panTo(latLng) { this._api?.then((map) => map.panTo(latLng)); } async panBy(x, y) { this._api?.then((map) => map.panBy(x, y)); } async fitBounds(latLng, padding) { const map = await this._api; map?.fitBounds(latLng, padding); } async panToBounds(latLng, padding) { const map = await this._api; return map?.panToBounds(latLng, padding); } /** * Triggers the given event name on the map instance. */ async triggerMapEvent(eventName) { const map = await this._api; if (map) { google.maps.event.trigger(map, eventName); } } _isLatLngBoundsLiteral(bounds) { return bounds != null && bounds.extend === undefined; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsAPIWrapper, deps: [{ token: i1.MapsAPILoader }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsAPIWrapper }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsAPIWrapper, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsAPILoader }, { type: i0.NgZone }] }); function isValidMarkerIcon(marker) { if (marker === null) { return true; } else if (typeof marker === 'string') { return true; } else if (typeof marker === 'object' && Object.hasOwn(marker, 'url')) { return true; } else if (typeof marker === 'object' && Object.hasOwn(marker, 'path')) { return true; } else { return false; } } class GoogleMapsMarkerManager extends MarkerManager { constructor(_mapsWrapper, _zone) { super(_mapsWrapper, _zone); this._markers = new Map(); } deleteMarker(marker) { const m = this._markers.get(marker); if (m == null) { // marker already deleted return; } else { return this._zone.run(() => { m.setMap(null); this._markers.delete(marker); }); } } updateMarkerPosition(marker) { if (typeof marker.latitude !== 'number' || typeof marker.longitude !== 'number') { return; } const m = this._markers.get(marker); m?.setPosition({ lat: marker.latitude, lng: marker.longitude }); } updateTitle(marker) { const m = this._markers.get(marker); m?.setTitle(marker.title); } updateLabel(marker) { const m = this._markers.get(marker); m?.setLabel(marker.label); } updateDraggable(marker) { const m = this._markers.get(marker); m?.setDraggable(marker.draggable); } updateIconLegacy(marker) { const m = this._markers.get(marker); m?.setIcon(marker.iconUrl); } updateOpacity(marker) { const m = this._markers.get(marker); m?.setOpacity(marker.opacity); } updateVisible(marker) { const m = this._markers.get(marker); m?.setVisible(marker.visible); } updateZIndex(marker) { const m = this._markers.get(marker); m?.setZIndex(marker.zIndex); } updateClickable(marker) { const m = this._markers.get(marker); m?.setClickable(marker.clickable); } updateAnimation(marker) { const m = this._markers.get(marker); if (typeof marker.animation === 'string') { m?.setAnimation(google.maps.Animation[marker.animation]); } else { m?.setAnimation(marker.animation); } } createEventObservable(eventName, marker) { return new Observable((observer) => { const m = this._markers.get(marker); if (typeof eventName === 'string') { eventName = [eventName]; } eventName.forEach((event) => { m?.addListener(event, (e) => this._zone.run(() => observer.next(e))); }); }); } updateIcon(marker) { const m = this._markers.get(marker); if (m && isValidMarkerIcon(marker.icon)) { m.setIcon(marker.icon); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsMarkerManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsMarkerManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsMarkerManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }] }); class GoogleCircleManager extends CircleManager { constructor(_mapsWrapper, _zone) { super(_mapsWrapper, _zone); } /** * @fixme implement commented properties */ async addCircle(circle) { if (!circle.latitude || !circle.longitude) { return; } this._circles.set(circle, this._apiWrapper.createCircle({ lat: circle.latitude, lng: circle.longitude }, { // clickable: circle.clickable, // draggable: circle.draggable, // editable: circle.editable, fillColor: circle.fillColor, fillOpacity: circle.fillOpacity, radius: circle.radius, strokeColor: circle.strokeColor, strokeOpacity: circle.strokeOpacity, // strokePosition: circle.strokePosition, strokeWeight: circle.strokeWeight, visible: circle.visible, zIndex: circle.zIndex, })); } /** * Removes the given circle from the map. */ async removeCircle(circle) { const c = await this._circles.get(circle); c?.setMap(null); this._circles.delete(circle); } /** * @todo check how to improve type casting * @param circle instance of {@link NgMapsCircleDirective} * @param options options for the circle */ async setOptions(circle, options) { const c = await this._circles.get(circle); if (typeof options.strokePosition === 'string') { options.strokePosition = google.maps.StrokePosition[options.strokePosition]; } return c?.setOptions(options); } async getBounds(circle) { const c = await this._circles.get(circle); if (!c) { return null; } const bounds = c.getBounds(); return bounds ? bounds.toJSON() : null; } async getCenter(circle) { const c = await this._circles.get(circle); const center = c?.getCenter(); return center ? center.toJSON() : null; } async getRadius(circle) { const c = await this._circles.get(circle); return c?.getRadius() ?? null; } async setCenter(circle) { if (!circle.latitude || !circle.longitude) { return; } const c = await this._circles.get(circle); c?.setCenter({ lat: circle.latitude, lng: circle.longitude }); } async setEditable(circle) { const c = await this._circles.get(circle); c?.setEditable(circle.editable); } async setDraggable(circle) { const c = await this._circles.get(circle); c?.setDraggable(circle.draggable); } async setVisible(circle) { const c = await this._circles.get(circle); c?.setVisible(circle.visible); } async setRadius(circle) { const c = await this._circles.get(circle); c?.setRadius(circle.radius); } createEventObservable(eventName, circle) { return new Observable((observer) => { let listener = null; this._circles?.get(circle)?.then((c) => { listener = c.addListener(eventName, (e) => this._zone.run(() => observer.next(e))); }); return () => { if (listener !== null) { listener.remove(); } }; }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleCircleManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleCircleManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleCircleManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }] }); class GooglePolygonManager extends PolygonManager { constructor(_mapsWrapper, _zone) { super(_mapsWrapper, _zone); } addPolygon(path) { const polygonPromise = this._mapsWrapper.createPolygon({ clickable: path.clickable, draggable: path.draggable, editable: path.editable, fillColor: path.fillColor, fillOpacity: path.fillOpacity, geodesic: path.geodesic, paths: path.paths, strokeColor: path.strokeColor, strokeOpacity: path.strokeOpacity, strokeWeight: path.strokeWeight, visible: path.visible, zIndex: path.zIndex, }); this._polygons.set(path, polygonPromise); } async updatePolygon(polygon) { const item = await this._polygons.get(polygon); if (item != null) { this._zone.run(() => { item.setPaths(polygon.paths); }); } } async setPolygonOptions(path, options) { const l = await this._polygons.get(path); l?.setOptions(options); } deletePolygon(paths) { const m = this._polygons.get(paths); if (m == null) { return Promise.resolve(); } return m.then((l) => this._zone.run(() => { l.setMap(null); this._polygons.delete(paths); })); } createEventObservable(eventName, path) { return new Observable((observer) => { this._polygons.get(path)?.then((l) => { l.addListener(eventName, (e) => this._zone.run(() => observer.next(e))); }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolygonManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolygonManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolygonManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }] }); class GooglePolylineManager extends PolylineManager { constructor(_mapsWrapper, _zone) { super(_mapsWrapper, _zone); } _convertPoints(line) { return line._getPoints().map((point) => ({ lat: point.latitude, lng: point.longitude, })); } addPolyline(line) { const path = this._convertPoints(line); const polylinePromise = this._mapsWrapper.createPolyline({ clickable: line.clickable, draggable: line.draggable, editable: line.editable, geodesic: line.geodesic, strokeColor: line.strokeColor, strokeOpacity: line.strokeOpacity, strokeWeight: line.strokeWeight, visible: line.visible, zIndex: line.zIndex, icons: line.icons, path, }); this._polylines.set(line, polylinePromise); } updatePolylinePoints(line) { const path = this._convertPoints(line); const m = this._polylines.get(line); if (m == null) { return Promise.resolve(); } return m.then((l) => this._zone.run(() => { l.setPath(path); })); } async setPolylineOptions(line, options) { const l = await this._polylines.get(line); l?.setOptions(options); } deletePolyline(line) { const m = this._polylines.get(line); if (m == null) { return Promise.resolve(); } return m.then((l) => this._zone.run(() => { l.setMap(null); this._polylines.delete(line); })); } createEventObservable(eventName, line) { return new Observable((observer) => { this._polylines.get(line)?.then((l) => { l.addListener(eventName, (e) => this._zone.run(() => observer.next(e))); }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolylineManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolylineManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GooglePolylineManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }] }); class GoogleRectangleManager extends RectangleManager { constructor(_mapsWrapper, _zone) { super(_mapsWrapper, _zone); } addRectangle(rectangle) { if (!rectangle.north || !rectangle.east || !rectangle.south || !rectangle.west) { return; } this._rectangles.set(rectangle, this._apiWrapper.createRectangle({ north: rectangle.north, east: rectangle.east, south: rectangle.south, west: rectangle.west, }, { // clickable: rectangle.clickable, // draggable: rectangle.draggable, // editable: rectangle.editable, fillColor: rectangle.fillColor, fillOpacity: rectangle.fillOpacity, strokeColor: rectangle.strokeColor, strokeOpacity: rectangle.strokeOpacity, // strokePosition: rectangle.strokePosition, strokeWeight: rectangle.strokeWeight, visible: rectangle.visible, zIndex: rectangle.zIndex, })); } /** * Removes the given rectangle from the map. */ async removeRectangle(rectangle) { return this._rectangles.get(rectangle)?.then((r) => { r.setMap(null); this._rectangles.delete(rectangle); }); } async setOptions(rectangle, options) { return this._rectangles.get(rectangle)?.then((r) => r.setOptions(options)); } async getBounds(rectangle) { const r = await this._rectangles.get(rectangle); const bounds = r?.getBounds(); return bounds ? bounds.toJSON() : null; } async setBounds(rectangle) { if (!rectangle.north || !rectangle.east || !rectangle.south || !rectangle.west) { return; } const r = await this._rectangles.get(rectangle); r?.setBounds({ north: rectangle.north, east: rectangle.east, south: rectangle.south, west: rectangle.west, }); } async setEditable(rectangle) { return this._rectangles .get(rectangle) ?.then((r) => r.setEditable(rectangle.editable)); } async setDraggable(rectangle) { return this._rectangles .get(rectangle) ?.then((r) => r.setDraggable(rectangle.draggable)); } async setVisible(rectangle) { return this._rectangles .get(rectangle) ?.then((r) => r.setVisible(rectangle.visible)); } createEventObservable(eventName, rectangle) { return new Observable((observer) => { let listener = null; this._rectangles.get(rectangle)?.then((r) => { listener = r.addListener(eventName, (e) => this._zone.run(() => observer.next(e))); }); return () => { if (listener !== null) { listener.remove(); } }; }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleRectangleManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleRectangleManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleRectangleManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }] }); class GoogleInfoWindowManager extends InfoWindowManager { constructor(_mapsWrapper, _zone, _markerManager) { super(_mapsWrapper, _zone, _markerManager); } async deleteInfoWindow(infoWindow) { const iWindow = await this._infoWindows.get(infoWindow); if (iWindow == null) { // info window already deleted return; } else { return this._zone.run(() => { iWindow.close(); this._infoWindows.delete(infoWindow); }); } } setPosition(infoWindow) { if (!infoWindow.latitude || !infoWindow.longitude) { return; } const i = this._infoWindows.get(infoWindow); i?.setPosition({ lat: infoWindow.latitude, lng: infoWindow.longitude, }); } setZIndex(infoWindow) { if (!infoWindow.zIndex) { return; } const i = this._infoWindows.get(infoWindow); i?.setZIndex(infoWindow.zIndex); } async open(infoWindow) { const w = this._infoWindows.get(infoWindow); const map = await this._mapsWrapper.getNativeMap(); if (infoWindow.hostMarker != null) { const marker = await this._markerManager.getNativeMarker(infoWindow.hostMarker); w?.open(map, marker); } else { w?.open(map); } } close(infoWindow) { const w = this._infoWindows.get(infoWindow); w?.close(); } setOptions(infoWindow, options) { const i = this._infoWindows.get(infoWindow); i?.setOptions(options); } async addInfoWindow(infoWindow) { const options = { content: infoWindow.content?.nativeElement, maxWidth: infoWindow.maxWidth, zIndex: infoWindow.zIndex, disableAutoPan: infoWindow.disableAutoPan, }; const center = typeof infoWindow.latitude === 'number' && typeof infoWindow.longitude === 'number' ? { lat: infoWindow.latitude, lng: infoWindow.longitude, } : null; const instance = await this._mapsWrapper.createInfoWindow(center, options); this._infoWindows.set(infoWindow, instance); } /** * Creates a Google Maps event listener for the given InfoWindow as an Observable */ createEventObservable(eventName, infoWindow) { const i = this._infoWindows.get(infoWindow); return new Observable((observer) => { i?.addListener(eventName, (e) => this._zone.run(() => observer.next(e))); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleInfoWindowManager, deps: [{ token: i1.MapsApiWrapper }, { token: i0.NgZone }, { token: i1.MarkerManager }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleInfoWindowManager }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleInfoWindowManager, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i0.NgZone }, { type: i1.MarkerManager }] }); /** * The FitBoundsService is responsible for computing the bounds of the a single map. */ class GoogleMapsFitBoundsService extends FitBoundsService { constructor(_loader) { super(_loader); } generateBounds(includeInBounds) { if (includeInBounds.size === 0) { return new google.maps.LatLngBounds().toJSON(); } else { const bounds = new google.maps.LatLngBounds(); includeInBounds.forEach((b) => bounds.extend(b)); return bounds.toJSON(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsFitBoundsService, deps: [{ token: i1.MapsAPILoader }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsFitBoundsService }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsFitBoundsService, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: i1.MapsAPILoader }] }); class GoogleComponent extends NgMapsViewComponent { constructor(_mapsWrapper, _fitBoundsService, _zone) { super(_mapsWrapper, _fitBoundsService, _zone); } async _handleMapCenterChange() { const s = this._mapsWrapper .subscribeToMapEvent('center_changed') .subscribe(() => { this._mapsWrapper.getCenter().then((center) => { if (center) { this.latitude = center.lat; this.longitude = center.lng; this.centerChange.emit({ lat: this.latitude, lng: this.longitude, }); } }); }); this.subscription.add(s); } _handleBoundsChange() { const s = this._mapsWrapper .subscribeToMapEvent('bounds_changed') .subscribe(() => { this._mapsWrapper.getBounds().then((bounds) => { this.boundsChange.emit(bounds); }); }); this.subscription.add(s); } async _handleMapTypeIdChange() { const s = this._mapsWrapper .subscribeToMapEvent('maptypeid_changed') .subscribe(() => { this._mapsWrapper.getMapTypeId().then((mapTypeId) => { this.mapTypeIdChange.emit(mapTypeId); }); }); this.subscription.add(s); } _handleMapZoomChange() { const s = this._mapsWrapper .subscribeToMapEvent('zoom_changed') .subscribe(() => { this._mapsWrapper.getZoom().then((z) => { this.zoom = z ?? 8; this.zoomChange.emit(z); }); }); this.subscription.add(s); } _handleIdleEvent() { const s = this._mapsWrapper.subscribeToMapEvent('idle').subscribe(() => { this.idle.emit(void 0); }); this.subscription.add(s); } _handleTilesLoadedEvent() { const s = this._mapsWrapper .subscribeToMapEvent('tilesloaded') .subscribe(() => this.tilesLoaded.emit(void 0)); this.subscription.add(s); } _handleMapMouseEvents() { const events = [ { name: 'click', emitter: this.mapClick }, { name: 'rightclick', emitter: this.mapRightClick }, { name: 'dblclick', emitter: this.mapDblClick }, ]; events.forEach((e) => { const s = this._mapsWrapper .subscribeToMapEvent(e.name) .subscribe((event) => { const value = { coords: { lat: event[0].latLng.lat(), lng: event[0].latLng.lng() }, }; e.emitter.emit(value); }); this.subscription.add(s); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleComponent, deps: [{ token: i1.MapsApiWrapper }, { token: i1.FitBoundsService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: GoogleComponent, selector: "map-view", providers: [ { provide: MapsApiWrapper, useClass: GoogleMapsAPIWrapper }, { provide: FitBoundsService, useClass: GoogleMapsFitBoundsService }, { provide: MarkerManager, useClass: GoogleMapsMarkerManager }, { provide: CircleManager, useClass: GoogleCircleManager }, { provide: PolygonManager, useClass: GooglePolygonManager }, { provide: PolylineManager, useClass: GooglePolylineManager }, { provide: RectangleManager, useClass: GoogleRectangleManager }, { provide: InfoWindowManager, useClass: GoogleInfoWindowManager }, ], usesInheritance: true, ngImport: i0, template: ` <div class="map-container-inner" #container></div> <div class="map-content"> <ng-content></ng-content> </div> `, isInline: true, styles: [".map-container-inner{width:inherit;height:inherit}.map-content{display:none}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleComponent, decorators: [{ type: Component, args: [{ selector: 'map-view', providers: [ { provide: MapsApiWrapper, useClass: GoogleMapsAPIWrapper }, { provide: FitBoundsService, useClass: GoogleMapsFitBoundsService }, { provide: MarkerManager, useClass: GoogleMapsMarkerManager }, { provide: CircleManager, useClass: GoogleCircleManager }, { provide: PolygonManager, useClass: GooglePolygonManager }, { provide: PolylineManager, useClass: GooglePolylineManager }, { provide: RectangleManager, useClass: GoogleRectangleManager }, { provide: InfoWindowManager, useClass: GoogleInfoWindowManager }, ], template: ` <div class="map-container-inner" #container></div> <div class="map-content"> <ng-content></ng-content> </div> `, styles: [".map-container-inner{width:inherit;height:inherit}.map-content{display:none}\n"] }] }], ctorParameters: () => [{ type: i1.MapsApiWrapper }, { type: i1.FitBoundsService }, { type: i0.NgZone }] }); var GoogleMapsScriptProtocol; (function (GoogleMapsScriptProtocol) { GoogleMapsScriptProtocol[GoogleMapsScriptProtocol["HTTP"] = 1] = "HTTP"; GoogleMapsScriptProtocol[GoogleMapsScriptProtocol["HTTPS"] = 2] = "HTTPS"; GoogleMapsScriptProtocol[GoogleMapsScriptProtocol["AUTO"] = 3] = "AUTO"; })(GoogleMapsScriptProtocol || (GoogleMapsScriptProtocol = {})); /** * Token for the config of google maps module * Please provide an object of type {@link GoogleModuleOptions}. */ const GOOGLE_MAPS_API_CONFIG = new InjectionToken('angular-google-maps GOOGLE_MAPS_API_CONFIG'); class GoogleMapsScriptLoader extends MapsAPILoader { constructor(config, document) { super(); this._config = new ReplaySubject(1); this._SCRIPT_ID = 'GoogleMapsApiScript'; this.callbackName = `LazyMapsAPILoader`; if (config instanceof Promise) { config.then((c) => { this.configure(c); }); } else if (typeof config === 'object') { this.configure(config); } this._document = document; this._window = this._document.defaultView; } /** * If no configuration is provided at load time you can use this function to provide configuration at any time. * Loading scripts will be postponed until a configuration is provided * * @param config - {@link GoogleModuleOptions} configuration needed for bootstrapping */ configure(config) { this._config.next(config); this._config.complete(); } load() { if (this._window.google && this._window.google.maps) { // Google maps already loaded on the page return Promise.resolve(); } else if (this._scriptLoadingPromise) { return this._scriptLoadingPromise; } else { this._scriptLoadingPromise = this.checkScriptElement(); return this._scriptLoadingPromise; } } async checkScriptElement() { let scriptElement = this._document?.getElementById(this._SCRIPT_ID); if (scriptElement == null) { scriptElement = await this.createScriptElement(); } return this.assignScriptLoadingPromise(scriptElement); } assignScriptLoadingPromise(scriptElement) { this._document?.body.appendChild(scriptElement); return new Promise((resolve, reject) => { // FIXME // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore this._window[this.callbackName] = () => resolve(); // FIXME // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore scriptElement.onerror = (error) => reject(error); }); } async createScriptElement() { if (!this._document) { throw new Error('Document is not defined'); } const script = this._document.createElement('script'); script.type = 'text/javascript'; script.async = true; script.defer = true; script.id = this._SCRIPT_ID; script.src = await this._getScriptSrc(this.callbackName); return script; } async _getScriptSrc(callbackName) { const config = await firstValueFrom(this._config); if (!config) { throw new Error('No configuration provided'); } const protocolType = (config && config.protocol) || GoogleMapsScriptProtocol.HTTPS; let protocol; switch (protocolType) { case GoogleMapsScriptProtocol.AUTO: protocol = ''; break; case GoogleMapsScriptProtocol.HTTP: protocol = 'http:'; break; case GoogleMapsScriptProtocol.HTTPS: protocol = 'https:'; break; } const hostAndPath = config.hostAndPath || 'maps.googleapis.com/maps/api/js'; const queryParams = { v: config.apiVersion || 'quarterly', callback: callbackName, key: config.apiKey, client: config.clientId, channel: config.channel, libraries: config.libraries, region: config.region, language: config.language, }; const params = Object.keys(queryParams) .filter((k) => queryParams[k] != null) .filter((k) => // remove empty arrays !Array.isArray(queryParams[k]) || (Array.isArray(queryParams[k]) && queryParams[k].length > 0)) .map((k) => { // join arrays as comma seperated strings const i = queryParams[k]; if (Array.isArray(i)) { return { key: k, value: i.join(',') }; } return { key: k, value: queryParams[k] }; }) .map( // FIXME // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore (entry) => `${entry.key}=${entry.value}`) .join('&'); return `${protocol}//${hostAndPath}?${params}`; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsScriptLoader, deps: [{ token: GOOGLE_MAPS_API_CONFIG, optional: true }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsScriptLoader }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: GoogleMapsScriptLoader, decorators: [{ type: Injectable }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [GOOGLE_MAPS_API_CONFIG] }] }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }] }); class NgMapsGoogleModule { /** * configure the NgMapsGoogleModule with a value * @param config */ static forRoot(config) { return { ngModule: NgMapsGoogleModule, providers: [ { provide: GOOGLE_MAPS_API_CONFIG, useValue: config, }, ], }; } /** * configure the NgMapsGoogleModule with a factory * @param factory */ static forRootFactory(factory, deps) { return { ngModule: NgMapsGoogleModule, providers: [ { provide: GOOGLE_MAPS_API_CONFIG, useFactory: factory, deps, }, ], }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: NgMapsGoogleModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.8", ngImport: i0, type: NgMapsGoogleModule, declarations: [GoogleComponent], exports: [GoogleComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: NgMapsGoogleModule, providers: [ { provide: MapsAPILoader, useClass: GoogleMapsScriptLoader }, { provide: MAP_PROVIDER, useValue: 'GoogleMaps', }, ] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: NgMapsGoogleModule, decorators: [{ type: NgModule, args: [{ declarations: [GoogleComponent], exports: [GoogleComponent], providers: [ { provide: MapsAPILoader, useClass: GoogleMapsScriptLoader }, { provide: MAP_PROVIDER, useValue: 'GoogleMaps', }, ], }] }] }); /* * Public API Surface of google */ /** * Generated bundle index. Do not edit. */ export { GOOGLE_MAPS_API_CONFIG, GoogleCircleManager, GoogleComponent, GoogleInfoWindowManager, GoogleMapsAPIWrapper, GoogleMapsMarkerManager, GoogleMapsScriptProtocol, GooglePolygonManager, GooglePolylineManager, GoogleRectangleManager, NgMapsGoogleModule, isValidMarkerIcon }; //# sourceMappingURL=ng-maps-google.mjs.map