UNPKG

@maplibre/ngx-maplibre-gl

Version:
2,978 lines 186 kB
import * as i0 from '@angular/core';
import { inject, NgZone, signal, Injectable, input, viewChild, afterNextRender, ChangeDetectionStrategy, Component, Directive, output, DestroyRef, forwardRef, model, ElementRef, afterEveryRender, ViewEncapsulation, contentChild, TemplateRef, NgModule } from '@angular/core';
import { Marker, Popup, Map as Map$1, AttributionControl, FullscreenControl, GeolocateControl, NavigationControl, ScaleControl, TerrainControl, GlobeControl } from 'maplibre-gl';
import { AsyncSubject, Subject, fromEvent, Subscription, firstValueFrom, merge, tap as tap$1 } from 'rxjs';
import { takeUntilDestroyed, outputToObservable } from '@angular/core/rxjs-interop';
import { tap, switchMap, filter, debounceTime, takeUntil, take, startWith, map } from 'rxjs/operators';
import { NgTemplateOutlet } from '@angular/common';

const keepAvailableObjectValues = (object) => {
    return Object.keys(object).reduce((acc, curr) => {
        const tKey = curr;
        if (object[tKey] === undefined) {
            return acc;
        }
        return { ...acc, [tKey]: object[tKey] };
    }, {});
};

/**
 * @private
 */
class MapService {
    constructor() {
        this.zone = inject(NgZone);
        this.subscriptionsPerInstance = new Map();
        this.mapCreated = new AsyncSubject();
        this.mapLoaded = new AsyncSubject();
        this.markersToRemove = signal([], ...(ngDevMode ? [{ debugName: "markersToRemove" }] : []));
        this.popupsToRemove = signal([], ...(ngDevMode ? [{ debugName: "popupsToRemove" }] : []));
        this.imageIdsToRemove = signal([], ...(ngDevMode ? [{ debugName: "imageIdsToRemove" }] : []));
        this.mapCreated$ = this.mapCreated.asObservable();
        this.mapLoaded$ = this.mapLoaded.asObservable();
    }
    setup(options) {
        // Workaround rollup issue
        this.createMap(options.mapOptions);
        this.hookEvents(options.mapEvents);
        this.mapEvents = options.mapEvents;
        this.mapCreated.next(undefined);
        this.mapCreated.complete();
        if (options.mapOptions.terrain || options.mapOptions.projection) {
            this.mapInstance.on('load', () => {
                if (options.mapOptions.projection) {
                    this.setProjection(options.mapOptions.projection);
                }
                if (options.mapOptions.terrain) {
                    this.setTerrain(options.mapOptions.terrain);
                }
            });
        }
    }
    destroyMap() {
        if (this.mapInstance) {
            this.mapInstance.remove();
        }
    }
    updateMinZoom(minZoom) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setMinZoom(minZoom);
        });
    }
    updateMaxZoom(maxZoom) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setMaxZoom(maxZoom);
        });
    }
    updateMinPitch(minPitch) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setMinPitch(minPitch);
        });
    }
    updateMaxPitch(maxPitch) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setMaxPitch(maxPitch);
        });
    }
    updateRenderWorldCopies(status) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setRenderWorldCopies(status);
        });
    }
    updateScrollZoom(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.scrollZoom.enable()
                : this.mapInstance.scrollZoom.disable();
        });
    }
    updateDragRotate(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.dragRotate.enable()
                : this.mapInstance.dragRotate.disable();
        });
    }
    updateTouchPitch(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.touchPitch.enable()
                : this.mapInstance.touchPitch.disable();
        });
    }
    updateTouchZoomRotate(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.touchZoomRotate.enable()
                : this.mapInstance.touchZoomRotate.disable();
        });
    }
    updateDoubleClickZoom(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.doubleClickZoom.enable()
                : this.mapInstance.doubleClickZoom.disable();
        });
    }
    updateKeyboard(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.keyboard.enable()
                : this.mapInstance.keyboard.disable();
        });
    }
    updateDragPan(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.dragPan.enable()
                : this.mapInstance.dragPan.disable();
        });
    }
    updateBoxZoom(status) {
        return this.zone.runOutsideAngular(() => {
            status
                ? this.mapInstance.boxZoom.enable()
                : this.mapInstance.boxZoom.disable();
        });
    }
    updateStyle(style) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setStyle(style);
        });
    }
    updateMaxBounds(maxBounds) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setMaxBounds(maxBounds);
        });
    }
    setProjection(options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setProjection(options);
        });
    }
    setTerrain(options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setTerrain(options);
        });
    }
    getTerrain() {
        return this.zone.runOutsideAngular(() => {
            return this.mapInstance.getTerrain();
        });
    }
    setCenterElevation(elevation) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setCenterElevation(elevation);
        });
    }
    changeCanvasCursor(cursor) {
        const canvas = this.mapInstance.getCanvasContainer();
        canvas.style.cursor = cursor;
    }
    queryRenderedFeatures(pointOrBox, parameters) {
        return this.mapInstance.queryRenderedFeatures(pointOrBox, parameters);
    }
    panTo(center, options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.panTo(center, options);
        });
    }
    move(movingMethod, movingOptions, zoom, center, bearing, pitch, roll) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance[movingMethod]({
                ...movingOptions,
                zoom: zoom != null ? zoom : this.mapInstance.getZoom(),
                center: center != null ? center : this.mapInstance.getCenter(),
                bearing: bearing != null ? bearing : this.mapInstance.getBearing(),
                pitch: pitch != null ? pitch : this.mapInstance.getPitch(),
                roll: roll != null ? roll : this.mapInstance.getRoll(),
            });
        });
    }
    addLayer(layer, bindEvents, before) {
        this.zone.runOutsideAngular(() => {
            Object.keys(layer.layerOptions).forEach((key) => {
                const tkey = key;
                if (layer.layerOptions[tkey] === undefined) {
                    delete layer.layerOptions[tkey];
                }
            });
            this.mapInstance.addLayer(layer.layerOptions, before);
            if (!bindEvents) {
                return;
            }
            const subscriptions = [];
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'click', layer.layerEvents.layerClick));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'dblclick', layer.layerEvents.layerDblClick));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mousedown', layer.layerEvents.layerMouseDown));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mouseup', layer.layerEvents.layerMouseUp));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mouseenter', layer.layerEvents.layerMouseEnter));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mouseleave', layer.layerEvents.layerMouseLeave));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mousemove', layer.layerEvents.layerMouseMove));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mouseover', layer.layerEvents.layerMouseOver));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'mouseout', layer.layerEvents.layerMouseOut));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'contextmenu', layer.layerEvents.layerContextMenu));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'touchstart', layer.layerEvents.layerTouchStart));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'touchend', layer.layerEvents.layerTouchEnd));
            subscriptions.push(this.createSubscriptionForLayer(layer.layerOptions.id, 'touchcancel', layer.layerEvents.layerTouchCancel));
            const layerInstance = this.mapInstance.getLayer(layer.layerOptions.id);
            if (layerInstance) {
                this.subscriptionsPerInstance.set(layerInstance, subscriptions);
            }
        });
    }
    removeLayer(layerId) {
        this.zone.runOutsideAngular(() => {
            const layerInstance = this.mapInstance.getLayer(layerId);
            if (layerInstance != null) {
                const subscriptions = this.subscriptionsPerInstance.get(layerInstance) || [];
                for (const subscription of subscriptions) {
                    subscription.unsubscribe();
                }
                this.subscriptionsPerInstance.delete(layerInstance);
                this.mapInstance.removeLayer(layerId);
            }
        });
    }
    addMarker(marker) {
        const options = {
            offset: marker.markersOptions.offset,
            anchor: marker.markersOptions.anchor,
            color: marker.markersOptions.color,
            scale: marker.markersOptions.scale,
            draggable: !!marker.markersOptions.draggable,
            rotationAlignment: marker.markersOptions.rotationAlignment,
            rotation: marker.markersOptions.rotation,
            pitchAlignment: marker.markersOptions.pitchAlignment,
            clickTolerance: marker.markersOptions.clickTolerance,
            element: marker.markersOptions.element.childNodes.length > 0
                ? marker.markersOptions.element
                : undefined,
            opacity: marker.markersOptions.opacity,
            opacityWhenCovered: marker.markersOptions.opacityWhenCovered,
            subpixelPositioning: marker.markersOptions.subpixelPositioning,
        };
        const markerInstance = new Marker(options);
        markerInstance.on('dragstart', (event) => {
            if (event) {
                const { target } = event;
                this.zone.run(() => {
                    marker.markersEvents.markerDragStart.emit(target);
                });
            }
        });
        markerInstance.on('drag', (event) => {
            if (event) {
                const { target } = event;
                this.zone.run(() => marker.markersEvents.markerDrag.emit(target));
            }
        });
        markerInstance.on('dragend', (event) => {
            if (event) {
                const { target } = event;
                this.zone.run(() => marker.markersEvents.markerDragEnd.emit(target));
            }
        });
        const lngLat = marker.markersOptions.feature
            ? marker.markersOptions.feature.geometry.coordinates
            : marker.markersOptions.lngLat;
        markerInstance.setLngLat(lngLat);
        return this.zone.runOutsideAngular(() => {
            markerInstance.addTo(this.mapInstance);
            return markerInstance;
        });
    }
    removeMarker(marker) {
        this.markersToRemove.update((markers) => [...markers, marker]);
    }
    createPopup(popup, element) {
        return this.zone.runOutsideAngular(() => {
            const popupOptions = keepAvailableObjectValues(popup.popupOptions);
            const popupInstance = new Popup(popupOptions);
            popupInstance.setDOMContent(element);
            const subscriptions = [];
            subscriptions.push(this.createSubscriptionForPopup(popupInstance, 'open', popup.popupEvents.popupOpen));
            subscriptions.push(this.createSubscriptionForPopup(popupInstance, 'close', popup.popupEvents.popupClose));
            this.subscriptionsPerInstance.set(popupInstance, subscriptions);
            return popupInstance;
        });
    }
    addPopupToMap(popup, lngLat) {
        return this.zone.runOutsideAngular(() => {
            popup.setLngLat(lngLat);
            popup.addTo(this.mapInstance);
        });
    }
    addPopupToMarker(marker, popup) {
        return this.zone.runOutsideAngular(() => {
            marker.setPopup(popup);
        });
    }
    removePopupFromMap(popup) {
        if (this.subscriptionsPerInstance.has(popup)) {
            const subscriptions = this.subscriptionsPerInstance.get(popup) || [];
            for (const subscription of subscriptions) {
                subscription.unsubscribe();
            }
            this.subscriptionsPerInstance.delete(popup);
        }
        this.popupsToRemove.update((popups) => [...popups, popup]);
    }
    removePopupFromMarker(marker) {
        return this.zone.runOutsideAngular(() => {
            const popup = marker.getPopup();
            if (this.subscriptionsPerInstance.has(popup)) {
                const subscriptions = this.subscriptionsPerInstance.get(popup) || [];
                for (const subscription of subscriptions) {
                    subscription.unsubscribe();
                }
                this.subscriptionsPerInstance.delete(popup);
            }
            marker.setPopup(undefined);
        });
    }
    addControl(control, position) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.addControl(control, position);
        });
    }
    removeControl(control) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.removeControl(control);
        });
    }
    async loadAndAddImage(imageId, url, options) {
        return this.zone.runOutsideAngular(async () => {
            const image = await this.mapInstance.loadImage(url);
            this.addImage(imageId, image.data, options);
        });
    }
    addImage(imageId, data, options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.addImage(imageId, data, options);
        });
    }
    removeImage(imageId) {
        this.imageIdsToRemove.update((imagesIds) => [...imagesIds, imageId]);
    }
    addSource(sourceId, source) {
        return this.zone.runOutsideAngular(() => {
            Object.keys(source).forEach((key) => source[key] === undefined && delete source[key]);
            this.mapInstance.addSource(sourceId, source);
        });
    }
    getSource(sourceId) {
        return this.mapInstance.getSource(sourceId);
    }
    removeSource(sourceId) {
        this.zone.runOutsideAngular(() => {
            this.findLayersBySourceId(sourceId).forEach((layer) => this.removeLayer(layer.id));
            this.mapInstance.removeSource(sourceId);
        });
    }
    setAllLayerPaintProperty(layerId, paint) {
        return this.zone.runOutsideAngular(() => {
            Object.keys(paint).forEach((key) => {
                // TODO Check for perf, setPaintProperty only on changed paint props maybe
                this.mapInstance.setPaintProperty(layerId, key, paint[key]);
            });
        });
    }
    setAllLayerLayoutProperty(layerId, layout) {
        return this.zone.runOutsideAngular(() => {
            Object.keys(layout).forEach((key) => {
                // TODO Check for perf, setPaintProperty only on changed paint props maybe
                this.mapInstance.setLayoutProperty(layerId, key, layout[key]);
            });
        });
    }
    setLayerFilter(layerId, filter) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setFilter(layerId, filter);
        });
    }
    setLayerBefore(layerId, beforeId) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.moveLayer(layerId, beforeId);
        });
    }
    setLayerZoomRange(layerId, minZoom, maxZoom) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.setLayerZoomRange(layerId, minZoom ? minZoom : 0, maxZoom ? maxZoom : 20);
        });
    }
    fitBounds(bounds, options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.fitBounds(bounds, options);
        });
    }
    fitScreenCoordinates(points, bearing, options) {
        return this.zone.runOutsideAngular(() => {
            this.mapInstance.fitScreenCoordinates(points[0], points[1], bearing, options);
        });
    }
    clearMapElements() {
        this.zone.runOutsideAngular(() => {
            this.removeMarkers();
            this.removePopups();
            this.removeImages();
        });
    }
    createMap(options) {
        NgZone.assertNotInAngularZone();
        const mapOptions = keepAvailableObjectValues(options);
        this.mapInstance = new Map$1(mapOptions);
        const isIEorEdge = window && /msie\s|trident\/|edge\//i.test(window.navigator.userAgent);
        if (isIEorEdge) {
            this.mapInstance.setStyle(options.style);
        }
    }
    removeMarkers() {
        for (const marker of this.markersToRemove()) {
            marker.remove();
        }
        this.markersToRemove.set([]);
    }
    removePopups() {
        for (const popup of this.popupsToRemove()) {
            popup.remove();
        }
        this.popupsToRemove.set([]);
    }
    removeImages() {
        for (const imageId of this.imageIdsToRemove()) {
            this.mapInstance.removeImage(imageId);
        }
        this.imageIdsToRemove.set([]);
    }
    findLayersBySourceId(sourceId) {
        const layers = this.mapInstance.getStyle().layers;
        if (layers == null) {
            return [];
        }
        return layers.filter((l) => 'source' in l ? l.source === sourceId : false);
    }
    hookEvents(events) {
        this.mapInstance.on('load', (evt) => {
            this.mapLoaded.next(undefined);
            this.mapLoaded.complete();
            this.zone.run(() => {
                events.mapLoad.emit(evt.target);
            });
        });
        this.mapInstance.on('resize', (evt) => this.zone.run(() => {
            events.mapResize.emit(evt);
        }));
        this.mapInstance.on('remove', (evt) => this.zone.run(() => {
            events.mapRemove.emit(evt);
        }));
        this.mapInstance.on('mousedown', (evt) => this.zone.run(() => {
            events.mapMouseDown.emit(evt);
        }));
        this.mapInstance.on('mouseup', (evt) => this.zone.run(() => {
            events.mapMouseUp.emit(evt);
        }));
        this.mapInstance.on('mousemove', (evt) => this.zone.run(() => {
            events.mapMouseMove.emit(evt);
        }));
        this.mapInstance.on('click', (evt) => this.zone.run(() => {
            events.mapClick.emit(evt);
        }));
        this.mapInstance.on('dblclick', (evt) => this.zone.run(() => {
            events.mapDblClick.emit(evt);
        }));
        this.mapInstance.on('mouseover', (evt) => this.zone.run(() => {
            events.mapMouseOver.emit(evt);
        }));
        this.mapInstance.on('mouseout', (evt) => this.zone.run(() => {
            events.mapMouseOut.emit(evt);
        }));
        this.mapInstance.on('contextmenu', (evt) => this.zone.run(() => {
            events.mapContextMenu.emit(evt);
        }));
        this.mapInstance.on('touchstart', (evt) => this.zone.run(() => {
            events.mapTouchStart.emit(evt);
        }));
        this.mapInstance.on('touchend', (evt) => this.zone.run(() => {
            events.mapTouchEnd.emit(evt);
        }));
        this.mapInstance.on('touchmove', (evt) => this.zone.run(() => {
            events.mapTouchMove.emit(evt);
        }));
        this.mapInstance.on('touchcancel', (evt) => this.zone.run(() => {
            events.mapTouchCancel.emit(evt);
        }));
        this.mapInstance.on('wheel', (evt) => this.zone.run(() => {
            events.mapWheel.emit(evt);
        }));
        this.mapInstance.on('movestart', (evt) => this.zone.run(() => events.moveStart.emit(evt)));
        this.mapInstance.on('move', (evt) => this.zone.run(() => events.move.emit(evt)));
        this.mapInstance.on('moveend', (evt) => this.zone.run(() => events.moveEnd.emit(evt)));
        this.mapInstance.on('dragstart', (evt) => this.zone.run(() => {
            events.mapDragStart.emit(evt);
        }));
        this.mapInstance.on('drag', (evt) => this.zone.run(() => {
            events.mapDrag.emit(evt);
        }));
        this.mapInstance.on('dragend', (evt) => this.zone.run(() => {
            events.mapDragEnd.emit(evt);
        }));
        this.mapInstance.on('zoomstart', (evt) => this.zone.run(() => events.zoomStart.emit(evt)));
        this.mapInstance.on('zoom', (evt) => this.zone.run(() => events.zoomEvt.emit(evt)));
        this.mapInstance.on('zoomend', (evt) => this.zone.run(() => events.zoomEnd.emit(evt)));
        this.mapInstance.on('rotatestart', (evt) => this.zone.run(() => events.rotateStart.emit(evt)));
        this.mapInstance.on('rotate', (evt) => this.zone.run(() => events.rotate.emit(evt)));
        this.mapInstance.on('rotateend', (evt) => this.zone.run(() => events.rotateEnd.emit(evt)));
        this.mapInstance.on('pitchstart', (evt) => this.zone.run(() => events.pitchStart.emit(evt)));
        this.mapInstance.on('pitch', (evt) => this.zone.run(() => events.pitchEvt.emit(evt)));
        this.mapInstance.on('pitchend', (evt) => this.zone.run(() => events.pitchEnd.emit(evt)));
        this.mapInstance.on('boxzoomstart', (evt) => this.zone.run(() => events.boxZoomStart.emit(evt)));
        this.mapInstance.on('boxzoomend', (evt) => this.zone.run(() => events.boxZoomEnd.emit(evt)));
        this.mapInstance.on('boxzoomcancel', (evt) => this.zone.run(() => events.boxZoomCancel.emit(evt)));
        this.mapInstance.on('webglcontextlost', (evt) => this.zone.run(() => events.webGlContextLost.emit(evt)));
        this.mapInstance.on('webglcontextrestored', (evt) => this.zone.run(() => events.webGlContextRestored.emit(evt)));
        this.mapInstance.on('render', (evt) => this.zone.run(() => events.render.emit(evt)));
        this.mapInstance.on('error', (evt) => this.zone.run(() => {
            events.mapError.emit(evt);
        }));
        this.mapInstance.on('data', (evt) => this.zone.run(() => events.data.emit(evt)));
        this.mapInstance.on('styledata', (evt) => this.zone.run(() => events.styleData.emit(evt)));
        this.mapInstance.on('sourcedata', (evt) => this.zone.run(() => events.sourceData.emit(evt)));
        this.mapInstance.on('dataloading', (evt) => this.zone.run(() => events.dataLoading.emit(evt)));
        this.mapInstance.on('styledataloading', (evt) => this.zone.run(() => events.styleDataLoading.emit(evt)));
        this.mapInstance.on('sourcedataloading', (evt) => this.zone.run(() => events.sourceDataLoading.emit(evt)));
        this.mapInstance.on('styleimagemissing', (evt) => this.zone.run(() => events.styleImageMissing.emit(evt)));
        this.mapInstance.on('idle', (evt) => this.zone.run(() => events.idle.emit(evt)));
    }
    createSubscriptionForLayer(layerId, event, emitter) {
        const handler = (evt) => {
            this.zone.run(() => {
                emitter.emit(evt);
            });
        };
        this.mapInstance.on(event, layerId, handler);
        return {
            unsubscribe: () => {
                this.mapInstance.off(event, layerId, handler);
            },
        };
    }
    createSubscriptionForPopup(popup, event, emitter) {
        const handler = (evt) => {
            this.zone.run(() => {
                emitter.emit(evt);
            });
        };
        popup.on(event, handler);
        return {
            unsubscribe: () => {
                popup.off(event, handler);
            },
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MapService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MapService }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MapService, decorators: [{
            type: Injectable
        }] });

class CustomControl {
    constructor(container) {
        this.container = container;
    }
    /** @inheritdoc */
    onAdd() {
        return this.container;
    }
    /** @inheritdoc */
    onRemove() {
        return this.container.parentNode?.removeChild(this.container);
    }
    /** @inheritdoc */
    getDefaultPosition() {
        return 'top-right';
    }
}
/**
 * `mgl-control` - a custom control component
 * @see [Controls](https://maplibre.org/maplibre-gl-js/docs/API/interfaces/IControl/)
 *
 * @category Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-control> Hello </mgl-control>
 *   ...
 *   <mgl-control mglNavigation></mgl-control>
 *   ...
 *   <mgl-control mglScale unit="imperial" position="top-right"></mgl-control>
 *   ...
 *   <mgl-control
 *     mglTerrain
 *     source="rasterDemSource"
 *     exaggeration="3.1"
 *   ></mgl-control>
 * </mgl-map>
 * ```
 */
class ControlComponent {
    constructor() {
        /** Init injection */
        this.mapService = inject(MapService);
        /** Init input */
        this.position = input(...(ngDevMode ? [undefined, { debugName: "position" }] : []));
        /** @hidden */
        this.content = viewChild.required('content');
        afterNextRender(() => {
            if (this.content().nativeElement.childNodes.length) {
                this.control = new CustomControl(this.content().nativeElement);
                this.mapService.mapCreated$.subscribe(() => {
                    this.mapService.addControl(this.control, this.position());
                });
            }
        });
    }
    ngOnDestroy() {
        if (this.mapService?.mapInstance?.hasControl(this.control)) {
            this.mapService.removeControl(this.control);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: ControlComponent, isStandalone: true, selector: "mgl-control", inputs: { position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], ngImport: i0, template: `
    <div class="maplibregl-ctrl" #content>
      <ng-content></ng-content>
    </div>
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ControlComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-control',
                    template: `
    <div class="maplibregl-ctrl" #content>
      <ng-content></ng-content>
    </div>
  `,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], content: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });

/**
 * `mglAttribution` - an attribution control directive
 *
 * @category Directives
 *
 * @see [Add custom attribution](https://maplibre.org/ngx-maplibre-gl/demo/custom-attribution)
 * @see [AttributionControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/AttributionControl)
 */
class AttributionControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /** Init input */
        this.compact = input(...(ngDevMode ? [undefined, { debugName: "compact" }] : []));
        /** Init input */
        this.customAttribution = input(...(ngDevMode ? [undefined, { debugName: "customAttribution" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                const options = keepAvailableObjectValues({
                    compact: this.compact(),
                    customAttribution: this.customAttribution(),
                });
                this.controlComponent.control = new AttributionControl(options);
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AttributionControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: AttributionControlDirective, isStandalone: true, selector: "[mglAttribution]", inputs: { compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, customAttribution: { classPropertyName: "customAttribution", publicName: "customAttribution", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: AttributionControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglAttribution]',
                }]
        }], ctorParameters: () => [], propDecorators: { compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], customAttribution: [{ type: i0.Input, args: [{ isSignal: true, alias: "customAttribution", required: false }] }] } });

/**
 * `mglFullscreen` - a fullscreen control directive
 *
 * @category Directives
 */
class FullscreenControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /* Init inputs */
        this.container = input(...(ngDevMode ? [undefined, { debugName: "container" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                this.controlComponent.control = new FullscreenControl({
                    container: this.container(),
                });
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    onFullscreen() {
        this.mapService.mapInstance.resize();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FullscreenControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: FullscreenControlDirective, isStandalone: true, selector: "[mglFullscreen]", inputs: { container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:webkitfullscreenchange": "onFullscreen()" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FullscreenControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglFullscreen]',
                    host: {
                        // eslint-disable-next-line @typescript-eslint/naming-convention
                        '(window:webkitfullscreenchange)': 'onFullscreen()',
                    },
                }]
        }], ctorParameters: () => [], propDecorators: { container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: false }] }] } });

/**
 * `mglGeolocate` - a geolocate control directive
 *
 * @category Directives
 *
 * @see [Locate user](https://maplibre.org/ngx-maplibre-gl/demo/locate-user)
 * @see [GeolocateControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/GeolocateControl)
 */
class GeolocateControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /* Init inputs */
        this.positionOptions = input(...(ngDevMode ? [undefined, { debugName: "positionOptions" }] : []));
        /* Init inputs */
        this.fitBoundsOptions = input(...(ngDevMode ? [undefined, { debugName: "fitBoundsOptions" }] : []));
        /* Init inputs */
        this.trackUserLocation = input(...(ngDevMode ? [undefined, { debugName: "trackUserLocation" }] : []));
        /* Init inputs */
        this.showUserLocation = input(...(ngDevMode ? [undefined, { debugName: "showUserLocation" }] : []));
        this.geolocate = output();
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                const options = keepAvailableObjectValues({
                    positionOptions: this.positionOptions(),
                    fitBoundsOptions: this.fitBoundsOptions(),
                    trackUserLocation: this.trackUserLocation(),
                    showUserLocation: this.showUserLocation(),
                });
                this.controlComponent.control = new GeolocateControl(options);
                this.controlComponent.control.on('geolocate', (data) => {
                    this.geolocate.emit(data);
                });
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GeolocateControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: GeolocateControlDirective, isStandalone: true, selector: "[mglGeolocate]", inputs: { positionOptions: { classPropertyName: "positionOptions", publicName: "positionOptions", isSignal: true, isRequired: false, transformFunction: null }, fitBoundsOptions: { classPropertyName: "fitBoundsOptions", publicName: "fitBoundsOptions", isSignal: true, isRequired: false, transformFunction: null }, trackUserLocation: { classPropertyName: "trackUserLocation", publicName: "trackUserLocation", isSignal: true, isRequired: false, transformFunction: null }, showUserLocation: { classPropertyName: "showUserLocation", publicName: "showUserLocation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { geolocate: "geolocate" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GeolocateControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglGeolocate]',
                }]
        }], ctorParameters: () => [], propDecorators: { positionOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "positionOptions", required: false }] }], fitBoundsOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitBoundsOptions", required: false }] }], trackUserLocation: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackUserLocation", required: false }] }], showUserLocation: [{ type: i0.Input, args: [{ isSignal: true, alias: "showUserLocation", required: false }] }], geolocate: [{ type: i0.Output, args: ["geolocate"] }] } });

/**
 * `mglNavigation` - a navigation control directive
 *
 * @category Directives
 *
 * @see [Navigation](https://maplibre.org/ngx-maplibre-gl/demo/navigation)
 * @see [NavigationControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/NavigationControl)
 */
class NavigationControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /* Init inputs */
        this.showCompass = input(...(ngDevMode ? [undefined, { debugName: "showCompass" }] : []));
        /* Init inputs */
        this.showZoom = input(...(ngDevMode ? [undefined, { debugName: "showZoom" }] : []));
        /* Init inputs */
        this.visualizePitch = input(...(ngDevMode ? [undefined, { debugName: "visualizePitch" }] : []));
        /* Init inputs */
        this.visualizeRoll = input(...(ngDevMode ? [undefined, { debugName: "visualizeRoll" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                const options = keepAvailableObjectValues({
                    showCompass: this.showCompass(),
                    showZoom: this.showZoom(),
                    visualizePitch: this.visualizePitch(),
                    visualizeRoll: this.visualizeRoll(),
                });
                this.controlComponent.control = new NavigationControl(options);
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NavigationControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NavigationControlDirective, isStandalone: true, selector: "[mglNavigation]", inputs: { showCompass: { classPropertyName: "showCompass", publicName: "showCompass", isSignal: true, isRequired: false, transformFunction: null }, showZoom: { classPropertyName: "showZoom", publicName: "showZoom", isSignal: true, isRequired: false, transformFunction: null }, visualizePitch: { classPropertyName: "visualizePitch", publicName: "visualizePitch", isSignal: true, isRequired: false, transformFunction: null }, visualizeRoll: { classPropertyName: "visualizeRoll", publicName: "visualizeRoll", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NavigationControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglNavigation]',
                }]
        }], ctorParameters: () => [], propDecorators: { showCompass: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCompass", required: false }] }], showZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "showZoom", required: false }] }], visualizePitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "visualizePitch", required: false }] }], visualizeRoll: [{ type: i0.Input, args: [{ isSignal: true, alias: "visualizeRoll", required: false }] }] } });

/**
 * `mglScale` - a scale control directive
 *
 * @category Directives
 *
 * @see [Scale](https://maplibre.org/ngx-maplibre-gl/demo/ngx-scale-control)
 * @see [ScaleControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/ScaleControl)
 */
class ScaleControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /* Init inputs */
        this.maxWidth = input(...(ngDevMode ? [undefined, { debugName: "maxWidth" }] : []));
        /* Dynamic inputs */
        this.unit = input(...(ngDevMode ? [undefined, { debugName: "unit" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                const options = keepAvailableObjectValues({
                    maxWidth: this.maxWidth(),
                    unit: this.unit(),
                });
                this.controlComponent.control = new ScaleControl(options);
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    ngOnChanges(changes) {
        if (changes.unit && !changes.unit.isFirstChange()) {
            this.controlComponent.control.setUnit(changes.unit.currentValue);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ScaleControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: ScaleControlDirective, isStandalone: true, selector: "[mglScale]", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ScaleControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglScale]',
                }]
        }], ctorParameters: () => [], propDecorators: { maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }] } });

/**
 * `mglTerrain` - a terrain control directive
 *
 * @category Directives
 *
 * @see [Terrain](https://maplibre.org/ngx-maplibre-gl/demo/terrain-control)
 * @see [TerrainControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/TerrainControl)
 */
class TerrainControlDirective {
    constructor() {
        /* Init injection */
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        /* Init inputs */
        this.source = input.required(...(ngDevMode ? [{ debugName: "source" }] : []));
        this.exaggeration = input(...(ngDevMode ? [undefined, { debugName: "exaggeration" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                const options = {
                    source: this.source(),
                    exaggeration: this.exaggeration() ?? 1,
                };
                this.controlComponent.control = new TerrainControl(options);
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TerrainControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: TerrainControlDirective, isStandalone: true, selector: "[mglTerrain]", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, exaggeration: { classPropertyName: "exaggeration", publicName: "exaggeration", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: TerrainControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglTerrain]',
                }]
        }], ctorParameters: () => [], propDecorators: { source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: true }] }], exaggeration: [{ type: i0.Input, args: [{ isSignal: true, alias: "exaggeration", required: false }] }] } });

/**
 * @internal
 * A composition object for the source components
 */
class SourceDirective {
    constructor() {
        /** Init injection */
        this.mapService = inject(MapService);
        this.destroyRef = inject(DestroyRef);
        /**  Init input */
        this.id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
        /**
         * @internal
         * Used to store the current source id and make sure removeSource is only called once.
         */
        this.sourceId = signal(null, ...(ngDevMode ? [{ debugName: "sourceId" }] : []));
        this.loadSourceSubject = new Subject();
        this.loadSource$ = this.loadSourceSubject.asObservable();
    }
    ngOnInit() {
        this.mapService.mapLoaded$
            .pipe(tap(() => this.loadSourceSubject.next()), switchMap(() => fromEvent(this.mapService.mapInstance, 'styledata').pipe(filter(() => !this.mapService.mapInstance.getSource(this.id())), tap(() => this.loadSourceSubject.next()))), takeUntilDestroyed(this.destroyRef))
            .subscribe();
    }
    ngOnDestroy() {
        this.removeSource();
    }
    refresh() {
        this.removeSource();
        this.loadSourceSubject.next();
    }
    removeSource() {
        const currentId = this.sourceId();
        if (currentId) {
            this.mapService.removeSource(currentId);
            this.sourceId.set(null);
        }
    }
    addSource(source) {
        this.mapService.addSource(this.id(), source);
        this.sourceId.set(this.id());
    }
    getSource() {
        return this.mapService.getSource(this.id());
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SourceDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: SourceDirective, isStandalone: true, inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: SourceDirective, decorators: [{
            type: Directive,
            args: [{}]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }] } });

/**
 * `mgl-geojson-source` - a geojson source component
 * @see [geojson](https://maplibre.org/maplibre-gl-js/docs/API/classes/maplibregl.GeoJSONSource/)
 *
 * @category Source Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-geojson-source id="symbols-source">
 *     <mgl-feature
 *       *ngFor="let geometry of geometries"
 *       [geometry]="geometry"
 *     ></mgl-feature>
 *   </mgl-geojson-source>
 *   ...
 *   <mgl-geojson-source
 *     id="earthquakes"
 *     [data]="earthquakes"
 *     [cluster]="true"
 *     [clusterMaxZoom]="14"
 *     [clusterRadius]="50"
 *   ></mgl-geojson-source>
 * </mgl-map>
 *
 * ```
 */
class GeoJSONSourceComponent {
    constructor() {
        /** Init injections */
        this.sourceDirective = inject(SourceDirective);
        /** Init injection */
        this.ngZone = inject(NgZone);
        /** Dynamic input */
        this.data = input({
            type: 'FeatureCollection',
            features: [],
        }, ...(ngDevMode ? [{ debugName: "data" }] : []));
        /** Dynamic input */
        this.maxzoom = input(...(ngDevMode ? [undefined, { debugName: "maxzoom" }] : []));
        /** Dynamic input */
        this.attribution = input(...(ngDevMode ? [undefined, { debugName: "attribution" }] : []));
        /** Dynamic input */
        this.buffer = input(...(ngDevMode ? [undefined, { debugName: "buffer" }] : []));
        /** Dynamic input */
        this.tolerance = input(...(ngDevMode ? [undefined, { debugName: "tolerance" }] : []));
        /** Dynamic input */
        this.cluster = input(...(ngDevMode ? [undefined, { debugName: "cluster" }] : []));
        /** Dynamic input */
        this.clusterRadius = input(...(ngDevMode ? [undefined, { debugName: "clusterRadius" }] : []));
        /** Dynamic input */
        this.clusterMaxZoom = input(...(ngDevMode ? [undefined, { debugName: "clusterMaxZoom" }] : []));
        /** Dynamic input */
        this.clusterMinPoints = input(...(ngDevMode ? [undefined, { debugName: "clusterMinPoints" }] : []));
        /** Dynamic input */
        this.clusterProperties = input(...(ngDevMode ? [undefined, { debugName: "clusterProperties" }] : []));
        /** Dynamic input */
        this.lineMetrics = input(...(ngDevMode ? [undefined, { debugName: "lineMetrics" }] : []));
        /** Dynamic input */
        this.generateId = input(...(ngDevMode ? [undefined, { debugName: "generateId" }] : []));
        /** Dynamic input */
        this.promoteId = input(...(ngDevMode ? [undefined, { debugName: "promoteId" }] : []));
        /** Dynamic input */
        this.filter = input(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
        this.updateFeatureDataSubject = new Subject();
        this.featureIdCounter = signal(0, ...(ngDevMode ? [{ debugName: "featureIdCounter" }] : []));
        this.sourceDirective.loadSource$
            .pipe(tap(() => this.sourceDirective.addSource(this.getGeoJSONSourceSpecification())), switchMap(() => this.updateFeature()), takeUntilDestroyed())
            .subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if ((changes.maxzoom && !changes.maxzoom.isFirstChange()) ||
            (changes.attribution && !changes.attribution.isFirstChange()) ||
            (changes.buffer && !changes.buffer.isFirstChange()) ||
            (changes.tolerance && !changes.tolerance.isFirstChange()) ||
            (changes.cluster && !changes.cluster.isFirstChange()) ||
            (changes.clusterRadius && !changes.clusterRadius.isFirstChange()) ||
            (changes.clusterMaxZoom && !changes.clusterMaxZoom.isFirstChange()) ||
            (changes.clusterMinPoints && !changes.clusterMinPoints.isFirstChange()) ||
            (changes.clusterProperties &&
                !changes.clusterProperties.isFirstChange()) ||
            (changes.lineMetrics && !changes.lineMetrics.isFirstChange()) ||
            (changes.generateId && !changes.generateId.isFirstChange()) ||
            (changes.promoteId && !changes.promoteId.isFirstChange()) ||
            (changes.filter && !changes.filter.isFirstChange())) {
            this.sourceDirective.refresh();
        }
        if (changes.data && !changes.data.isFirstChange()) {
            const source = this.sourceDirective.getSource();
            if (source === undefined) {
                return;
            }
            source.setData(changes.data.currentValue);
        }
    }
    /**
     * For clustered sources, fetches the zoom at which the given cluster expands.
     * @param clusterId The value of the cluster's cluster_id property.
     */
    async getClusterExpansionZoom(clusterId) {
        const source = this.sourceDirective.getSource();
        return this.ngZone.run(async () => {
            return source.getClusterExpansionZoom(clusterId);
        });
    }
    /**
     * For clustered sources, fetches the children of the given cluster on the next zoom level (as an array of GeoJSON features).
     * @param clusterId The value of the cluster's cluster_id property.
     */
    async getClusterChildren(clusterId) {
        const source = this.sourceDirective.getSource();
        return this.ngZone.run(async () => {
            return source.getClusterChildren(clusterId);
        });
    }
    /**
     * For clustered sources, fetches the original points that belong to the cluster (as an array of GeoJSON features).
     * @param clusterId The value of the cluster's cluster_id property.
     * @param limit The maximum number of features to return.
     * @param offset The number of features to skip (e.g. for pagination).
     */
    async getClusterLeaves(clusterId, limit, offset) {
        const source = this.sourceDirective.getSource();
        return this.ngZone.run(async () => {
            return source.getClusterLeaves(clusterId, limit, offset);
        });
    }
    _addFeature(feature) {
        const collection = (this.data());
        collection.features.push(feature);
        this.updateFeatureDataSubject.next();
    }
    _removeFeature(feature) {
        const collection = (this.data());
        const index = collection.features.indexOf(feature);
        if (index > -1) {
            collection.features.splice(index, 1);
        }
        this.updateFeatureDataSubject.next();
    }
    updateFeatureData() {
        this.updateFeatureDataSubject.next();
    }
    _getNewFeatureId() {
        this.featureIdCounter.update((featureIdCounter) => ++featureIdCounter);
        return this.featureIdCounter();
    }
    getGeoJSONSourceSpecification() {
        return {
            type: 'geojson',
            data: this.data(),
            maxzoom: this.maxzoom(),
            attribution: this.attribution(),
            buffer: this.buffer(),
            tolerance: this.tolerance(),
            cluster: this.cluster(),
            clusterRadius: this.clusterRadius(),
            clusterMaxZoom: this.clusterMaxZoom(),
            clusterMinPoints: this.clusterMinPoints(),
            clusterProperties: this.clusterProperties(),
            lineMetrics: this.lineMetrics(),
            generateId: this.generateId(),
            promoteId: this.promoteId(),
            filter: this.filter(),
        };
    }
    updateFeature() {
        return this.updateFeatureDataSubject.pipe(debounceTime(0)).pipe(tap(() => {
            const source = this.sourceDirective.getSource();
            if (source === undefined) {
                return;
            }
            source.setData(this.data());
        }));
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GeoJSONSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: GeoJSONSourceComponent, isStandalone: true, selector: "mgl-geojson-source", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, maxzoom: { classPropertyName: "maxzoom", publicName: "maxzoom", isSignal: true, isRequired: false, transformFunction: null }, attribution: { classPropertyName: "attribution", publicName: "attribution", isSignal: true, isRequired: false, transformFunction: null }, buffer: { classPropertyName: "buffer", publicName: "buffer", isSignal: true, isRequired: false, transformFunction: null }, tolerance: { classPropertyName: "tolerance", publicName: "tolerance", isSignal: true, isRequired: false, transformFunction: null }, cluster: { classPropertyName: "cluster", publicName: "cluster", isSignal: true, isRequired: false, transformFunction: null }, clusterRadius: { classPropertyName: "clusterRadius", publicName: "clusterRadius", isSignal: true, isRequired: false, transformFunction: null }, clusterMaxZoom: { classPropertyName: "clusterMaxZoom", publicName: "clusterMaxZoom", isSignal: true, isRequired: false, transformFunction: null }, clusterMinPoints: { classPropertyName: "clusterMinPoints", publicName: "clusterMinPoints", isSignal: true, isRequired: false, transformFunction: null }, clusterProperties: { classPropertyName: "clusterProperties", publicName: "clusterProperties", isSignal: true, isRequired: false, transformFunction: null }, lineMetrics: { classPropertyName: "lineMetrics", publicName: "lineMetrics", isSignal: true, isRequired: false, transformFunction: null }, generateId: { classPropertyName: "generateId", publicName: "generateId", isSignal: true, isRequired: false, transformFunction: null }, promoteId: { classPropertyName: "promoteId", publicName: "promoteId", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GeoJSONSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-geojson-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], maxzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxzoom", required: false }] }], attribution: [{ type: i0.Input, args: [{ isSignal: true, alias: "attribution", required: false }] }], buffer: [{ type: i0.Input, args: [{ isSignal: true, alias: "buffer", required: false }] }], tolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "tolerance", required: false }] }], cluster: [{ type: i0.Input, args: [{ isSignal: true, alias: "cluster", required: false }] }], clusterRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "clusterRadius", required: false }] }], clusterMaxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "clusterMaxZoom", required: false }] }], clusterMinPoints: [{ type: i0.Input, args: [{ isSignal: true, alias: "clusterMinPoints", required: false }] }], clusterProperties: [{ type: i0.Input, args: [{ isSignal: true, alias: "clusterProperties", required: false }] }], lineMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineMetrics", required: false }] }], generateId: [{ type: i0.Input, args: [{ isSignal: true, alias: "generateId", required: false }] }], promoteId: [{ type: i0.Input, args: [{ isSignal: true, alias: "promoteId", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }] } });

/**
 * `mgl-feature` - a feature component
 * [ngx] inside {@link GeoJSONSourceComponent} only
 *
 * @category Source Components
 */
class FeatureComponent {
    constructor() {
        /** Init injection */
        this.geoJSONSourceComponent = inject(forwardRef(() => GeoJSONSourceComponent));
        /** Init input */
        this.id = model(...(ngDevMode ? [undefined, { debugName: "id" }] : []));
        /** Init input */
        this.geometry = input.required(...(ngDevMode ? [{ debugName: "geometry" }] : []));
        /** Init input */
        this.properties = input(...(ngDevMode ? [undefined, { debugName: "properties" }] : []));
    }
    ngOnInit() {
        const id = this.id();
        if (!id) {
            this.id.set(this.geoJSONSourceComponent._getNewFeatureId());
        }
        const properties = this.properties();
        this.feature = {
            type: 'Feature',
            geometry: this.geometry(),
            properties: properties ?? {},
        };
        this.feature.id = this.id();
        this.geoJSONSourceComponent._addFeature(this.feature);
    }
    ngOnDestroy() {
        this.geoJSONSourceComponent._removeFeature(this.feature);
    }
    updateCoordinates(coordinates) {
        this.feature.geometry.coordinates = coordinates;
        this.geoJSONSourceComponent.updateFeatureData();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FeatureComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: FeatureComponent, isStandalone: true, selector: "mgl-feature", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, geometry: { classPropertyName: "geometry", publicName: "geometry", isSignal: true, isRequired: true, transformFunction: null }, properties: { classPropertyName: "properties", publicName: "properties", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { id: "idChange" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: FeatureComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-feature',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }, { type: i0.Output, args: ["idChange"] }], geometry: [{ type: i0.Input, args: [{ isSignal: true, alias: "geometry", required: true }] }], properties: [{ type: i0.Input, args: [{ isSignal: true, alias: "properties", required: false }] }] } });

/**
 * `mglDraggable` - a directive for Feature or Marker
 *
 * @category Directives
 *
 * @see [Draggable Marker](https://maplibre.org/ng-maplibre-gl/demo/ngx-drag-a-point)
 */
class DraggableDirective {
    constructor() {
        /** Init injection */
        this.mapService = inject(MapService);
        this.ngZone = inject(NgZone);
        this.featureComponent = inject(FeatureComponent, {
            host: true,
            optional: true,
        });
        // eslint-disable-next-line @angular-eslint/no-input-rename
        this.layer = input(null, { ...(ngDevMode ? { debugName: "layer" } : {}), alias: 'mglDraggable' });
        this.featureDragStart = output();
        this.featureDragEnd = output();
        this.featureDrag = output();
        this.sub = new Subscription();
    }
    ngOnInit() {
        let enter$;
        let leave$;
        let updateCoords;
        const layer = this.layer();
        if (this.featureComponent && layer) {
            enter$ = outputToObservable(layer.layerMouseEnter);
            leave$ = outputToObservable(layer.layerMouseLeave);
            updateCoords = this.featureComponent.updateCoordinates.bind(this.featureComponent);
            if (this.featureComponent.geometry().type !== 'Point') {
                throw new Error('mglDraggable only support point feature');
            }
        }
        else {
            throw new Error('mglDraggable can only be used on Feature (with a layer as input) or Marker');
        }
        this.handleDraggable(enter$, leave$, updateCoords);
    }
    ngOnDestroy() {
        this.sub.unsubscribe();
    }
    handleDraggable(enter$, leave$, updateCoords) {
        let moving = false;
        let inside = false;
        this.mapService.mapCreated$.subscribe(() => {
            const mouseUp$ = fromEvent(this.mapService.mapInstance, 'mouseup');
            const dragStart$ = enter$.pipe(filter(() => !moving), filter((evt) => this.filterFeature(evt)), tap(() => {
                inside = true;
                this.mapService.changeCanvasCursor('move');
                this.mapService.updateDragPan(false);
            }), switchMap(() => fromEvent(this.mapService.mapInstance, 'mousedown').pipe(takeUntil(leave$))));
            const dragging$ = dragStart$.pipe(switchMap(() => fromEvent(this.mapService.mapInstance, 'mousemove').pipe(takeUntil(mouseUp$))));
            const dragEnd$ = dragStart$.pipe(switchMap(() => mouseUp$.pipe(take(1))));
            this.sub.add(dragStart$.subscribe((evt) => {
                moving = true;
                this.ngZone.run(() => {
                    this.featureDragStart.emit(evt);
                });
            }));
            this.sub.add(dragging$.subscribe((evt) => {
                updateCoords([evt.lngLat.lng, evt.lngLat.lat]);
                this.ngZone.run(() => {
                    this.featureDrag.emit(evt);
                });
            }));
            this.sub.add(dragEnd$.subscribe((evt) => {
                moving = false;
                this.ngZone.run(() => {
                    this.featureDragEnd.emit(evt);
                });
                if (!inside) {
                    // It's possible to dragEnd outside the target (small input lag)
                    this.mapService.changeCanvasCursor('');
                    this.mapService.updateDragPan(true);
                }
            }));
            this.sub.add(leave$
                .pipe(tap(() => (inside = false)), filter(() => !moving))
                .subscribe(() => {
                this.mapService.changeCanvasCursor('');
                this.mapService.updateDragPan(true);
            }));
        });
    }
    filterFeature(evt) {
        const layer = this.layer();
        if (this.featureComponent && layer) {
            const feature = this.mapService.queryRenderedFeatures(evt.point, {
                layers: [layer.id()],
                filter: [
                    'all',
                    ['==', '$type', 'Point'],
                    ['==', '$id', this.featureComponent.id()],
                ],
            })[0];
            if (!feature) {
                return false;
            }
        }
        return true;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DraggableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: DraggableDirective, isStandalone: true, selector: "[mglDraggable]", inputs: { layer: { classPropertyName: "layer", publicName: "mglDraggable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { featureDragStart: "featureDragStart", featureDragEnd: "featureDragEnd", featureDrag: "featureDrag" }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: DraggableDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglDraggable]',
                }]
        }], propDecorators: { layer: [{ type: i0.Input, args: [{ isSignal: true, alias: "mglDraggable", required: false }] }], featureDragStart: [{ type: i0.Output, args: ["featureDragStart"] }], featureDragEnd: [{ type: i0.Output, args: ["featureDragEnd"] }], featureDrag: [{ type: i0.Output, args: ["featureDrag"] }] } });

/**
 * `mgl-image` - an image component
 * @see [addImage](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/#addimage)
 *
 * @category Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map
 *   ...
 * >
 *    <mgl-image
 *      id="image"
 *      url="https://..."
 *      (imageLoaded)="imageLoaded = true"
 *    >
 *    ...
 *    <mgl-image
 *      id="image2"
 *      [data]="{
 *        width: 64,
 *        height: 64,
 *        data: imageData
 *      }"
 *    >
 * </mgl-map>
 * ...
 * imageData: Uint8Array;
 * ```
 */
class ImageComponent {
    constructor() {
        /** Init injection */
        this.mapService = inject(MapService);
        this.destroyRef = inject(DestroyRef);
        this.zone = inject(NgZone);
        /** Init input */
        this.id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
        /** Dynamic input */
        this.data = input(...(ngDevMode ? [undefined, { debugName: "data" }] : []));
        /** Dynamic input */
        this.options = input(...(ngDevMode ? [undefined, { debugName: "options" }] : []));
        /** Dynamic input */
        this.url = input(...(ngDevMode ? [undefined, { debugName: "url" }] : []));
        this.imageError = output();
        this.imageLoaded = output();
        this.isAdded = signal(false, ...(ngDevMode ? [{ debugName: "isAdded" }] : []));
        this.isAdding = signal(false, ...(ngDevMode ? [{ debugName: "isAdding" }] : []));
    }
    ngOnInit() {
        this.mapService.mapLoaded$
            .pipe(switchMap(() => fromEvent(this.mapService.mapInstance, 'styledata').pipe(startWith(undefined), filter(() => !this.isAdding() &&
            !this.mapService.mapInstance.hasImage(this.id())))), takeUntilDestroyed(this.destroyRef))
            .subscribe(() => this.addImage());
    }
    ngOnChanges(changes) {
        if ((changes.data && !changes.data.isFirstChange()) ||
            (changes.options && !changes.options.isFirstChange()) ||
            (changes.url && !changes.url.isFirstChange())) {
            this.removeImage();
            this.ngOnInit();
        }
    }
    ngOnDestroy() {
        this.removeImage();
    }
    removeImage() {
        if (this.isAdded()) {
            this.mapService.removeImage(this.id());
        }
    }
    async addImage() {
        this.isAdding.set(true);
        const data = this.data();
        const url = this.url();
        if (data) {
            this.mapService.addImage(this.id(), data, this.options());
            this.isAdded.set(true);
            this.isAdding.set(false);
        }
        else if (url) {
            try {
                await this.mapService.loadAndAddImage(this.id(), url, this.options());
                this.isAdded.set(true);
                this.isAdding.set(false);
                this.zone.run(() => {
                    this.imageLoaded.emit();
                });
            }
            catch (error) {
                this.zone.run(() => {
                    this.imageError.emit(error);
                });
            }
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: ImageComponent, isStandalone: true, selector: "mgl-image", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { imageError: "imageError", imageLoaded: "imageLoaded" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImageComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-image',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], imageError: [{ type: i0.Output, args: ["imageError"] }], imageLoaded: [{ type: i0.Output, args: ["imageLoaded"] }] } });

/**
 * `mgl-layer` - a layer component
 * @see [layers](https://maplibre.org/maplibre-style-spec/layers/)
 *
 * @category Layer Component
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-layer
 *     id="state-borders"
 *     type="line"
 *     [source]="states"
 *     [paint]="{
 *       'line-color': '#627BC1',
 *       'line-width': 2
 *     }"
 *   ></mgl-layer>
 * </mgl-map>
 * ```
 */
class LayerComponent {
    constructor() {
        /** Init injection */
        this.destroyRef = inject(DestroyRef);
        this.mapService = inject(MapService);
        /** Init input */
        this.id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
        this.type = input.required(...(ngDevMode ? [{ debugName: "type" }] : []));
        this.source = input(...(ngDevMode ? [undefined, { debugName: "source" }] : []));
        this.metadata = input(...(ngDevMode ? [undefined, { debugName: "metadata" }] : []));
        this.sourceLayer = input(...(ngDevMode ? [undefined, { debugName: "sourceLayer" }] : []));
        /**
         * A flag to enable removeSource clean up functionality
         *
         * Init input
         */
        this.removeSource = input(...(ngDevMode ? [undefined, { debugName: "removeSource" }] : []));
        this.filter = input(...(ngDevMode ? [undefined, { debugName: "filter" }] : []));
        this.layout = input(...(ngDevMode ? [undefined, { debugName: "layout" }] : []));
        this.paint = input(...(ngDevMode ? [undefined, { debugName: "paint" }] : []));
        this.before = input(...(ngDevMode ? [undefined, { debugName: "before" }] : []));
        this.minzoom = input(...(ngDevMode ? [undefined, { debugName: "minzoom" }] : []));
        this.maxzoom = input(...(ngDevMode ? [undefined, { debugName: "maxzoom" }] : []));
        this.layerClick = output();
        this.layerDblClick = output();
        this.layerMouseDown = output();
        this.layerMouseUp = output();
        this.layerMouseEnter = output();
        this.layerMouseLeave = output();
        this.layerMouseMove = output();
        this.layerMouseOver = output();
        this.layerMouseOut = output();
        this.layerContextMenu = output();
        this.layerTouchStart = output();
        this.layerTouchEnd = output();
        this.layerTouchCancel = output();
        this.layerAdded = signal(false, ...(ngDevMode ? [{ debugName: "layerAdded" }] : []));
        this.sourceIdAdded = signal(null, ...(ngDevMode ? [{ debugName: "sourceIdAdded" }] : []));
    }
    ngOnInit() {
        this.mapService.mapLoaded$
            .pipe(switchMap(() => fromEvent(this.mapService.mapInstance, 'styledata').pipe(map(() => false), filter(() => !this.mapService.mapInstance.getLayer(this.id())), startWith(true))), takeUntilDestroyed(this.destroyRef))
            .subscribe((bindEvents) => this.init(bindEvents));
    }
    ngOnChanges(changes) {
        if (!this.layerAdded()) {
            return;
        }
        if (changes.paint && !changes.paint.isFirstChange()) {
            this.mapService.setAllLayerPaintProperty(this.id(), changes.paint.currentValue);
        }
        if (changes.layout && !changes.layout.isFirstChange()) {
            this.mapService.setAllLayerLayoutProperty(this.id(), changes.layout.currentValue);
        }
        if (changes.filter && !changes.filter.isFirstChange()) {
            this.mapService.setLayerFilter(this.id(), changes.filter.currentValue);
        }
        if (changes.before && !changes.before.isFirstChange()) {
            this.mapService.setLayerBefore(this.id(), changes.before.currentValue);
        }
        if ((changes.minzoom && !changes.minzoom.isFirstChange()) ||
            (changes.maxzoom && !changes.maxzoom.isFirstChange())) {
            this.mapService.setLayerZoomRange(this.id(), this.minzoom(), this.maxzoom());
        }
    }
    ngOnDestroy() {
        if (this.layerAdded()) {
            const sourceIdAdded = this.sourceIdAdded();
            this.mapService.removeLayer(this.id());
            if (sourceIdAdded !== null) {
                // Clean up any automatically created source for this layer
                if (this.mapService.getSource(sourceIdAdded)) {
                    this.mapService.removeSource(sourceIdAdded);
                }
            }
        }
    }
    init(bindEvents) {
        const layer = {
            layerOptions: {
                id: this.id(),
                type: this.type(),
                source: this.source(),
                metadata: this.metadata(),
                // eslint-disable-next-line @typescript-eslint/naming-convention
                'source-layer': this.sourceLayer(),
                minzoom: this.minzoom(),
                maxzoom: this.maxzoom(),
                filter: this.filter(),
                layout: this.layout(),
                paint: this.paint(),
            },
            layerEvents: {
                layerClick: this.layerClick,
                layerDblClick: this.layerDblClick,
                layerMouseDown: this.layerMouseDown,
                layerMouseUp: this.layerMouseUp,
                layerMouseEnter: this.layerMouseEnter,
                layerMouseLeave: this.layerMouseLeave,
                layerMouseMove: this.layerMouseMove,
                layerMouseOver: this.layerMouseOver,
                layerMouseOut: this.layerMouseOut,
                layerContextMenu: this.layerContextMenu,
                layerTouchStart: this.layerTouchStart,
                layerTouchEnd: this.layerTouchEnd,
                layerTouchCancel: this.layerTouchCancel,
            },
        };
        if (this.removeSource() && typeof this.source() !== 'string') {
            // There is no id of an existing source bound to this layer
            if (this.mapService.getSource(this.id()) === undefined) {
                // A source with this layer id doesn't exist so it will be created automatically in the addLayer call below
                this.sourceIdAdded.set(this.id());
            }
        }
        this.mapService.addLayer(layer, bindEvents, this.before());
        const sourceIdAdded = this.sourceIdAdded();
        if (sourceIdAdded !== null) {
            const getSource = this.mapService.getSource(sourceIdAdded);
            if (getSource === undefined) {
                // If it wasn't created for some reason then we don't want to clean it up
                this.sourceIdAdded.set(null);
            }
        }
        this.layerAdded.set(true);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: LayerComponent, isStandalone: true, selector: "mgl-layer", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: true, transformFunction: null }, source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: false, transformFunction: null }, metadata: { classPropertyName: "metadata", publicName: "metadata", isSignal: true, isRequired: false, transformFunction: null }, sourceLayer: { classPropertyName: "sourceLayer", publicName: "sourceLayer", isSignal: true, isRequired: false, transformFunction: null }, removeSource: { classPropertyName: "removeSource", publicName: "removeSource", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, paint: { classPropertyName: "paint", publicName: "paint", isSignal: true, isRequired: false, transformFunction: null }, before: { classPropertyName: "before", publicName: "before", isSignal: true, isRequired: false, transformFunction: null }, minzoom: { classPropertyName: "minzoom", publicName: "minzoom", isSignal: true, isRequired: false, transformFunction: null }, maxzoom: { classPropertyName: "maxzoom", publicName: "maxzoom", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { layerClick: "layerClick", layerDblClick: "layerDblClick", layerMouseDown: "layerMouseDown", layerMouseUp: "layerMouseUp", layerMouseEnter: "layerMouseEnter", layerMouseLeave: "layerMouseLeave", layerMouseMove: "layerMouseMove", layerMouseOver: "layerMouseOver", layerMouseOut: "layerMouseOut", layerContextMenu: "layerContextMenu", layerTouchStart: "layerTouchStart", layerTouchEnd: "layerTouchEnd", layerTouchCancel: "layerTouchCancel" }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: LayerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-layer',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: true }] }], source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: false }] }], metadata: [{ type: i0.Input, args: [{ isSignal: true, alias: "metadata", required: false }] }], sourceLayer: [{ type: i0.Input, args: [{ isSignal: true, alias: "sourceLayer", required: false }] }], removeSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeSource", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], paint: [{ type: i0.Input, args: [{ isSignal: true, alias: "paint", required: false }] }], before: [{ type: i0.Input, args: [{ isSignal: true, alias: "before", required: false }] }], minzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minzoom", required: false }] }], maxzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxzoom", required: false }] }], layerClick: [{ type: i0.Output, args: ["layerClick"] }], layerDblClick: [{ type: i0.Output, args: ["layerDblClick"] }], layerMouseDown: [{ type: i0.Output, args: ["layerMouseDown"] }], layerMouseUp: [{ type: i0.Output, args: ["layerMouseUp"] }], layerMouseEnter: [{ type: i0.Output, args: ["layerMouseEnter"] }], layerMouseLeave: [{ type: i0.Output, args: ["layerMouseLeave"] }], layerMouseMove: [{ type: i0.Output, args: ["layerMouseMove"] }], layerMouseOver: [{ type: i0.Output, args: ["layerMouseOver"] }], layerMouseOut: [{ type: i0.Output, args: ["layerMouseOut"] }], layerContextMenu: [{ type: i0.Output, args: ["layerContextMenu"] }], layerTouchStart: [{ type: i0.Output, args: ["layerTouchStart"] }], layerTouchEnd: [{ type: i0.Output, args: ["layerTouchEnd"] }], layerTouchCancel: [{ type: i0.Output, args: ["layerTouchCancel"] }] } });

/**
 * `mgl-map` - The main map component
 * @see [Map](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/)
 *
 * @category Map Component
 *
 * @example
 * ```typescript
 * ...
 * @Component({
 *   template: `
 *   <mgl-map
 *     [mapStyle]="'https://demotiles.maplibre.org/style.json'"
 *     [zoom]="[9]"
 *     [center]="[-74.50, 40]"
 *     (mapLoad)="map = $event"
 *   ></mgl-map>
 *   `,
 * ...
 * })
 * export class DisplayMapComponent {
 *   map: Map; // MapLibre GL Map object (MapLibre is ran outside angular zone, keep that in mind when binding events from this object)
 * ...
 * }
 * ```
 */
class MapComponent {
    get mapInstance() {
        return this.mapService.mapInstance;
    }
    constructor() {
        this.mapService = inject(MapService);
        this.elementRef = inject(ElementRef);
        /** Init input */
        this.collectResourceTiming = input(...(ngDevMode ? [undefined, { debugName: "collectResourceTiming" }] : []));
        /** Init input */
        this.crossSourceCollisions = input(...(ngDevMode ? [undefined, { debugName: "crossSourceCollisions" }] : []));
        /** Init input */
        this.customMapboxApiUrl = input(...(ngDevMode ? [undefined, { debugName: "customMapboxApiUrl" }] : []));
        /** Init input */
        this.fadeDuration = input(...(ngDevMode ? [undefined, { debugName: "fadeDuration" }] : []));
        /** Init input */
        this.hash = input(...(ngDevMode ? [undefined, { debugName: "hash" }] : []));
        /** Init input */
        this.refreshExpiredTiles = input(...(ngDevMode ? [undefined, { debugName: "refreshExpiredTiles" }] : []));
        /** Init input */
        this.canvasContextAttributes = input(...(ngDevMode ? [undefined, { debugName: "canvasContextAttributes" }] : []));
        /** Init input */
        this.bearingSnap = input(...(ngDevMode ? [undefined, { debugName: "bearingSnap" }] : []));
        /** Init input */
        this.interactive = input(...(ngDevMode ? [undefined, { debugName: "interactive" }] : []));
        /** Init input */
        this.pitchWithRotate = input(...(ngDevMode ? [undefined, { debugName: "pitchWithRotate" }] : []));
        /** Init input */
        this.clickTolerance = input(...(ngDevMode ? [undefined, { debugName: "clickTolerance" }] : []));
        /** Init input */
        this.attributionControl = input(...(ngDevMode ? [undefined, { debugName: "attributionControl" }] : []));
        /** Init input */
        this.logoPosition = input(...(ngDevMode ? [undefined, { debugName: "logoPosition" }] : []));
        /** Init input */
        this.maxTileCacheSize = input(...(ngDevMode ? [undefined, { debugName: "maxTileCacheSize" }] : []));
        /** Init input */
        this.localIdeographFontFamily = input(...(ngDevMode ? [undefined, { debugName: "localIdeographFontFamily" }] : []));
        /** Init input */
        this.trackResize = input(...(ngDevMode ? [undefined, { debugName: "trackResize" }] : []));
        /** Init input */
        this.transformRequest = input(...(ngDevMode ? [undefined, { debugName: "transformRequest" }] : []));
        /** Init input */
        this.bounds = input(...(ngDevMode ? [undefined, { debugName: "bounds" }] : []));
        /** Init input */
        this.locale = input(...(ngDevMode ? [undefined, { debugName: "locale" }] : []));
        /** Init input */
        this.cooperativeGestures = input(...(ngDevMode ? [undefined, { debugName: "cooperativeGestures" }] : []));
        /** Init input */
        this.cancelPendingTileRequestsWhileZooming = input(...(ngDevMode ? [undefined, { debugName: "cancelPendingTileRequestsWhileZooming" }] : []));
        /** Init input */
        this.centerClampedToGround = input(...(ngDevMode ? [undefined, { debugName: "centerClampedToGround" }] : []));
        /** Init input */
        this.maplibreLogo = input(...(ngDevMode ? [undefined, { debugName: "maplibreLogo" }] : []));
        /** Init input */
        this.maxCanvasSize = input(...(ngDevMode ? [undefined, { debugName: "maxCanvasSize" }] : []));
        /** Init input */
        this.maxTileCacheZoomLevels = input(...(ngDevMode ? [undefined, { debugName: "maxTileCacheZoomLevels" }] : []));
        /** Init input */
        this.pixelRatio = input(...(ngDevMode ? [undefined, { debugName: "pixelRatio" }] : []));
        /** Init input */
        this.rollEnabled = input(...(ngDevMode ? [undefined, { debugName: "rollEnabled" }] : []));
        /** Init input */
        this.transformCameraUpdate = input(...(ngDevMode ? [undefined, { debugName: "transformCameraUpdate" }] : []));
        /** Init input */
        this.validateStyle = input(...(ngDevMode ? [undefined, { debugName: "validateStyle" }] : []));
        /** Dynamic input */
        this.minZoom = input(...(ngDevMode ? [undefined, { debugName: "minZoom" }] : []));
        /** Dynamic input */
        this.maxZoom = input(...(ngDevMode ? [undefined, { debugName: "maxZoom" }] : []));
        /** Dynamic input */
        this.minPitch = input(...(ngDevMode ? [undefined, { debugName: "minPitch" }] : []));
        /** Dynamic input */
        this.maxPitch = input(...(ngDevMode ? [undefined, { debugName: "maxPitch" }] : []));
        /** Dynamic input */
        this.scrollZoom = input(...(ngDevMode ? [undefined, { debugName: "scrollZoom" }] : []));
        /** Dynamic input */
        this.dragRotate = input(...(ngDevMode ? [undefined, { debugName: "dragRotate" }] : []));
        /** Dynamic input */
        this.touchPitch = input(...(ngDevMode ? [undefined, { debugName: "touchPitch" }] : []));
        /** Dynamic input */
        this.touchZoomRotate = input(...(ngDevMode ? [undefined, { debugName: "touchZoomRotate" }] : []));
        /** Dynamic input */
        this.doubleClickZoom = input(...(ngDevMode ? [undefined, { debugName: "doubleClickZoom" }] : []));
        /** Dynamic input */
        this.keyboard = input(...(ngDevMode ? [undefined, { debugName: "keyboard" }] : []));
        /** Dynamic input */
        this.dragPan = input(...(ngDevMode ? [undefined, { debugName: "dragPan" }] : []));
        /** Dynamic input */
        this.boxZoom = input(...(ngDevMode ? [undefined, { debugName: "boxZoom" }] : []));
        /** Dynamic input */
        this.mapStyle = input.required(...(ngDevMode ? [{ debugName: "mapStyle" }] : []));
        /** Dynamic input */
        this.center = input(...(ngDevMode ? [undefined, { debugName: "center" }] : []));
        /** Dynamic input */
        this.maxBounds = input(...(ngDevMode ? [undefined, { debugName: "maxBounds" }] : []));
        /** Dynamic input */
        this.zoom = input(...(ngDevMode ? [undefined, { debugName: "zoom" }] : []));
        /** Dynamic input */
        this.bearing = input(...(ngDevMode ? [undefined, { debugName: "bearing" }] : []));
        /** Dynamic input */
        this.pitch = input(...(ngDevMode ? [undefined, { debugName: "pitch" }] : []));
        /** Dynamic input */
        this.roll = input(...(ngDevMode ? [undefined, { debugName: "roll" }] : []));
        /** Dynamic input */
        this.fitBoundsOptions = input(...(ngDevMode ? [undefined, { debugName: "fitBoundsOptions" }] : [])); // First value goes to options.fitBoundsOptions. Subsequents changes are passed to fitBounds
        /** Dynamic input */
        this.renderWorldCopies = input(...(ngDevMode ? [undefined, { debugName: "renderWorldCopies" }] : []));
        /** Dynamic input */
        this.elevation = input(...(ngDevMode ? [undefined, { debugName: "elevation" }] : []));
        /** Dynamic input that is not part of the `MapOptions` object */
        this.terrain = input(...(ngDevMode ? [undefined, { debugName: "terrain" }] : []));
        /** Dynamic input that is not part of the `MapOptions` object  */
        this.projection = input(...(ngDevMode ? [undefined, { debugName: "projection" }] : []));
        /** Added by ngx-mapbox-gl */
        this.movingMethod = input('flyTo', ...(ngDevMode ? [{ debugName: "movingMethod" }] : []));
        this.movingOptions = input(...(ngDevMode ? [undefined, { debugName: "movingOptions" }] : []));
        // => First value is a alias to bounds input (since mapbox 0.53.0). Subsequents changes are passed to fitBounds
        this.fitBounds = input(...(ngDevMode ? [undefined, { debugName: "fitBounds" }] : []));
        this.fitScreenCoordinates = input(...(ngDevMode ? [undefined, { debugName: "fitScreenCoordinates" }] : []));
        this.centerWithPanTo = input(...(ngDevMode ? [undefined, { debugName: "centerWithPanTo" }] : []));
        this.panToOptions = input(...(ngDevMode ? [undefined, { debugName: "panToOptions" }] : []));
        this.cursorStyle = input(...(ngDevMode ? [undefined, { debugName: "cursorStyle" }] : []));
        this.mapResize = output();
        this.mapRemove = output();
        this.mapMouseDown = output();
        this.mapMouseUp = output();
        this.mapMouseMove = output();
        this.mapClick = output();
        this.mapDblClick = output();
        this.mapMouseOver = output();
        this.mapMouseOut = output();
        this.mapContextMenu = output();
        this.mapTouchStart = output();
        this.mapTouchEnd = output();
        this.mapTouchMove = output();
        this.mapTouchCancel = output();
        this.mapWheel = output();
        this.moveStart = output();
        this.move = output();
        this.moveEnd = output();
        this.mapDragStart = output();
        this.mapDrag = output();
        this.mapDragEnd = output();
        this.zoomStart = output();
        this.zoomEvt = output();
        this.zoomEnd = output();
        this.rotateStart = output();
        this.rotate = output();
        this.rotateEnd = output();
        this.pitchStart = output();
        this.pitchEvt = output();
        this.pitchEnd = output();
        this.boxZoomStart = output();
        this.boxZoomEnd = output();
        this.boxZoomCancel = output();
        this.webGlContextLost = output();
        this.webGlContextRestored = output();
        this.mapLoad = output();
        this.idle = output();
        this.render = output();
        this.mapError = output();
        this.data = output();
        this.styleData = output();
        this.sourceData = output();
        this.dataLoading = output();
        this.styleDataLoading = output();
        this.sourceDataLoading = output();
        this.styleImageMissing = output();
        this.mapContainer = viewChild.required('container');
        afterNextRender(() => {
            if (this.canvasContextAttributes()?.preserveDrawingBuffer) {
                // This is to allow better interaction with the map state
                const htmlElement = this.elementRef.nativeElement;
                htmlElement.setAttribute('data-cy', 'map');
                this.mapLoad.subscribe(() => {
                    htmlElement.setAttribute('data-loaded', 'true');
                });
                this.idle.subscribe(() => {
                    htmlElement.setAttribute('data-idle', 'true');
                });
                this.render.subscribe(() => {
                    htmlElement.removeAttribute('data-idle');
                });
            }
            this.mapService.setup({
                mapOptions: {
                    collectResourceTiming: this.collectResourceTiming(),
                    container: this.mapContainer().nativeElement,
                    crossSourceCollisions: this.crossSourceCollisions(),
                    fadeDuration: this.fadeDuration(),
                    minZoom: this.minZoom(),
                    maxZoom: this.maxZoom(),
                    minPitch: this.minPitch(),
                    maxPitch: this.maxPitch(),
                    style: this.mapStyle(),
                    hash: this.hash(),
                    interactive: this.interactive(),
                    bearingSnap: this.bearingSnap(),
                    pitchWithRotate: this.pitchWithRotate(),
                    clickTolerance: this.clickTolerance(),
                    attributionControl: this.attributionControl(),
                    logoPosition: this.logoPosition(),
                    canvasContextAttributes: this.canvasContextAttributes(),
                    refreshExpiredTiles: this.refreshExpiredTiles(),
                    maxBounds: this.maxBounds(),
                    scrollZoom: this.scrollZoom(),
                    boxZoom: this.boxZoom(),
                    dragRotate: this.dragRotate(),
                    dragPan: this.dragPan(),
                    keyboard: this.keyboard(),
                    doubleClickZoom: this.doubleClickZoom(),
                    touchPitch: this.touchPitch(),
                    touchZoomRotate: this.touchZoomRotate(),
                    trackResize: this.trackResize(),
                    center: this.center(),
                    zoom: this.zoom(),
                    bearing: this.bearing(),
                    pitch: this.pitch(),
                    roll: this.roll(),
                    renderWorldCopies: this.renderWorldCopies(),
                    maxTileCacheSize: this.maxTileCacheSize(),
                    localIdeographFontFamily: this.localIdeographFontFamily(),
                    transformRequest: this.transformRequest(),
                    bounds: this.bounds() ? this.bounds() : this.fitBounds(),
                    fitBoundsOptions: this.fitBoundsOptions(),
                    locale: this.locale(),
                    cooperativeGestures: this.cooperativeGestures(),
                    cancelPendingTileRequestsWhileZooming: this.cancelPendingTileRequestsWhileZooming(),
                    centerClampedToGround: this.centerClampedToGround(),
                    elevation: this.elevation(),
                    maplibreLogo: this.maplibreLogo(),
                    maxCanvasSize: this.maxCanvasSize(),
                    maxTileCacheZoomLevels: this.maxTileCacheZoomLevels(),
                    pixelRatio: this.pixelRatio(),
                    rollEnabled: this.rollEnabled(),
                    transformCameraUpdate: this.transformCameraUpdate(),
                    validateStyle: this.validateStyle(),
                    terrain: this.terrain(),
                    projection: this.projection(),
                },
                mapEvents: this,
            });
            const cursorStyle = this.cursorStyle();
            if (cursorStyle) {
                this.mapService.changeCanvasCursor(cursorStyle);
            }
        });
        afterEveryRender(() => {
            this.mapService.clearMapElements();
        });
    }
    ngOnDestroy() {
        this.mapService.destroyMap();
    }
    async ngOnChanges(changes) {
        await firstValueFrom(this.mapService.mapCreated$);
        const zoom = this.zoom();
        const bearing = this.bearing();
        const pitch = this.pitch();
        const center = this.center();
        if (changes.cursorStyle && !changes.cursorStyle.isFirstChange()) {
            this.mapService.changeCanvasCursor(changes.cursorStyle.currentValue);
        }
        if (changes.minZoom && !changes.minZoom.isFirstChange()) {
            this.mapService.updateMinZoom(changes.minZoom.currentValue);
        }
        if (changes.maxZoom && !changes.maxZoom.isFirstChange()) {
            this.mapService.updateMaxZoom(changes.maxZoom.currentValue);
        }
        if (changes.minPitch && !changes.minPitch.isFirstChange()) {
            this.mapService.updateMinPitch(changes.minPitch.currentValue);
        }
        if (changes.maxPitch && !changes.maxPitch.isFirstChange()) {
            this.mapService.updateMaxPitch(changes.maxPitch.currentValue);
        }
        if (changes.renderWorldCopies &&
            !changes.renderWorldCopies.isFirstChange()) {
            this.mapService.updateRenderWorldCopies(changes.renderWorldCopies.currentValue);
        }
        if (changes.scrollZoom && !changes.scrollZoom.isFirstChange()) {
            this.mapService.updateScrollZoom(changes.scrollZoom.currentValue);
        }
        if (changes.dragRotate && !changes.dragRotate.isFirstChange()) {
            this.mapService.updateDragRotate(changes.dragRotate.currentValue);
        }
        if (changes.touchPitch && !changes.touchPitch.isFirstChange()) {
            this.mapService.updateTouchPitch(changes.touchPitch.currentValue);
        }
        if (changes.touchZoomRotate && !changes.touchZoomRotate.isFirstChange()) {
            this.mapService.updateTouchZoomRotate(changes.touchZoomRotate.currentValue);
        }
        if (changes.doubleClickZoom && !changes.doubleClickZoom.isFirstChange()) {
            this.mapService.updateDoubleClickZoom(changes.doubleClickZoom.currentValue);
        }
        if (changes.keyboard && !changes.keyboard.isFirstChange()) {
            this.mapService.updateKeyboard(changes.keyboard.currentValue);
        }
        if (changes.dragPan && !changes.dragPan.isFirstChange()) {
            this.mapService.updateDragPan(changes.dragPan.currentValue);
        }
        if (changes.boxZoom && !changes.boxZoom.isFirstChange()) {
            this.mapService.updateBoxZoom(changes.boxZoom.currentValue);
        }
        if (changes.mapStyle && !changes.mapStyle.isFirstChange()) {
            this.mapService.updateStyle(changes.mapStyle.currentValue);
        }
        if (changes.maxBounds && !changes.maxBounds.isFirstChange()) {
            this.mapService.updateMaxBounds(changes.maxBounds.currentValue);
        }
        if (changes.fitBounds &&
            changes.fitBounds.currentValue &&
            !changes.fitBounds.isFirstChange()) {
            this.mapService.fitBounds(changes.fitBounds.currentValue, this.fitBoundsOptions());
        }
        if (changes.fitScreenCoordinates &&
            changes.fitScreenCoordinates.currentValue) {
            if ((center || zoom || pitch || this.fitBounds()) &&
                changes.fitScreenCoordinates.isFirstChange()) {
                console.warn('[ngx-maplibre-gl] center / zoom / pitch / fitBounds inputs are being overridden by fitScreenCoordinates input');
            }
            this.mapService.fitScreenCoordinates(changes.fitScreenCoordinates.currentValue, bearing ? bearing[0] : 0, this.movingOptions());
        }
        if (this.centerWithPanTo() &&
            changes.center &&
            !changes.center.isFirstChange() &&
            !changes.zoom &&
            !changes.bearing &&
            !changes.pitch &&
            !changes.roll) {
            this.mapService.panTo(this.center(), this.panToOptions());
        }
        else if ((changes.center && !changes.center.isFirstChange()) ||
            (changes.zoom && !changes.zoom.isFirstChange()) ||
            (changes.bearing &&
                !changes.bearing.isFirstChange() &&
                !changes.fitScreenCoordinates) ||
            (changes.pitch && !changes.pitch.isFirstChange()) ||
            (changes.roll && !changes.roll.isFirstChange())) {
            this.mapService.move(this.movingMethod(), this.movingOptions(), changes.zoom && zoom ? zoom[0] : undefined, changes.center ? center : undefined, changes.bearing && bearing ? bearing[0] : undefined, changes.pitch && pitch ? pitch[0] : undefined, changes.roll ? changes.roll.currentValue : undefined);
        }
        if (changes.terrain && !changes.terrain.isFirstChange()) {
            this.mapService.setTerrain(changes.terrain.currentValue);
        }
        if (changes.projection && !changes.projection.isFirstChange()) {
            this.mapService.setProjection(changes.projection.currentValue);
        }
        if (changes.elevation && !changes.elevation.isFirstChange()) {
            this.mapService.setCenterElevation(changes.elevation.currentValue);
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MapComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: MapComponent, isStandalone: true, selector: "mgl-map", inputs: { collectResourceTiming: { classPropertyName: "collectResourceTiming", publicName: "collectResourceTiming", isSignal: true, isRequired: false, transformFunction: null }, crossSourceCollisions: { classPropertyName: "crossSourceCollisions", publicName: "crossSourceCollisions", isSignal: true, isRequired: false, transformFunction: null }, customMapboxApiUrl: { classPropertyName: "customMapboxApiUrl", publicName: "customMapboxApiUrl", isSignal: true, isRequired: false, transformFunction: null }, fadeDuration: { classPropertyName: "fadeDuration", publicName: "fadeDuration", isSignal: true, isRequired: false, transformFunction: null }, hash: { classPropertyName: "hash", publicName: "hash", isSignal: true, isRequired: false, transformFunction: null }, refreshExpiredTiles: { classPropertyName: "refreshExpiredTiles", publicName: "refreshExpiredTiles", isSignal: true, isRequired: false, transformFunction: null }, canvasContextAttributes: { classPropertyName: "canvasContextAttributes", publicName: "canvasContextAttributes", isSignal: true, isRequired: false, transformFunction: null }, bearingSnap: { classPropertyName: "bearingSnap", publicName: "bearingSnap", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, pitchWithRotate: { classPropertyName: "pitchWithRotate", publicName: "pitchWithRotate", isSignal: true, isRequired: false, transformFunction: null }, clickTolerance: { classPropertyName: "clickTolerance", publicName: "clickTolerance", isSignal: true, isRequired: false, transformFunction: null }, attributionControl: { classPropertyName: "attributionControl", publicName: "attributionControl", isSignal: true, isRequired: false, transformFunction: null }, logoPosition: { classPropertyName: "logoPosition", publicName: "logoPosition", isSignal: true, isRequired: false, transformFunction: null }, maxTileCacheSize: { classPropertyName: "maxTileCacheSize", publicName: "maxTileCacheSize", isSignal: true, isRequired: false, transformFunction: null }, localIdeographFontFamily: { classPropertyName: "localIdeographFontFamily", publicName: "localIdeographFontFamily", isSignal: true, isRequired: false, transformFunction: null }, trackResize: { classPropertyName: "trackResize", publicName: "trackResize", isSignal: true, isRequired: false, transformFunction: null }, transformRequest: { classPropertyName: "transformRequest", publicName: "transformRequest", isSignal: true, isRequired: false, transformFunction: null }, bounds: { classPropertyName: "bounds", publicName: "bounds", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, cooperativeGestures: { classPropertyName: "cooperativeGestures", publicName: "cooperativeGestures", isSignal: true, isRequired: false, transformFunction: null }, cancelPendingTileRequestsWhileZooming: { classPropertyName: "cancelPendingTileRequestsWhileZooming", publicName: "cancelPendingTileRequestsWhileZooming", isSignal: true, isRequired: false, transformFunction: null }, centerClampedToGround: { classPropertyName: "centerClampedToGround", publicName: "centerClampedToGround", isSignal: true, isRequired: false, transformFunction: null }, maplibreLogo: { classPropertyName: "maplibreLogo", publicName: "maplibreLogo", isSignal: true, isRequired: false, transformFunction: null }, maxCanvasSize: { classPropertyName: "maxCanvasSize", publicName: "maxCanvasSize", isSignal: true, isRequired: false, transformFunction: null }, maxTileCacheZoomLevels: { classPropertyName: "maxTileCacheZoomLevels", publicName: "maxTileCacheZoomLevels", isSignal: true, isRequired: false, transformFunction: null }, pixelRatio: { classPropertyName: "pixelRatio", publicName: "pixelRatio", isSignal: true, isRequired: false, transformFunction: null }, rollEnabled: { classPropertyName: "rollEnabled", publicName: "rollEnabled", isSignal: true, isRequired: false, transformFunction: null }, transformCameraUpdate: { classPropertyName: "transformCameraUpdate", publicName: "transformCameraUpdate", isSignal: true, isRequired: false, transformFunction: null }, validateStyle: { classPropertyName: "validateStyle", publicName: "validateStyle", isSignal: true, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: true, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: true, isRequired: false, transformFunction: null }, minPitch: { classPropertyName: "minPitch", publicName: "minPitch", isSignal: true, isRequired: false, transformFunction: null }, maxPitch: { classPropertyName: "maxPitch", publicName: "maxPitch", isSignal: true, isRequired: false, transformFunction: null }, scrollZoom: { classPropertyName: "scrollZoom", publicName: "scrollZoom", isSignal: true, isRequired: false, transformFunction: null }, dragRotate: { classPropertyName: "dragRotate", publicName: "dragRotate", isSignal: true, isRequired: false, transformFunction: null }, touchPitch: { classPropertyName: "touchPitch", publicName: "touchPitch", isSignal: true, isRequired: false, transformFunction: null }, touchZoomRotate: { classPropertyName: "touchZoomRotate", publicName: "touchZoomRotate", isSignal: true, isRequired: false, transformFunction: null }, doubleClickZoom: { classPropertyName: "doubleClickZoom", publicName: "doubleClickZoom", isSignal: true, isRequired: false, transformFunction: null }, keyboard: { classPropertyName: "keyboard", publicName: "keyboard", isSignal: true, isRequired: false, transformFunction: null }, dragPan: { classPropertyName: "dragPan", publicName: "dragPan", isSignal: true, isRequired: false, transformFunction: null }, boxZoom: { classPropertyName: "boxZoom", publicName: "boxZoom", isSignal: true, isRequired: false, transformFunction: null }, mapStyle: { classPropertyName: "mapStyle", publicName: "mapStyle", isSignal: true, isRequired: true, transformFunction: null }, center: { classPropertyName: "center", publicName: "center", isSignal: true, isRequired: false, transformFunction: null }, maxBounds: { classPropertyName: "maxBounds", publicName: "maxBounds", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, bearing: { classPropertyName: "bearing", publicName: "bearing", isSignal: true, isRequired: false, transformFunction: null }, pitch: { classPropertyName: "pitch", publicName: "pitch", isSignal: true, isRequired: false, transformFunction: null }, roll: { classPropertyName: "roll", publicName: "roll", isSignal: true, isRequired: false, transformFunction: null }, fitBoundsOptions: { classPropertyName: "fitBoundsOptions", publicName: "fitBoundsOptions", isSignal: true, isRequired: false, transformFunction: null }, renderWorldCopies: { classPropertyName: "renderWorldCopies", publicName: "renderWorldCopies", isSignal: true, isRequired: false, transformFunction: null }, elevation: { classPropertyName: "elevation", publicName: "elevation", isSignal: true, isRequired: false, transformFunction: null }, terrain: { classPropertyName: "terrain", publicName: "terrain", isSignal: true, isRequired: false, transformFunction: null }, projection: { classPropertyName: "projection", publicName: "projection", isSignal: true, isRequired: false, transformFunction: null }, movingMethod: { classPropertyName: "movingMethod", publicName: "movingMethod", isSignal: true, isRequired: false, transformFunction: null }, movingOptions: { classPropertyName: "movingOptions", publicName: "movingOptions", isSignal: true, isRequired: false, transformFunction: null }, fitBounds: { classPropertyName: "fitBounds", publicName: "fitBounds", isSignal: true, isRequired: false, transformFunction: null }, fitScreenCoordinates: { classPropertyName: "fitScreenCoordinates", publicName: "fitScreenCoordinates", isSignal: true, isRequired: false, transformFunction: null }, centerWithPanTo: { classPropertyName: "centerWithPanTo", publicName: "centerWithPanTo", isSignal: true, isRequired: false, transformFunction: null }, panToOptions: { classPropertyName: "panToOptions", publicName: "panToOptions", isSignal: true, isRequired: false, transformFunction: null }, cursorStyle: { classPropertyName: "cursorStyle", publicName: "cursorStyle", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { mapResize: "mapResize", mapRemove: "mapRemove", mapMouseDown: "mapMouseDown", mapMouseUp: "mapMouseUp", mapMouseMove: "mapMouseMove", mapClick: "mapClick", mapDblClick: "mapDblClick", mapMouseOver: "mapMouseOver", mapMouseOut: "mapMouseOut", mapContextMenu: "mapContextMenu", mapTouchStart: "mapTouchStart", mapTouchEnd: "mapTouchEnd", mapTouchMove: "mapTouchMove", mapTouchCancel: "mapTouchCancel", mapWheel: "mapWheel", moveStart: "moveStart", move: "move", moveEnd: "moveEnd", mapDragStart: "mapDragStart", mapDrag: "mapDrag", mapDragEnd: "mapDragEnd", zoomStart: "zoomStart", zoomEvt: "zoomEvt", zoomEnd: "zoomEnd", rotateStart: "rotateStart", rotate: "rotate", rotateEnd: "rotateEnd", pitchStart: "pitchStart", pitchEvt: "pitchEvt", pitchEnd: "pitchEnd", boxZoomStart: "boxZoomStart", boxZoomEnd: "boxZoomEnd", boxZoomCancel: "boxZoomCancel", webGlContextLost: "webGlContextLost", webGlContextRestored: "webGlContextRestored", mapLoad: "mapLoad", idle: "idle", render: "render", mapError: "mapError", data: "data", styleData: "styleData", sourceData: "sourceData", dataLoading: "dataLoading", styleDataLoading: "styleDataLoading", sourceDataLoading: "sourceDataLoading", styleImageMissing: "styleImageMissing" }, providers: [MapService], viewQueries: [{ propertyName: "mapContainer", first: true, predicate: ["container"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: '<div #container></div>', isInline: true, styles: [":host{display:block}div{height:100%;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MapComponent, decorators: [{
            type: Component,
            args: [{ selector: 'mgl-map', template: '<div #container></div>', providers: [MapService], changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{display:block}div{height:100%;width:100%}\n"] }]
        }], ctorParameters: () => [], propDecorators: { collectResourceTiming: [{ type: i0.Input, args: [{ isSignal: true, alias: "collectResourceTiming", required: false }] }], crossSourceCollisions: [{ type: i0.Input, args: [{ isSignal: true, alias: "crossSourceCollisions", required: false }] }], customMapboxApiUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "customMapboxApiUrl", required: false }] }], fadeDuration: [{ type: i0.Input, args: [{ isSignal: true, alias: "fadeDuration", required: false }] }], hash: [{ type: i0.Input, args: [{ isSignal: true, alias: "hash", required: false }] }], refreshExpiredTiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "refreshExpiredTiles", required: false }] }], canvasContextAttributes: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasContextAttributes", required: false }] }], bearingSnap: [{ type: i0.Input, args: [{ isSignal: true, alias: "bearingSnap", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], pitchWithRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "pitchWithRotate", required: false }] }], clickTolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickTolerance", required: false }] }], attributionControl: [{ type: i0.Input, args: [{ isSignal: true, alias: "attributionControl", required: false }] }], logoPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "logoPosition", required: false }] }], maxTileCacheSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTileCacheSize", required: false }] }], localIdeographFontFamily: [{ type: i0.Input, args: [{ isSignal: true, alias: "localIdeographFontFamily", required: false }] }], trackResize: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackResize", required: false }] }], transformRequest: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformRequest", required: false }] }], bounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "bounds", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], cooperativeGestures: [{ type: i0.Input, args: [{ isSignal: true, alias: "cooperativeGestures", required: false }] }], cancelPendingTileRequestsWhileZooming: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelPendingTileRequestsWhileZooming", required: false }] }], centerClampedToGround: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerClampedToGround", required: false }] }], maplibreLogo: [{ type: i0.Input, args: [{ isSignal: true, alias: "maplibreLogo", required: false }] }], maxCanvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxCanvasSize", required: false }] }], maxTileCacheZoomLevels: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTileCacheZoomLevels", required: false }] }], pixelRatio: [{ type: i0.Input, args: [{ isSignal: true, alias: "pixelRatio", required: false }] }], rollEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "rollEnabled", required: false }] }], transformCameraUpdate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformCameraUpdate", required: false }] }], validateStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "validateStyle", required: false }] }], minZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minZoom", required: false }] }], maxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxZoom", required: false }] }], minPitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "minPitch", required: false }] }], maxPitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxPitch", required: false }] }], scrollZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollZoom", required: false }] }], dragRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragRotate", required: false }] }], touchPitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "touchPitch", required: false }] }], touchZoomRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "touchZoomRotate", required: false }] }], doubleClickZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "doubleClickZoom", required: false }] }], keyboard: [{ type: i0.Input, args: [{ isSignal: true, alias: "keyboard", required: false }] }], dragPan: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragPan", required: false }] }], boxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "boxZoom", required: false }] }], mapStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "mapStyle", required: true }] }], center: [{ type: i0.Input, args: [{ isSignal: true, alias: "center", required: false }] }], maxBounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxBounds", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], bearing: [{ type: i0.Input, args: [{ isSignal: true, alias: "bearing", required: false }] }], pitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "pitch", required: false }] }], roll: [{ type: i0.Input, args: [{ isSignal: true, alias: "roll", required: false }] }], fitBoundsOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitBoundsOptions", required: false }] }], renderWorldCopies: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderWorldCopies", required: false }] }], elevation: [{ type: i0.Input, args: [{ isSignal: true, alias: "elevation", required: false }] }], terrain: [{ type: i0.Input, args: [{ isSignal: true, alias: "terrain", required: false }] }], projection: [{ type: i0.Input, args: [{ isSignal: true, alias: "projection", required: false }] }], movingMethod: [{ type: i0.Input, args: [{ isSignal: true, alias: "movingMethod", required: false }] }], movingOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "movingOptions", required: false }] }], fitBounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitBounds", required: false }] }], fitScreenCoordinates: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitScreenCoordinates", required: false }] }], centerWithPanTo: [{ type: i0.Input, args: [{ isSignal: true, alias: "centerWithPanTo", required: false }] }], panToOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "panToOptions", required: false }] }], cursorStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "cursorStyle", required: false }] }], mapResize: [{ type: i0.Output, args: ["mapResize"] }], mapRemove: [{ type: i0.Output, args: ["mapRemove"] }], mapMouseDown: [{ type: i0.Output, args: ["mapMouseDown"] }], mapMouseUp: [{ type: i0.Output, args: ["mapMouseUp"] }], mapMouseMove: [{ type: i0.Output, args: ["mapMouseMove"] }], mapClick: [{ type: i0.Output, args: ["mapClick"] }], mapDblClick: [{ type: i0.Output, args: ["mapDblClick"] }], mapMouseOver: [{ type: i0.Output, args: ["mapMouseOver"] }], mapMouseOut: [{ type: i0.Output, args: ["mapMouseOut"] }], mapContextMenu: [{ type: i0.Output, args: ["mapContextMenu"] }], mapTouchStart: [{ type: i0.Output, args: ["mapTouchStart"] }], mapTouchEnd: [{ type: i0.Output, args: ["mapTouchEnd"] }], mapTouchMove: [{ type: i0.Output, args: ["mapTouchMove"] }], mapTouchCancel: [{ type: i0.Output, args: ["mapTouchCancel"] }], mapWheel: [{ type: i0.Output, args: ["mapWheel"] }], moveStart: [{ type: i0.Output, args: ["moveStart"] }], move: [{ type: i0.Output, args: ["move"] }], moveEnd: [{ type: i0.Output, args: ["moveEnd"] }], mapDragStart: [{ type: i0.Output, args: ["mapDragStart"] }], mapDrag: [{ type: i0.Output, args: ["mapDrag"] }], mapDragEnd: [{ type: i0.Output, args: ["mapDragEnd"] }], zoomStart: [{ type: i0.Output, args: ["zoomStart"] }], zoomEvt: [{ type: i0.Output, args: ["zoomEvt"] }], zoomEnd: [{ type: i0.Output, args: ["zoomEnd"] }], rotateStart: [{ type: i0.Output, args: ["rotateStart"] }], rotate: [{ type: i0.Output, args: ["rotate"] }], rotateEnd: [{ type: i0.Output, args: ["rotateEnd"] }], pitchStart: [{ type: i0.Output, args: ["pitchStart"] }], pitchEvt: [{ type: i0.Output, args: ["pitchEvt"] }], pitchEnd: [{ type: i0.Output, args: ["pitchEnd"] }], boxZoomStart: [{ type: i0.Output, args: ["boxZoomStart"] }], boxZoomEnd: [{ type: i0.Output, args: ["boxZoomEnd"] }], boxZoomCancel: [{ type: i0.Output, args: ["boxZoomCancel"] }], webGlContextLost: [{ type: i0.Output, args: ["webGlContextLost"] }], webGlContextRestored: [{ type: i0.Output, args: ["webGlContextRestored"] }], mapLoad: [{ type: i0.Output, args: ["mapLoad"] }], idle: [{ type: i0.Output, args: ["idle"] }], render: [{ type: i0.Output, args: ["render"] }], mapError: [{ type: i0.Output, args: ["mapError"] }], data: [{ type: i0.Output, args: ["data"] }], styleData: [{ type: i0.Output, args: ["styleData"] }], sourceData: [{ type: i0.Output, args: ["sourceData"] }], dataLoading: [{ type: i0.Output, args: ["dataLoading"] }], styleDataLoading: [{ type: i0.Output, args: ["styleDataLoading"] }], sourceDataLoading: [{ type: i0.Output, args: ["sourceDataLoading"] }], styleImageMissing: [{ type: i0.Output, args: ["styleImageMissing"] }], mapContainer: [{ type: i0.ViewChild, args: ['container', { isSignal: true }] }] } });

/**
 * `mgl-marker` - a marker component
 * @see [Marker](https://maplibre.org/maplibre-gl-js/docs/API/classes/Marker/)
 *
 * @category Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-marker [lngLat]="[-66.324462890625, -16.024695711685304]">
 *     <div (click)="alert('Foo')" class="marker">Hello</div>
 *   </mgl-marker>
 * </mgl-map>
 * ```
 *
 * Note: Only use this if you **really** need to use HTML/Angular component to render your symbol. These markers are slow compared to a `Layer` of symbol because they're not rendered using WebGL.
 */
class MarkerComponent {
    constructor() {
        /** Init injection */
        this.mapService = inject(MapService);
        this.destroyRef = inject(DestroyRef);
        /** Init inputs */
        this.offset = input(...(ngDevMode ? [undefined, { debugName: "offset" }] : []));
        this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : []));
        this.clickTolerance = input(...(ngDevMode ? [undefined, { debugName: "clickTolerance" }] : []));
        this.color = input(...(ngDevMode ? [undefined, { debugName: "color" }] : []));
        this.scale = input(...(ngDevMode ? [undefined, { debugName: "scale" }] : []));
        this.opacity = input(...(ngDevMode ? [undefined, { debugName: "opacity" }] : []));
        this.opacityWhenCovered = input(...(ngDevMode ? [undefined, { debugName: "opacityWhenCovered" }] : []));
        this.subpixelPositioning = input(...(ngDevMode ? [undefined, { debugName: "subpixelPositioning" }] : []));
        /** Dynamic input */
        this.feature = input(...(ngDevMode ? [undefined, { debugName: "feature" }] : []));
        this.lngLat = input(...(ngDevMode ? [undefined, { debugName: "lngLat" }] : []));
        this.draggable = input(...(ngDevMode ? [undefined, { debugName: "draggable" }] : []));
        this.popupShown = input(...(ngDevMode ? [undefined, { debugName: "popupShown" }] : []));
        this.className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
        this.pitchAlignment = input(...(ngDevMode ? [undefined, { debugName: "pitchAlignment" }] : []));
        this.rotationAlignment = input(...(ngDevMode ? [undefined, { debugName: "rotationAlignment" }] : []));
        this.rotation = input(...(ngDevMode ? [undefined, { debugName: "rotation" }] : []));
        this.markerDragStart = output();
        this.markerDragEnd = output();
        this.markerDrag = output();
        this.content = viewChild.required('content');
        this.markerInstance = signal(null, ...(ngDevMode ? [{ debugName: "markerInstance" }] : []));
        afterNextRender(() => {
            this.mapService.mapCreated$
                .pipe(takeUntilDestroyed(this.destroyRef))
                .subscribe(() => {
                const marker = this.mapService.addMarker({
                    markersOptions: {
                        element: this.content().nativeElement,
                        feature: this.feature(),
                        lngLat: this.lngLat(),
                        offset: this.offset(),
                        anchor: this.anchor(),
                        color: this.color(),
                        scale: this.scale(),
                        draggable: !!this.draggable(),
                        clickTolerance: this.clickTolerance(),
                        rotation: this.rotation(),
                        rotationAlignment: this.rotationAlignment(),
                        pitchAlignment: this.pitchAlignment(),
                        opacity: this.opacity(),
                        opacityWhenCovered: this.opacityWhenCovered(),
                        subpixelPositioning: this.subpixelPositioning(),
                    },
                    markersEvents: {
                        markerDragStart: this.markerDragStart,
                        markerDrag: this.markerDrag,
                        markerDragEnd: this.markerDragEnd,
                    },
                });
                this.markerInstance.set(marker);
            });
        });
    }
    ngOnDestroy() {
        this.removeMarker();
    }
    ngOnInit() {
        if (this.feature() && this.lngLat()) {
            throw new Error('feature and lngLat input are mutually exclusive');
        }
    }
    ngOnChanges(changes) {
        const markerInstance = this.markerInstance();
        if (changes.lngLat && !changes.lngLat.isFirstChange()) {
            markerInstance.setLngLat(changes.lngLat.currentValue);
        }
        if (changes.feature && !changes.feature.isFirstChange()) {
            markerInstance.setLngLat(changes.feature.currentValue.geometry.coordinates);
        }
        if (changes.draggable && !changes.draggable.isFirstChange()) {
            markerInstance.setDraggable(!!changes.draggable.currentValue);
        }
        if (changes.popupShown && !changes.popupShown.isFirstChange()) {
            changes.popupShown.currentValue
                ? markerInstance.getPopup().addTo(this.mapService.mapInstance)
                : markerInstance.getPopup().remove();
        }
        if (changes.pitchAlignment && !changes.pitchAlignment.isFirstChange()) {
            markerInstance.setPitchAlignment(changes.pitchAlignment.currentValue);
        }
        if (changes.rotationAlignment &&
            !changes.rotationAlignment.isFirstChange()) {
            markerInstance.setRotationAlignment(changes.rotationAlignment.currentValue);
        }
        if (changes.rotation && !changes.rotation.isFirstChange()) {
            markerInstance.setRotation(changes.rotation.currentValue);
        }
    }
    removeMarker() {
        this.mapService.removeMarker(this.markerInstance());
        this.markerInstance.set(null);
    }
    togglePopup() {
        this.markerInstance().togglePopup();
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MarkerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: MarkerComponent, isStandalone: true, selector: "mgl-marker", inputs: { offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, clickTolerance: { classPropertyName: "clickTolerance", publicName: "clickTolerance", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, opacity: { classPropertyName: "opacity", publicName: "opacity", isSignal: true, isRequired: false, transformFunction: null }, opacityWhenCovered: { classPropertyName: "opacityWhenCovered", publicName: "opacityWhenCovered", isSignal: true, isRequired: false, transformFunction: null }, subpixelPositioning: { classPropertyName: "subpixelPositioning", publicName: "subpixelPositioning", isSignal: true, isRequired: false, transformFunction: null }, feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null }, lngLat: { classPropertyName: "lngLat", publicName: "lngLat", isSignal: true, isRequired: false, transformFunction: null }, draggable: { classPropertyName: "draggable", publicName: "draggable", isSignal: true, isRequired: false, transformFunction: null }, popupShown: { classPropertyName: "popupShown", publicName: "popupShown", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, pitchAlignment: { classPropertyName: "pitchAlignment", publicName: "pitchAlignment", isSignal: true, isRequired: false, transformFunction: null }, rotationAlignment: { classPropertyName: "rotationAlignment", publicName: "rotationAlignment", isSignal: true, isRequired: false, transformFunction: null }, rotation: { classPropertyName: "rotation", publicName: "rotation", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { markerDragStart: "markerDragStart", markerDragEnd: "markerDragEnd", markerDrag: "markerDrag" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: `<div [class]="className()" #content>
    <ng-content></ng-content>
  </div>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MarkerComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-marker',
                    template: `<div [class]="className()" #content>
    <ng-content></ng-content>
  </div>`,
                    encapsulation: ViewEncapsulation.None,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], ctorParameters: () => [], propDecorators: { offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], clickTolerance: [{ type: i0.Input, args: [{ isSignal: true, alias: "clickTolerance", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], scale: [{ type: i0.Input, args: [{ isSignal: true, alias: "scale", required: false }] }], opacity: [{ type: i0.Input, args: [{ isSignal: true, alias: "opacity", required: false }] }], opacityWhenCovered: [{ type: i0.Input, args: [{ isSignal: true, alias: "opacityWhenCovered", required: false }] }], subpixelPositioning: [{ type: i0.Input, args: [{ isSignal: true, alias: "subpixelPositioning", required: false }] }], feature: [{ type: i0.Input, args: [{ isSignal: true, alias: "feature", required: false }] }], lngLat: [{ type: i0.Input, args: [{ isSignal: true, alias: "lngLat", required: false }] }], draggable: [{ type: i0.Input, args: [{ isSignal: true, alias: "draggable", required: false }] }], popupShown: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupShown", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], pitchAlignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "pitchAlignment", required: false }] }], rotationAlignment: [{ type: i0.Input, args: [{ isSignal: true, alias: "rotationAlignment", required: false }] }], rotation: [{ type: i0.Input, args: [{ isSignal: true, alias: "rotation", required: false }] }], markerDragStart: [{ type: i0.Output, args: ["markerDragStart"] }], markerDragEnd: [{ type: i0.Output, args: ["markerDragEnd"] }], markerDrag: [{ type: i0.Output, args: ["markerDrag"] }], content: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });

/**
 * a template directive for point for {@link MarkersForClustersComponent}
 *
 * @category Directives
 */
class PointDirective {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: PointDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: PointDirective, isStandalone: true, selector: "ng-template[mglPoint]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: PointDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'ng-template[mglPoint]',
                }]
        }] });
/**
 * a template directive for clustered point for {@link MarkersForClustersComponent}
 *
 * @category Directives
 */
class ClusterPointDirective {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ClusterPointDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: ClusterPointDirective, isStandalone: true, selector: "ng-template[mglClusterPoint]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ClusterPointDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: 'ng-template[mglClusterPoint]',
                }]
        }] });
let uniqId = 0;
/**
 * [ngx] `mgl-markers-for-clusters` - an HTML marker component for clustered points.
 * Requires a geojson source that is clustered.
 *
 * @category Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-markers-for-cluster [source]="myGeoJsonclusteredSource">
 *     <ng-template mglPoint let-feature> Marker! </ng-template>
 *     <ng-template mglClusterPoint let-feature>
 *       ClusterId: {{feature.properties?.cluster_id}}, Points:
 *       {{feature.properties?.point_count}}
 *     </ng-template>
 *   </mgl-markers-for-cluster>
 * </mgl-map>
 * ```
 *
 * Note: Only use this if you **really** need to use HTML/Angular component to render your symbols. This is **slower** than rendering symbols in WebGL.
 */
class MarkersForClustersComponent {
    constructor() {
        this.destroyRef = inject(DestroyRef);
        this.mapService = inject(MapService);
        this.ngZone = inject(NgZone);
        /** Init input */
        this.source = input.required(...(ngDevMode ? [{ debugName: "source" }] : []));
        /** @hidden */
        this.pointTpl = contentChild(PointDirective, { ...(ngDevMode ? { debugName: "pointTpl" } : {}), read: TemplateRef });
        /** @hidden */
        this.clusterPointTpl = contentChild(ClusterPointDirective, { ...(ngDevMode ? { debugName: "clusterPointTpl" } : {}), read: TemplateRef });
        /** @hidden */
        this.clusterPoints = signal([], ...(ngDevMode ? [{ debugName: "clusterPoints" }] : []));
        /** @hidden */
        this.layerId = `mgl-markers-for-clusters-${uniqId++}`;
        afterNextRender(() => {
            const clusterDataUpdate = () => fromEvent(this.mapService.mapInstance, 'data').pipe(filter((e) => e.sourceId === this.source() &&
                e.sourceDataType !== 'metadata' &&
                this.mapService.mapInstance.isSourceLoaded(this.source())));
            this.mapService.mapCreated$
                .pipe(switchMap(clusterDataUpdate), switchMap(() => merge(fromEvent(this.mapService.mapInstance, 'move'), fromEvent(this.mapService.mapInstance, 'moveend')).pipe(startWith(undefined))))
                .pipe(takeUntilDestroyed(this.destroyRef))
                .subscribe(() => {
                this.ngZone.run(() => {
                    this.updateCluster();
                });
            });
        });
    }
    updateCluster() {
        const params = this.getClusterParams(this.pointTpl());
        this.clusterPoints.set(this.mapService.mapInstance.queryRenderedFeatures(params));
    }
    getClusterParams(pointTpl) {
        if (!pointTpl) {
            return { layers: [this.layerId], filter: ['==', 'cluster', true] };
        }
        return { layers: [this.layerId] };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MarkersForClustersComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: MarkersForClustersComponent, isStandalone: true, selector: "mgl-markers-for-clusters", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null } }, queries: [{ propertyName: "pointTpl", first: true, predicate: PointDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "clusterPointTpl", first: true, predicate: ClusterPointDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: `
    <mgl-layer
      [id]="layerId"
      [source]="source()"
      type="circle"
      [paint]="{ 'circle-radius': 0 }"
    ></mgl-layer>
    @for (feature of clusterPoints(); track $index) { 
      @if (feature.properties.cluster) {
        <mgl-marker [feature]="feature">
          <ng-container
            *ngTemplateOutlet="clusterPointTpl(); context: { $implicit: feature }"
          ></ng-container>
        </mgl-marker>
      } @else {
        <mgl-marker [feature]="feature">
          <ng-container
            *ngTemplateOutlet="pointTpl(); context: { $implicit: feature }"
          ></ng-container>
        </mgl-marker>
      } 
    }`, isInline: true, dependencies: [{ kind: "component", type: LayerComponent, selector: "mgl-layer", inputs: ["id", "type", "source", "metadata", "sourceLayer", "removeSource", "filter", "layout", "paint", "before", "minzoom", "maxzoom"], outputs: ["layerClick", "layerDblClick", "layerMouseDown", "layerMouseUp", "layerMouseEnter", "layerMouseLeave", "layerMouseMove", "layerMouseOver", "layerMouseOut", "layerContextMenu", "layerTouchStart", "layerTouchEnd", "layerTouchCancel"] }, { kind: "component", type: MarkerComponent, selector: "mgl-marker", inputs: ["offset", "anchor", "clickTolerance", "color", "scale", "opacity", "opacityWhenCovered", "subpixelPositioning", "feature", "lngLat", "draggable", "popupShown", "className", "pitchAlignment", "rotationAlignment", "rotation"], outputs: ["markerDragStart", "markerDragEnd", "markerDrag"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: MarkersForClustersComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-markers-for-clusters',
                    template: `
    <mgl-layer
      [id]="layerId"
      [source]="source()"
      type="circle"
      [paint]="{ 'circle-radius': 0 }"
    ></mgl-layer>
    @for (feature of clusterPoints(); track $index) { 
      @if (feature.properties.cluster) {
        <mgl-marker [feature]="feature">
          <ng-container
            *ngTemplateOutlet="clusterPointTpl(); context: { $implicit: feature }"
          ></ng-container>
        </mgl-marker>
      } @else {
        <mgl-marker [feature]="feature">
          <ng-container
            *ngTemplateOutlet="pointTpl(); context: { $implicit: feature }"
          ></ng-container>
        </mgl-marker>
      } 
    }`,
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    preserveWhitespaces: false,
                    imports: [LayerComponent, MarkerComponent, NgTemplateOutlet],
                }]
        }], ctorParameters: () => [], propDecorators: { source: [{ type: i0.Input, args: [{ isSignal: true, alias: "source", required: true }] }], pointTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => PointDirective), { ...{
                            read: TemplateRef,
                        }, isSignal: true }] }], clusterPointTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ClusterPointDirective), { ...{
                            read: TemplateRef,
                        }, isSignal: true }] }] } });

/**
 * `mgl-popup` - a popup component
 * @see [Popup](https://maplibre.org/maplibre-gl-js/docs/API/classes/Popup/)
 *
 * @category Components
 *
 * @example
 * ```html
 * ...
 * <mgl-map ...>
 *   <mgl-popup [lngLat]="[-96, 37.8]" [closeOnClick]="false">
 *     <h1>Hello world !</h1>
 *   </mgl-popup>
 *   ...
 *   <mgl-marker #myMarker ...> ... </mgl-marker>
 *   <mgl-popup [marker]="myMarker"> Hello from marker ! </mgl-popup>
 * </mgl-map>
 * ```
 */
class PopupComponent {
    constructor() {
        /** Init injection */
        this.destroyRef = inject(DestroyRef);
        this.mapService = inject(MapService);
        /** Init input */
        this.closeButton = input(...(ngDevMode ? [undefined, { debugName: "closeButton" }] : []));
        /** Init input */
        this.closeOnClick = input(...(ngDevMode ? [undefined, { debugName: "closeOnClick" }] : []));
        /** Init input */
        this.closeOnMove = input(...(ngDevMode ? [undefined, { debugName: "closeOnMove" }] : []));
        /** Init input */
        this.focusAfterOpen = input(...(ngDevMode ? [undefined, { debugName: "focusAfterOpen" }] : []));
        /** Init input */
        this.anchor = input(...(ngDevMode ? [undefined, { debugName: "anchor" }] : []));
        /** Init input */
        this.className = input(...(ngDevMode ? [undefined, { debugName: "className" }] : []));
        /** Init input */
        this.maxWidth = input(...(ngDevMode ? [undefined, { debugName: "maxWidth" }] : []));
        /** Init input */
        this.subpixelPositioning = input(...(ngDevMode ? [undefined, { debugName: "subpixelPositioning" }] : []));
        /**
         * Dynamic input [ngx]
         * Mutually exclusive with `lngLat`
         */
        this.feature = input(...(ngDevMode ? [undefined, { debugName: "feature" }] : []));
        /** Dynamic input */
        this.lngLat = input(...(ngDevMode ? [undefined, { debugName: "lngLat" }] : []));
        /**
         * Dynamic input [ngx]
         * The targeted marker
         */
        this.marker = input(...(ngDevMode ? [undefined, { debugName: "marker" }] : []));
        /** Dynamic input */
        this.offset = input(...(ngDevMode ? [undefined, { debugName: "offset" }] : []));
        this.popupClose = output();
        this.popupOpen = output();
        /** @hidden */
        this.content = viewChild.required('content');
        this.popupInstance = null;
        afterNextRender(() => {
            this.popupInstance = this.createPopup();
            this.addPopup(this.popupInstance)
                .pipe(takeUntilDestroyed(this.destroyRef))
                .subscribe();
        });
    }
    ngOnInit() {
        if ((this.lngLat() && this.marker()) ||
            (this.feature() && this.lngLat()) ||
            (this.feature() && this.marker())) {
            throw new Error('marker, lngLat, feature input are mutually exclusive');
        }
    }
    ngOnChanges(changes) {
        if (changes.feature && !changes.feature.isFirstChange()) {
            const newlngLat = this.getLngLat(this.lngLat(), this.feature());
            this.mapService.removePopupFromMap(this.popupInstance);
            const popupInstanceTmp = this.createPopup();
            this.mapService.addPopupToMap(popupInstanceTmp, newlngLat);
            this.popupInstance = popupInstanceTmp;
        }
        if (changes.lngLat && !changes.lngLat.isFirstChange()) {
            this.popupInstance.setLngLat(changes.lngLat.currentValue);
        }
        if (changes.marker && !changes.marker.isFirstChange()) {
            const previousMarker = changes.marker.previousValue;
            const previousMarkerInstance = previousMarker.markerInstance();
            if (previousMarkerInstance) {
                this.mapService.removePopupFromMarker(previousMarkerInstance);
            }
            const markerInstance = this.marker()?.markerInstance();
            if (markerInstance && this.popupInstance) {
                this.mapService.addPopupToMarker(markerInstance, this.popupInstance);
            }
        }
        if (changes.offset &&
            !changes.offset.isFirstChange() &&
            this.popupInstance) {
            this.popupInstance.setOffset(changes.offset.currentValue);
        }
    }
    ngOnDestroy() {
        this.removePopupFromMarker();
    }
    createPopup() {
        return this.mapService.createPopup({
            popupOptions: {
                closeButton: this.closeButton(),
                closeOnClick: this.closeOnClick(),
                closeOnMove: this.closeOnMove(),
                focusAfterOpen: this.focusAfterOpen(),
                anchor: this.anchor(),
                offset: this.offset(),
                className: this.className(),
                maxWidth: this.maxWidth(),
                subpixelPositioning: this.subpixelPositioning(),
            },
            popupEvents: {
                popupOpen: this.popupOpen,
                popupClose: this.popupClose,
            },
        }, this.content().nativeElement);
    }
    addPopup(popup) {
        return this.mapService.mapCreated$.pipe(tap$1(() => {
            const lngLat = this.lngLat();
            const feature = this.feature();
            const markerInstance = this.marker()?.markerInstance();
            if (lngLat || feature) {
                this.mapService.addPopupToMap(popup, this.getLngLat(lngLat, feature));
            }
            else if (markerInstance) {
                this.mapService.addPopupToMarker(markerInstance, popup);
            }
            else {
                throw new Error('mgl-popup need either lngLat/marker/feature to be set');
            }
        }));
    }
    removePopupFromMarker() {
        if (this.popupInstance) {
            const markerInstance = this.marker()?.markerInstance();
            if (this.lngLat() || this.feature()) {
                this.mapService.removePopupFromMap(this.popupInstance);
            }
            else if (markerInstance) {
                this.mapService.removePopupFromMarker(markerInstance);
            }
            else {
                this.mapService.removePopupFromMap(this.popupInstance);
            }
        }
        this.popupInstance = null;
    }
    getLngLat(lngLat, feature) {
        if (lngLat) {
            return lngLat;
        }
        else if (feature) {
            return feature.geometry.coordinates;
        }
        throw new Error('lngLat or feature value is required');
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: PopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.0.6", type: PopupComponent, isStandalone: true, selector: "mgl-popup", inputs: { closeButton: { classPropertyName: "closeButton", publicName: "closeButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnClick: { classPropertyName: "closeOnClick", publicName: "closeOnClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnMove: { classPropertyName: "closeOnMove", publicName: "closeOnMove", isSignal: true, isRequired: false, transformFunction: null }, focusAfterOpen: { classPropertyName: "focusAfterOpen", publicName: "focusAfterOpen", isSignal: true, isRequired: false, transformFunction: null }, anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, subpixelPositioning: { classPropertyName: "subpixelPositioning", publicName: "subpixelPositioning", isSignal: true, isRequired: false, transformFunction: null }, feature: { classPropertyName: "feature", publicName: "feature", isSignal: true, isRequired: false, transformFunction: null }, lngLat: { classPropertyName: "lngLat", publicName: "lngLat", isSignal: true, isRequired: false, transformFunction: null }, marker: { classPropertyName: "marker", publicName: "marker", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { popupClose: "popupClose", popupOpen: "popupOpen" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], usesOnChanges: true, ngImport: i0, template: '<div #content data-cy="mgl-popup"><ng-content></ng-content></div>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: PopupComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-popup',
                    template: '<div #content data-cy="mgl-popup"><ng-content></ng-content></div>',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], ctorParameters: () => [], propDecorators: { closeButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeButton", required: false }] }], closeOnClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnClick", required: false }] }], closeOnMove: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnMove", required: false }] }], focusAfterOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusAfterOpen", required: false }] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], subpixelPositioning: [{ type: i0.Input, args: [{ isSignal: true, alias: "subpixelPositioning", required: false }] }], feature: [{ type: i0.Input, args: [{ isSignal: true, alias: "feature", required: false }] }], lngLat: [{ type: i0.Input, args: [{ isSignal: true, alias: "lngLat", required: false }] }], marker: [{ type: i0.Input, args: [{ isSignal: true, alias: "marker", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], popupClose: [{ type: i0.Output, args: ["popupClose"] }], popupOpen: [{ type: i0.Output, args: ["popupOpen"] }], content: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }] } });

/**
 * `mgl-canvas-source` - a canvas source component
 * @see [canvas](https://maplibre.org/maplibre-style-spec/sources/#canvas)
 *
 * @category Source Components
 */
class CanvasSourceComponent {
    constructor() {
        /** Init injections */
        this.sourceDirective = inject(SourceDirective);
        /** Dynamic input */
        this.coordinates = input.required(...(ngDevMode ? [{ debugName: "coordinates" }] : []));
        /** Dynamic input */
        this.canvas = input.required(...(ngDevMode ? [{ debugName: "canvas" }] : []));
        /** Dynamic input */
        this.animate = input(...(ngDevMode ? [undefined, { debugName: "animate" }] : []));
        this.sourceDirective.loadSource$
            .pipe(tap$1(() => this.sourceDirective.addSource(this.getCanvasSourceSpecification())), takeUntilDestroyed())
            .subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if ((changes.canvas && !changes.canvas.isFirstChange()) ||
            (changes.animate && !changes.animate.isFirstChange())) {
            this.sourceDirective.refresh();
        }
        else if (changes.coordinates && !changes.coordinates.isFirstChange()) {
            const source = this.sourceDirective.getSource();
            if (source === undefined) {
                return;
            }
            source.setCoordinates(changes.coordinates.currentValue);
        }
    }
    getCanvasSourceSpecification() {
        return {
            type: 'canvas',
            coordinates: this.coordinates(),
            canvas: this.canvas(),
            animate: this.animate(),
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CanvasSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: CanvasSourceComponent, isStandalone: true, selector: "mgl-canvas-source", inputs: { coordinates: { classPropertyName: "coordinates", publicName: "coordinates", isSignal: true, isRequired: true, transformFunction: null }, canvas: { classPropertyName: "canvas", publicName: "canvas", isSignal: true, isRequired: true, transformFunction: null }, animate: { classPropertyName: "animate", publicName: "animate", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: CanvasSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-canvas-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { coordinates: [{ type: i0.Input, args: [{ isSignal: true, alias: "coordinates", required: true }] }], canvas: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvas", required: true }] }], animate: [{ type: i0.Input, args: [{ isSignal: true, alias: "animate", required: false }] }] } });

/**
 * `mgl-image-source` - an image source component
 * @see [image](https://maplibre.org/maplibre-style-spec/sources/#image)
 *
 * @category Source Components
 */
class ImageSourceComponent {
    constructor() {
        /** Init injection */
        this.destroyRef = inject(DestroyRef);
        this.mapService = inject(MapService);
        /** Init inputs */
        this.id = input.required(...(ngDevMode ? [{ debugName: "id" }] : []));
        /** Dynamic inputs */
        this.url = input.required(...(ngDevMode ? [{ debugName: "url" }] : []));
        this.coordinates = input.required(...(ngDevMode ? [{ debugName: "coordinates" }] : []));
        this.type = 'image';
        this.sourceId = signal(null, ...(ngDevMode ? [{ debugName: "sourceId" }] : []));
    }
    ngOnInit() {
        this.mapService.mapLoaded$
            .pipe(takeUntilDestroyed(this.destroyRef))
            .subscribe(() => this.addSource());
    }
    ngOnChanges(changes) {
        const sourceId = this.sourceId();
        if (sourceId === null) {
            return;
        }
        const source = this.mapService.getSource(sourceId);
        if (source === undefined) {
            return;
        }
        source.updateImage({
            url: changes.url === undefined ? undefined : this.url(),
            coordinates: changes.coordinates === undefined ? undefined : this.coordinates(),
        });
    }
    ngOnDestroy() {
        const sourceId = this.sourceId();
        if (sourceId !== null) {
            this.mapService.removeSource(sourceId);
            this.sourceId.set(null);
        }
    }
    addSource() {
        const imageSource = {
            type: 'image',
            url: this.url(),
            coordinates: this.coordinates(),
        };
        this.mapService.addSource(this.id(), imageSource);
        this.sourceId.set(this.id());
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImageSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: ImageSourceComponent, isStandalone: true, selector: "mgl-image-source", inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: true, transformFunction: null }, url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: true, transformFunction: null }, coordinates: { classPropertyName: "coordinates", publicName: "coordinates", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: ImageSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-image-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: true }] }], url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: true }] }], coordinates: [{ type: i0.Input, args: [{ isSignal: true, alias: "coordinates", required: true }] }] } });

/**
 * `mgl-raster-dem-source` - a raster DEM source
 * @see [raster DEM](https://maplibre.org/maplibre-style-spec/sources/#raster-dem)
 *
 * @category Source Components
 */
class RasterDemSourceComponent {
    constructor() {
        /** Init injections */
        this.sourceDirective = inject(SourceDirective);
        /** Dynamic input */
        this.url = input(...(ngDevMode ? [undefined, { debugName: "url" }] : []));
        /** Dynamic input */
        this.tiles = input(...(ngDevMode ? [undefined, { debugName: "tiles" }] : []));
        /** Dynamic input */
        this.bounds = input(...(ngDevMode ? [undefined, { debugName: "bounds" }] : []));
        /** Dynamic input */
        this.minzoom = input(...(ngDevMode ? [undefined, { debugName: "minzoom" }] : []));
        /** Dynamic input */
        this.maxzoom = input(...(ngDevMode ? [undefined, { debugName: "maxzoom" }] : []));
        /** Dynamic input */
        this.tileSize = input(...(ngDevMode ? [undefined, { debugName: "tileSize" }] : []));
        /** Dynamic input */
        this.attribution = input(...(ngDevMode ? [undefined, { debugName: "attribution" }] : []));
        /** Dynamic input */
        this.encoding = input(...(ngDevMode ? [undefined, { debugName: "encoding" }] : []));
        this.sourceDirective.loadSource$
            .pipe(tap(() => this.sourceDirective.addSource(this.getRasterDEMSourceSpecification())), takeUntilDestroyed())
            .subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if ((changes.url && !changes.url.isFirstChange()) ||
            (changes.tiles && !changes.tiles.isFirstChange()) ||
            (changes.bounds && !changes.bounds.isFirstChange()) ||
            (changes.minzoom && !changes.minzoom.isFirstChange()) ||
            (changes.maxzoom && !changes.maxzoom.isFirstChange()) ||
            (changes.tileSize && !changes.tileSize.isFirstChange()) ||
            (changes.attribution && !changes.attribution.isFirstChange()) ||
            (changes.encoding && !changes.encoding.isFirstChange())) {
            this.sourceDirective.refresh();
        }
    }
    getRasterDEMSourceSpecification() {
        return {
            type: 'raster-dem',
            url: this.url(),
            tiles: this.tiles(),
            bounds: this.bounds(),
            minzoom: this.minzoom(),
            maxzoom: this.maxzoom(),
            tileSize: this.tileSize(),
            attribution: this.attribution(),
            encoding: this.encoding(),
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RasterDemSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: RasterDemSourceComponent, isStandalone: true, selector: "mgl-raster-dem-source", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, tiles: { classPropertyName: "tiles", publicName: "tiles", isSignal: true, isRequired: false, transformFunction: null }, bounds: { classPropertyName: "bounds", publicName: "bounds", isSignal: true, isRequired: false, transformFunction: null }, minzoom: { classPropertyName: "minzoom", publicName: "minzoom", isSignal: true, isRequired: false, transformFunction: null }, maxzoom: { classPropertyName: "maxzoom", publicName: "maxzoom", isSignal: true, isRequired: false, transformFunction: null }, tileSize: { classPropertyName: "tileSize", publicName: "tileSize", isSignal: true, isRequired: false, transformFunction: null }, attribution: { classPropertyName: "attribution", publicName: "attribution", isSignal: true, isRequired: false, transformFunction: null }, encoding: { classPropertyName: "encoding", publicName: "encoding", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RasterDemSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-raster-dem-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], tiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiles", required: false }] }], bounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "bounds", required: false }] }], minzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minzoom", required: false }] }], maxzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxzoom", required: false }] }], tileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "tileSize", required: false }] }], attribution: [{ type: i0.Input, args: [{ isSignal: true, alias: "attribution", required: false }] }], encoding: [{ type: i0.Input, args: [{ isSignal: true, alias: "encoding", required: false }] }] } });

/**
 * `mgl-raster-source` - a raster source component
 * @see [raster](https://maplibre.org/maplibre-style-spec/sources/#raster)
 *
 * @category Source Components
 */
class RasterSourceComponent {
    constructor() {
        /** Init injections */
        this.sourceDirective = inject(SourceDirective);
        /** Dynamic input */
        this.url = input(...(ngDevMode ? [undefined, { debugName: "url" }] : []));
        /** Dynamic input */
        this.tiles = input(...(ngDevMode ? [undefined, { debugName: "tiles" }] : []));
        /** Dynamic input */
        this.bounds = input(...(ngDevMode ? [undefined, { debugName: "bounds" }] : []));
        /** Dynamic input */
        this.scheme = input(...(ngDevMode ? [undefined, { debugName: "scheme" }] : []));
        /** Dynamic input */
        this.minzoom = input(...(ngDevMode ? [undefined, { debugName: "minzoom" }] : []));
        /** Dynamic input */
        this.maxzoom = input(...(ngDevMode ? [undefined, { debugName: "maxzoom" }] : []));
        /** Dynamic input */
        this.tileSize = input(...(ngDevMode ? [undefined, { debugName: "tileSize" }] : []));
        /** Dynamic input */
        this.attribution = input(...(ngDevMode ? [undefined, { debugName: "attribution" }] : []));
        this.sourceDirective.loadSource$
            .pipe(tap$1(() => this.sourceDirective.addSource(this.getRasterSourceSpecification())), takeUntilDestroyed())
            .subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if ((changes.url && !changes.url.isFirstChange()) ||
            (changes.tiles && !changes.tiles.isFirstChange()) ||
            (changes.bounds && !changes.bounds.isFirstChange()) ||
            (changes.minzoom && !changes.minzoom.isFirstChange()) ||
            (changes.maxzoom && !changes.maxzoom.isFirstChange()) ||
            (changes.tileSize && !changes.tileSize.isFirstChange()) ||
            (changes.scheme && !changes.scheme.isFirstChange()) ||
            (changes.attribution && !changes.attribution.isFirstChange())) {
            this.sourceDirective.refresh();
        }
    }
    getRasterSourceSpecification() {
        return {
            type: 'raster',
            url: this.url(),
            tiles: this.tiles(),
            bounds: this.bounds(),
            minzoom: this.minzoom(),
            maxzoom: this.maxzoom(),
            tileSize: this.tileSize(),
            scheme: this.scheme(),
            attribution: this.attribution(),
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RasterSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: RasterSourceComponent, isStandalone: true, selector: "mgl-raster-source", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, tiles: { classPropertyName: "tiles", publicName: "tiles", isSignal: true, isRequired: false, transformFunction: null }, bounds: { classPropertyName: "bounds", publicName: "bounds", isSignal: true, isRequired: false, transformFunction: null }, scheme: { classPropertyName: "scheme", publicName: "scheme", isSignal: true, isRequired: false, transformFunction: null }, minzoom: { classPropertyName: "minzoom", publicName: "minzoom", isSignal: true, isRequired: false, transformFunction: null }, maxzoom: { classPropertyName: "maxzoom", publicName: "maxzoom", isSignal: true, isRequired: false, transformFunction: null }, tileSize: { classPropertyName: "tileSize", publicName: "tileSize", isSignal: true, isRequired: false, transformFunction: null }, attribution: { classPropertyName: "attribution", publicName: "attribution", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: RasterSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-raster-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], tiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiles", required: false }] }], bounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "bounds", required: false }] }], scheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "scheme", required: false }] }], minzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minzoom", required: false }] }], maxzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxzoom", required: false }] }], tileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "tileSize", required: false }] }], attribution: [{ type: i0.Input, args: [{ isSignal: true, alias: "attribution", required: false }] }] } });

/**
 * `mgl-vector-source` - a vector source component
 * @see [vector](https://maplibre.org/maplibre-style-spec/sources/#vector)
 *
 * @category Source Components
 */
class VectorSourceComponent {
    constructor() {
        /** Init injections */
        this.sourceDirective = inject(SourceDirective);
        /** Dynamic inputs */
        this.url = input(...(ngDevMode ? [undefined, { debugName: "url" }] : []));
        this.tiles = input(...(ngDevMode ? [undefined, { debugName: "tiles" }] : []));
        this.bounds = input(...(ngDevMode ? [undefined, { debugName: "bounds" }] : []));
        this.scheme = input(...(ngDevMode ? [undefined, { debugName: "scheme" }] : []));
        this.minzoom = input(...(ngDevMode ? [undefined, { debugName: "minzoom" }] : []));
        this.maxzoom = input(...(ngDevMode ? [undefined, { debugName: "maxzoom" }] : []));
        this.attribution = input(...(ngDevMode ? [undefined, { debugName: "attribution" }] : []));
        this.promoteId = input(...(ngDevMode ? [undefined, { debugName: "promoteId" }] : []));
        this.sourceDirective.loadSource$
            .pipe(tap$1(() => this.sourceDirective.addSource(this.getVectorSourceSpecification())), takeUntilDestroyed())
            .subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if ((changes.bounds && !changes.bounds.isFirstChange()) ||
            (changes.scheme && !changes.scheme.isFirstChange()) ||
            (changes.minzoom && !changes.minzoom.isFirstChange()) ||
            (changes.maxzoom && !changes.maxzoom.isFirstChange()) ||
            (changes.attribution && !changes.attribution.isFirstChange()) ||
            (changes.promoteId && !changes.promoteId.isFirstChange())) {
            this.sourceDirective.refresh();
        }
        else if ((changes.url && !changes.url.isFirstChange()) ||
            (changes.tiles && !changes.tiles.isFirstChange())) {
            const source = this.sourceDirective.getSource();
            if (source === undefined) {
                return;
            }
            const url = this.url();
            if (changes.url && url) {
                source.setUrl(url);
            }
            const tiles = this.tiles();
            if (changes.tiles && tiles) {
                source.setTiles(tiles);
            }
        }
    }
    getVectorSourceSpecification() {
        return {
            type: 'vector',
            url: this.url(),
            tiles: this.tiles(),
            bounds: this.bounds(),
            scheme: this.scheme(),
            minzoom: this.minzoom(),
            maxzoom: this.maxzoom(),
            attribution: this.attribution(),
            promoteId: this.promoteId(),
        };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: VectorSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: VectorSourceComponent, isStandalone: true, selector: "mgl-vector-source", inputs: { url: { classPropertyName: "url", publicName: "url", isSignal: true, isRequired: false, transformFunction: null }, tiles: { classPropertyName: "tiles", publicName: "tiles", isSignal: true, isRequired: false, transformFunction: null }, bounds: { classPropertyName: "bounds", publicName: "bounds", isSignal: true, isRequired: false, transformFunction: null }, scheme: { classPropertyName: "scheme", publicName: "scheme", isSignal: true, isRequired: false, transformFunction: null }, minzoom: { classPropertyName: "minzoom", publicName: "minzoom", isSignal: true, isRequired: false, transformFunction: null }, maxzoom: { classPropertyName: "maxzoom", publicName: "maxzoom", isSignal: true, isRequired: false, transformFunction: null }, attribution: { classPropertyName: "attribution", publicName: "attribution", isSignal: true, isRequired: false, transformFunction: null }, promoteId: { classPropertyName: "promoteId", publicName: "promoteId", isSignal: true, isRequired: false, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: VectorSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-vector-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { url: [{ type: i0.Input, args: [{ isSignal: true, alias: "url", required: false }] }], tiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "tiles", required: false }] }], bounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "bounds", required: false }] }], scheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "scheme", required: false }] }], minzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minzoom", required: false }] }], maxzoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxzoom", required: false }] }], attribution: [{ type: i0.Input, args: [{ isSignal: true, alias: "attribution", required: false }] }], promoteId: [{ type: i0.Input, args: [{ isSignal: true, alias: "promoteId", required: false }] }] } });

/**
 * `mgl-video-source` - a video source
 * @see [video](https://maplibre.org/maplibre-style-spec/sources/#video)
 *
 * @category Source Components
 */
class VideoSourceComponent {
    constructor() {
        this.sourceDirective = inject(SourceDirective);
        /** Dynamic input */
        this.urls = input.required(...(ngDevMode ? [{ debugName: "urls" }] : []));
        /** Dynamic input */
        this.coordinates = input.required(...(ngDevMode ? [{ debugName: "coordinates" }] : []));
        this.sourceDirective.loadSource$.pipe(tap$1(() => this.addSource()), takeUntilDestroyed()).subscribe();
    }
    ngOnChanges(changes) {
        if (!this.sourceDirective.sourceId()) {
            return;
        }
        if (changes.urls && !changes.urls.isFirstChange()) {
            this.sourceDirective.refresh();
        }
        else if (changes.coordinates && !changes.coordinates.isFirstChange()) {
            const source = this.sourceDirective.getSource();
            if (source === undefined) {
                return;
            }
            source.setCoordinates(changes.coordinates.currentValue);
        }
    }
    addSource() {
        const source = {
            type: 'video',
            urls: this.urls(),
            coordinates: this.coordinates(),
        };
        this.sourceDirective.addSource(source);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: VideoSourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.0.6", type: VideoSourceComponent, isStandalone: true, selector: "mgl-video-source", inputs: { urls: { classPropertyName: "urls", publicName: "urls", isSignal: true, isRequired: true, transformFunction: null }, coordinates: { classPropertyName: "coordinates", publicName: "coordinates", isSignal: true, isRequired: true, transformFunction: null } }, usesOnChanges: true, hostDirectives: [{ directive: SourceDirective, inputs: ["id", "id"] }], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: VideoSourceComponent, decorators: [{
            type: Component,
            args: [{
                    selector: 'mgl-video-source',
                    template: '',
                    changeDetection: ChangeDetectionStrategy.OnPush,
                    hostDirectives: [{ directive: SourceDirective, inputs: ['id'] }],
                }]
        }], ctorParameters: () => [], propDecorators: { urls: [{ type: i0.Input, args: [{ isSignal: true, alias: "urls", required: true }] }], coordinates: [{ type: i0.Input, args: [{ isSignal: true, alias: "coordinates", required: true }] }] } });

const NgxMapLibreGLImports = [
    MapComponent,
    LayerComponent,
    DraggableDirective,
    ImageComponent,
    VectorSourceComponent,
    GeoJSONSourceComponent,
    RasterDemSourceComponent,
    RasterSourceComponent,
    ImageSourceComponent,
    VideoSourceComponent,
    CanvasSourceComponent,
    FeatureComponent,
    MarkerComponent,
    PopupComponent,
    ControlComponent,
    FullscreenControlDirective,
    NavigationControlDirective,
    GeolocateControlDirective,
    AttributionControlDirective,
    ScaleControlDirective,
    PointDirective,
    ClusterPointDirective,
    MarkersForClustersComponent,
    TerrainControlDirective,
    SourceDirective,
];
class NgxMapLibreGLModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxMapLibreGLModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.0.6", ngImport: i0, type: NgxMapLibreGLModule, imports: [MapComponent,
            LayerComponent,
            DraggableDirective,
            ImageComponent,
            VectorSourceComponent,
            GeoJSONSourceComponent,
            RasterDemSourceComponent,
            RasterSourceComponent,
            ImageSourceComponent,
            VideoSourceComponent,
            CanvasSourceComponent,
            FeatureComponent,
            MarkerComponent,
            PopupComponent,
            ControlComponent,
            FullscreenControlDirective,
            NavigationControlDirective,
            GeolocateControlDirective,
            AttributionControlDirective,
            ScaleControlDirective,
            PointDirective,
            ClusterPointDirective,
            MarkersForClustersComponent,
            TerrainControlDirective,
            SourceDirective], exports: [MapComponent,
            LayerComponent,
            DraggableDirective,
            ImageComponent,
            VectorSourceComponent,
            GeoJSONSourceComponent,
            RasterDemSourceComponent,
            RasterSourceComponent,
            ImageSourceComponent,
            VideoSourceComponent,
            CanvasSourceComponent,
            FeatureComponent,
            MarkerComponent,
            PopupComponent,
            ControlComponent,
            FullscreenControlDirective,
            NavigationControlDirective,
            GeolocateControlDirective,
            AttributionControlDirective,
            ScaleControlDirective,
            PointDirective,
            ClusterPointDirective,
            MarkersForClustersComponent,
            TerrainControlDirective,
            SourceDirective] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxMapLibreGLModule }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgxMapLibreGLModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [...NgxMapLibreGLImports],
                    exports: [...NgxMapLibreGLImports],
                }]
        }] });

/**
 * `mglGlobe` - a globe control directive
 *
 * @category Directives
 *
 * @see [Globe](https://maplibre.org/ngx-maplibre-gl/demo/globe)
 * @see [GlobeControl](https://maplibre.org/maplibre-gl-js/docs/API/classes/GlobeControl)
 */
class GlobeControlDirective {
    constructor() {
        this.mapService = inject(MapService);
        this.controlComponent = inject(ControlComponent, { host: true });
        afterNextRender(() => {
            this.mapService.mapCreated$.subscribe(() => {
                if (this.controlComponent.control) {
                    throw new Error('Another control is already set for this control');
                }
                this.controlComponent.control = new GlobeControl();
                this.mapService.addControl(this.controlComponent.control, this.controlComponent.position());
            });
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GlobeControlDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
    static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.6", type: GlobeControlDirective, isStandalone: true, selector: "[mglGlobe]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GlobeControlDirective, decorators: [{
            type: Directive,
            args: [{
                    selector: '[mglGlobe]',
                }]
        }], ctorParameters: () => [] });

/*
 * Public API Surface of ngx-maplibre-gl
 */

/**
 * Generated bundle index. Do not edit.
 */

export { AttributionControlDirective, CanvasSourceComponent, ClusterPointDirective, ControlComponent, CustomControl, DraggableDirective, FeatureComponent, FullscreenControlDirective, GeoJSONSourceComponent, GeolocateControlDirective, GlobeControlDirective, ImageComponent, ImageSourceComponent, LayerComponent, MapComponent, MapService, MarkerComponent, MarkersForClustersComponent, NavigationControlDirective, NgxMapLibreGLImports, NgxMapLibreGLModule, PointDirective, PopupComponent, RasterDemSourceComponent, RasterSourceComponent, ScaleControlDirective, SourceDirective, TerrainControlDirective, VectorSourceComponent, VideoSourceComponent };
//# sourceMappingURL=maplibre-ngx-maplibre-gl.mjs.map