UNPKG

libre-routing

Version:

This library was generated with [Nx](https://nx.dev).

138 lines 5.78 kB
import { __awaiter } from "tslib"; import { Popup } from 'maplibre-gl'; import { featureCollection, point } from '@turf/helpers'; import { wrap } from 'comlink'; import bbox from '@turf/bbox'; import { LibreRoutingConsts } from '../../consts'; import { AnnotationPopupComponent, } from './popup-component'; const defaultConfig = { routeLayerIds: [LibreRoutingConsts.RouteLayerId], calculatePopupOnFly: true, componentFactory(routeId, data, ctx) { return new AnnotationPopupComponent(routeId, data, ctx); }, }; const resolveOptions = (ctx, options) => { return Object.assign(Object.assign({}, options), { routeLayerIds: options.routeLayerIds.map((id) => ctx.getUniqueName(id)) }); }; export class AnnotationPlugin { constructor(options = {}) { this.popups = []; this.allInBbox = false; this.currentFeatures = []; this.components = []; this.clearMapHandler = () => { this.destroyView(); }; this.routeCalculatedHandler = this.routeCalculated.bind(this); this.mapMoveEndHandler = this.recalculate.bind(this); this.options = Object.assign(Object.assign({}, defaultConfig), options); this.worker = new Worker(new URL('./annotation.worker', import.meta.url), { type: 'module', }); // @ts-ignore this.workerApi = wrap(this.worker); } onAdd(ctx) { this.options = resolveOptions(ctx, this.options); this.ctx = ctx; this.map = ctx.map; this.ctx.on('routesCalculated', this.routeCalculatedHandler); this.ctx.on('calculationStarted', this.clearMapHandler); this.ctx.on('clearMap', this.clearMapHandler); this.map.on(this.options.calculatePopupOnFly ? 'move' : 'moveend', this.mapMoveEndHandler); } onRemove() { var _a; this.worker.terminate(); this.destroyView(); this.ctx.on('routesCalculated', this.routeCalculatedHandler); (_a = this.ctx) === null || _a === void 0 ? void 0 : _a.off('calculationStarted', this.clearMapHandler); this.ctx.off('clearMap', this.clearMapHandler); this.map.off(this.options.calculatePopupOnFly ? 'move' : 'moveend', this.mapMoveEndHandler); } routeCalculated(data) { return __awaiter(this, void 0, void 0, function* () { this.data = data; this.destroyView(); const pendingRequests = yield this.ctx.options.dataProvider.hasPendingRequests(); if (!pendingRequests) { yield this.workerApi.createChunks(data); yield this.recalculate(true); } }); } recalculate(force = false) { return __awaiter(this, void 0, void 0, function* () { this.mapBounds = this.map.getBounds(); if (this.bounds && this.bounds.length === 4 && this.mapBounds.contains([this.bounds[0], this.bounds[1]]) && this.mapBounds.contains([this.bounds[2], this.bounds[3]]) && this.allInBbox && !force) { return; } const sw = this.mapBounds.getSouthWest(); const ne = this.mapBounds.getNorthEast(); const { points, allInBbox } = yield this.workerApi.recalculatePos({ bbox: { sw, ne }, popup: null, }); if (!points.length) return; const mathedFeatures = points .map((point) => { const xy = this.map.project(point.lngLat); return this.map.queryRenderedFeatures(xy, { layers: this.options.routeLayerIds, })[0]; }) .filter((d) => !!d); if (mathedFeatures.length === 0) { return; } const matchedIds = mathedFeatures.map((f) => f.properties.routeId); const currentFeatures = this.currentFeatures.map((f) => f.properties.routeId); if (matchedIds.toString() === currentFeatures.toString() && this.bounds && this.bounds.length === 4 && this.mapBounds.contains([this.bounds[0], this.bounds[1]]) && this.mapBounds.contains([this.bounds[2], this.bounds[3]]) && !force) { return; } this.destroyView(); this.currentFeatures = mathedFeatures; this.allInBbox = allInBbox; this.bounds = bbox(featureCollection(points.map((p) => point(p.lngLat)))); this.components = []; points.forEach((point) => { const component = this.options.componentFactory(point.properties.routeId, this.data, this.ctx); const popup = new Popup({ closeButton: false, closeOnClick: false, className: 'no-mouse-events', }) .setLngLat(point.lngLat) .setDOMContent(component.container) .addTo(this.map); if ('onAttach' in component) { component.onAttach(popup); } const popupElem = popup.getElement(); popupElem.querySelector('.maplibregl-popup-content').style.padding = '0'; this.components.push(component); this.popups.push(popup); }); }); } destroyView() { this.allInBbox = false; this.components.forEach((c) => c.destroy()); this.popups.forEach((p) => p.remove()); this.popups = []; this.components = []; } } //# sourceMappingURL=annotation.plugin.js.map