libre-routing
Version:
This library was generated with [Nx](https://nx.dev).
281 lines • 10.3 kB
JavaScript
import { __awaiter } from "tslib";
import { featureCollection, point } from '@turf/helpers';
import { Dispatcher } from './utils/dispatcher';
import { randomId } from './utils/random';
const defaultConfig = {
dataProvider: null,
alternatives: 1,
skipAlternativesOnMultipleWaypoint: true,
firstRouteCenter: true,
plugins: [],
routeSourceId: 'libre-routing-route-source',
waypointsSourceId: 'libre-routing-waypoints',
};
export const resolveOptions = (options) => {
return Object.assign(Object.assign({}, options), { routeSourceId: `libre-routing-route-source-${options.uniqueKey}`, waypointsSourceId: `libre-routing-waypoints-${options.uniqueKey}` });
};
export class LibreRouting {
constructor(options) {
this.dispatcher = new Dispatcher();
this._waypoints = [];
this._options = Object.assign(Object.assign({ uniqueKey: randomId() }, defaultConfig), options);
this._options = resolveOptions(this._options);
}
get map() {
return this._map;
}
get options() {
return this._options;
}
get data() {
return this._data;
}
get selectedRouteId() {
return this._selectedRouteId;
}
set waypoints(value) {
this._waypoints = value;
}
get waypoints() {
return this._waypoints;
}
onAdd(map) {
this._map = map;
this.enable();
return document.createElement('div');
}
onRemove() {
this.disable();
}
setWaypoints(waypoints, opts) {
this.waypoints = waypoints.map(({ position, properties }, index) => ({
originalPos: position,
properties: Object.assign(Object.assign({}, properties), { isFirst: index === 0, isLast: index === waypoints.length - 1 }),
}));
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvent) !== false) {
this.emitWaypointsChanged();
}
this.updateWaypointsSource();
}
addWaypoint(waypoint, index, mappedPos, opts) {
const newArr = [...this.waypoints];
newArr.splice(index, 0, {
originalPos: waypoint.position,
mappedPos,
properties: waypoint.properties,
});
this.waypoints = newArr;
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvent) !== false) {
this.dispatcher.fire('waypointAdded', {
index,
waypoint: this.waypoints[index],
});
this.emitWaypointsChanged();
}
this.updateWaypointsSource();
}
updateWaypoint(waypoint, index, mappedPos, opts) {
if (!this.waypoints[index] ||
(this.waypoints[index].originalPos[0] === waypoint.position[0] &&
this.waypoints[index].originalPos[1] === waypoint.position[1])) {
return false;
}
this.waypoints[index] = Object.assign(Object.assign({}, this.waypoints[index]), { originalPos: waypoint.position, mappedPos });
this.updateWaypointsSource();
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvent) !== false) {
this.emitWaypointChanged(index);
this.emitWaypointsChanged();
}
return true;
}
removeWaypoint(index, opts) {
const newArr = [...this.waypoints];
newArr.splice(index, 1);
this.waypoints = newArr;
this.updateWaypointsSource();
if ((opts === null || opts === void 0 ? void 0 : opts.emitEvent) !== false) {
this.emitWaypointsChanged();
}
}
getWaypoint(waypointId) {
return this._waypoints[waypointId];
}
recalculateRoute({ skipCenter, clearMap, dropPendingRequests, dragMode, } = {}) {
return __awaiter(this, void 0, void 0, function* () {
this.dispatcher.fire('calculationStarted', null);
if (clearMap) {
this.clearMap();
}
if (dropPendingRequests) {
this.options.dataProvider.abortAllRequests();
}
if (!this.map || this.waypoints.length < 2)
return;
if (!this.options.dataProvider) {
throw new Error('No data provider');
}
const alternatives = this.options.skipAlternativesOnMultipleWaypoint &&
this.waypoints.length !== 2
? 0
: this.options.alternatives;
try {
this.dispatcher.fire('calculatePending', true);
const data = (yield this.options.dataProvider.request(this.waypoints, {
alternatives,
dragMode,
}));
const firstData = !this.data;
this._data = data;
this.setSource(this.options.routeSourceId, data.routesShapeGeojson.data);
this.dispatcher.fire(dragMode ? 'mainRouteCalculated' : 'routesCalculated', this.data);
if (data.selectedRouteId != null && !dragMode) {
this._selectedRouteId = data.selectedRouteId;
this.dispatcher.fire('routeSelected', {
event: 'routeSelected',
data: this.data,
route: this.data.routes[data.selectedRouteId],
routeId: data.selectedRouteId,
});
}
if (this.waypoints.length === 2 &&
!skipCenter &&
firstData &&
!dragMode) {
this.zoomToData();
}
return data;
}
catch (e) {
this.dispatcher.fire('routeError', e);
throw e;
}
finally {
this.options.dataProvider.hasPendingRequests().then((pending) => {
if (!pending) {
this.dispatcher.fire('calculatePending', false);
}
});
}
});
}
zoomToData(opts) {
var _a;
if ((_a = this.data) === null || _a === void 0 ? void 0 : _a.routesShapeBounds) {
this.map.fitBounds(this.data.routesShapeBounds, Object.assign({ padding: 40 }, opts));
}
}
on(...args) {
this.dispatcher.on(...args);
}
off(...args) {
this.dispatcher.off(...args);
}
enable() {
this.setupMapSources();
this.initPlugins();
}
disable() {
var _a;
this.detachPlugins();
(_a = this.options.dataProvider) === null || _a === void 0 ? void 0 : _a.destroy();
this.map.removeSource(this.options.routeSourceId);
this.map.removeSource(this.options.waypointsSourceId);
}
selectRoute(routeId) {
if (!this.data) {
return;
}
const features = this.data.routesShapeGeojson.data.features.map((feature) => {
return Object.assign(Object.assign({}, feature), { properties: Object.assign(Object.assign({}, feature.properties), { selected: feature.properties.routeId === routeId }) });
});
this._selectedRouteId = routeId;
this.data.routesShapeGeojson.data.features = features;
const newData = Object.assign(Object.assign({}, this.data.routesShapeGeojson.data), { features });
this.setSource(this.options.routeSourceId, newData);
this.dispatcher.fire('routeSelected', {
event: 'routeSelected',
data: this.data,
route: this.data.routes[routeId],
routeId: routeId,
});
}
showAllRoutes() {
if (!this.data) {
return;
}
const newData = Object.assign(Object.assign({}, this.data.routesShapeGeojson.data), { features: this.data.routesShapeGeojson.data.features });
this.setSource(this.options.routeSourceId, newData);
}
clearMap() {
this.setSource(this.options.routeSourceId, featureCollection([]));
this.dispatcher.fire('clearMap', this);
this._data = null;
}
getUniqueName(name) {
return `${name}-${this.options.uniqueKey}`;
}
syncWaypointsPositions(opts) {
if (!this.data) {
return;
}
this.data.routes[0].waypoints.map((waypoint, index) => {
this.updateWaypoint({
properties: this.waypoints[index].properties,
position: [waypoint.lng, waypoint.lat],
}, index, [0, 0], opts);
});
}
emitWaypointsChanged() {
this.dispatcher.fire('waypointsChanged', this._waypoints);
}
emitWaypointChanged(waypointId) {
this.dispatcher.fire('waypointChanged', {
waypointId,
data: this.waypoints[waypointId],
});
}
emitWaypointDirtyChanged(waypointId) {
this.dispatcher.fire('waypointDirtyChanged', {
waypointId,
data: this.waypoints[waypointId],
});
}
emitWaypointAdded(waypointId) {
this.dispatcher.fire('waypointAdded', {
waypointId,
data: this.waypoints[waypointId],
});
}
updateWaypointsSource() {
const points = this.waypoints.map((waypoint, id) => point(waypoint.originalPos, Object.assign({ id }, waypoint.properties)));
const data = featureCollection(points);
this.setSource(this.options.waypointsSourceId, data);
}
initPlugins() {
this.options.plugins.forEach((plugin) => this.resolvePlugin(plugin).onAdd(this));
}
detachPlugins() {
this.options.plugins.forEach((plugin) => this.resolvePlugin(plugin).onRemove(this));
}
setupMapSources() {
this.map.addSource(this.options.routeSourceId, {
type: 'geojson',
data: featureCollection([]),
});
this.map.addSource(this.options.waypointsSourceId, {
type: 'geojson',
data: featureCollection([]),
});
}
resolvePlugin(plugin) {
if (typeof plugin === 'function') {
return new plugin({});
}
return plugin;
}
setSource(sourceId, data) {
// @ts-ignore
this.map.getSource(sourceId).setData(data);
}
}
//# sourceMappingURL=libre-routing.js.map