UNPKG

mobility-toolbox-js

Version:

Toolbox for JavaScript applications in the domains of mobility and logistics.

128 lines (127 loc) 5.92 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { getUid } from 'ol'; import GeoJSON from 'ol/format/GeoJSON'; import { getLayersAsFlatArray } from '../../common'; /** * @private */ const format = new GeoJSON(); /** * @private */ const getFeaturesFromWMS = (source, options, abortController) => { let url; const { coordinate, params, projection, resolution } = options; if (source && resolution && projection) { url = source.getFeatureInfoUrl(coordinate, resolution, projection, Object.assign({ info_format: 'application/json', query_layers: source.getParams().layers }, params)); } // @ts-expect-error url can be undefined return fetch(url, { signal: abortController.signal }) .then((resp) => { return resp.json(); }) .then((featureCollection) => { return format.readFeatures(featureCollection); }) .catch(() => { return []; }); }; /** * @private */ let abortControllers = {}; /** * Fetches feature information at a given coordinate from the provided layers. * It supports WMS sources and MapLibre layers and custom layer via the method `layer.getFeatureInfoAtCoordinate`. * * @param {Coordinate} coordinate - The coordinate to query for feature information. * @param {ol/layer/BaseLayer~BaseLayer[]} layers - The layers to query for feature information. * @param {number} hitTolerance - The pixel tolerance for feature selection. * @param {boolean} ignoreLayerMethod - If true, it ignores the `getFeatureInfoAtCoordinate` method on layers. * @returns {LayerGetFeatureInfoResponse[]} A promise that resolves to an array of feature information responses. * @private */ const getFeatureInfoAtCoordinate = (coordinate_1, layers_1, ...args_1) => __awaiter(void 0, [coordinate_1, layers_1, ...args_1], void 0, function* (coordinate, layers, hitTolerance = 5, ignoreLayerMethod = false) { // Kill all previous requests Object.values(abortControllers).forEach((abortController) => { abortController === null || abortController === void 0 ? void 0 : abortController.abort(); }); abortControllers = {}; const flatLayers = getLayersAsFlatArray(layers); const promises = flatLayers.map((baseLayer) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b, _c, _d; const map = baseLayer.getMapInternal(); const projection = (_b = (_a = map === null || map === void 0 ? void 0 : map.getView()) === null || _a === void 0 ? void 0 : _a.getProjection()) === null || _b === void 0 ? void 0 : _b.getCode(); const emptyResponse = { coordinate, features: [], layer: baseLayer, }; if (!projection) { return Promise.resolve(emptyResponse); } const layer = baseLayer; // For backward compatibility // @ts-expect-error getFeatureInfoAtCoordinate is deprecated if (!ignoreLayerMethod && layer.getFeatureInfoAtCoordinate) { // @ts-expect-error getFeatureInfoAtCoordinate is deprecated // eslint-disable-next-line @typescript-eslint/no-unsafe-call return layer.getFeatureInfoAtCoordinate(coordinate); } // WMS sources // Here we don't use instanceof, to be able to use this function if a layer comes from 2 different ol versions. const source = layer === null || layer === void 0 ? void 0 : layer.getSource(); if (source === null || source === void 0 ? void 0 : source.getFeatureInfoUrl) { const id = getUid(layer); // Abort and recreates one controller per layer (_c = abortControllers[id]) === null || _c === void 0 ? void 0 : _c.abort(); abortControllers[id] = new AbortController(); const resolution = (_d = map === null || map === void 0 ? void 0 : map.getView()) === null || _d === void 0 ? void 0 : _d.getResolution(); const features = yield getFeaturesFromWMS(source, { coordinate, params: { info_format: 'application/json', query_layers: source.getParams().layers, }, projection, resolution, }, abortControllers[id]).catch(() => { return []; }); const featureInfoResponse = { coordinate, features, layer, }; return Promise.resolve(featureInfoResponse); } // Other layers // For last resort we try the map function to get the features from the map const pixel = map === null || map === void 0 ? void 0 : map.getPixelFromCoordinate(coordinate); if (!pixel) { return Promise.resolve(emptyResponse); } const features = map === null || map === void 0 ? void 0 : map.getFeaturesAtPixel(pixel, { hitTolerance: layer.get('hitTolerance') || hitTolerance || 5, layerFilter: (l) => { return l === layer; }, }); return Promise.resolve({ coordinate, features, layer, }); })); return Promise.all(promises); }); export default getFeatureInfoAtCoordinate;