libre-routing
Version:
This library was generated with [Nx](https://nx.dev).
138 lines • 5.78 kB
JavaScript
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