@maplibre/ngx-maplibre-gl
Version:
An Angular binding for maplibre-gl
2,978 lines • 186 kB
JavaScript
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