UNPKG

mobility-toolbox-js

Version:

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

211 lines (210 loc) 7.9 kB
import { MapLibreLayer } from '@geoblocks/ol-maplibre-layer/lib'; import debounce from 'lodash.debounce'; import { unByKey } from 'ol/Observable'; import { getUrlWithParams } from '../../common/utils'; import MaplibreLayerRenderer from '../renderers/MaplibreLayerRenderer'; import defineDeprecatedProperties from '../utils/defineDeprecatedProperties'; const buildStyleUrl = (url, style, apiKey, apiKeyName) => { return getUrlWithParams(`${url}/styles/${style}/style.json`, { [apiKeyName]: apiKey, }).toString(); }; export let deprecated = () => { }; if (typeof window !== 'undefined' && new URLSearchParams(window.location.search).get('deprecated')) { deprecated = debounce((message) => { console.warn(message); }, 1000); } /** * An OpenLayers layer able to display data from the [geOps Maps API](https://developer.geops.io/apis/maps). * * @example * import { MaplibreLayer } from 'mobility-toolbox-js/ol'; * * const layer = new MaplibreLayer({ * apiKey: 'yourApiKey', * // apiKeyName: 'key', * // mapLibreOptions: { * // interactive: false, * // trackResize: false, * // attributionControl: false, * // } * // queryRenderedFeaturesOptions: { * // layers: ['waters_lakes'], // map.getFeaturesAtPixel will only return lakes. * // }, * // style: 'travic_v2', * // url: 'https://maps.geops.io', * }); * * @classproperty {maplibregl.Map} mapLibreMap - The Maplibre map object. Readonly. * @classproperty {string} style - The [geOps Maps API](https://developer.geops.io/apis/maps) style. * * * @see <a href="/example/ol-maplibre-layer">OpenLayers Maplibre layer example</a> * * @extends {geoblocks/ol-maplibre-layer/MapLibreLayer} * @public */ class MaplibreLayer extends MapLibreLayer { set apiKey(newValue) { this.set('apiKey', newValue); } get apiKey() { return this.get('apiKey'); } set apiKeyName(newValue) { this.set('apiKeyName', newValue); } get apiKeyName() { return this.get('apiKeyName'); } /** * @deprecated Use layer.mapLibreMap. */ get maplibreMap() { deprecated('MaplibreLayer.maplibreMap is deprecated. Use layer.mapLibreMap.'); return this.mapLibreMap; } // get queryRenderedFeaturesOptions(): maplibregl.QueryRenderedFeaturesOptions { // return this.get('queryRenderedFeaturesOptions'); // } // set queryRenderedFeaturesOptions( // newValue: maplibregl.QueryRenderedFeaturesOptions, // ) { // this.set('queryRenderedFeaturesOptions', newValue); // } /** * @deprecated Use layer.mapLibreMap. */ get mbMap() { deprecated('MaplibreLayer.mbMap is deprecated. Use layer.maplibreMap.'); return this.maplibreMap; } get style() { return this.get('style'); } set style(newValue) { this.set('style', newValue); } get url() { return this.get('url'); } set url(newValue) { this.set('url', newValue); } /** * Constructor. * * @param {Object} options * @param {string} options.apiKey Accesss key for [geOps APIs](https://developer.geops.io/). * @param {string} [options.apiKeyName="key"] The [geOps Maps API](https://developer.geops.io/apis/maps) key name. * @param {maplibregl.MapOptions} [options.mapLibreOptions={ interactive: false, trackResize: false, attributionControl: false }] MapLibre map options. * @param {string} [options.style="travic_v2"] The [geOps Maps API](https://developer.geops.io/apis/maps) style. * @param {string} [options.url="https://maps.geops.io"] The [geOps Maps API](https://developer.geops.io/apis/maps) url. */ constructor(options) { var _a; // Backward compatibility if (options.mapOptions && !options.mapLibreOptions) { deprecated('MaplibreLayer.mapOptions is deprecated. Use mapLibreOptions instead.'); options.mapLibreOptions = options.mapOptions; } const newOptions = Object.assign(Object.assign({ apiKeyName: 'key', style: 'travic_v2', url: 'https://maps.geops.io' }, (options || {})), { mapLibreOptions: Object.assign({}, (options.mapLibreOptions || {})) }); if (!newOptions.mapLibreOptions.style && ((_a = newOptions.url) === null || _a === void 0 ? void 0 : _a.includes('style.json'))) { newOptions.mapLibreOptions.style = newOptions.url; } else if (!newOptions.mapLibreOptions.style && newOptions.apiKey && newOptions.style && typeof newOptions.style === 'string') { newOptions.mapLibreOptions.style = buildStyleUrl(newOptions.url, newOptions.style, newOptions.apiKey, newOptions.apiKeyName); } super(newOptions); this.olEventsKeys = []; // For backward compatibility with v2 defineDeprecatedProperties(this, options); // We save the options to be able to clone the layer. // and to see if the style is defined by the maplibreOptions given by the user. this.set('options', options); } /** * Initialize the layer and listen to feature clicks. */ attachToMap() { const updateMaplibreMapDebounced = debounce(this.updateMaplibreMap.bind(this), 150); updateMaplibreMapDebounced(); this.olEventsKeys.push(this.on('propertychange', (evt) => { if (/(url|style|apiKey|apiKeyName)/.test(evt.key)) { updateMaplibreMapDebounced(); } })); } /** * Create a copy of the MaplibreLayer. * * @param {Object} newOptions Options to override. See constructor. * @return {MaplibreLayer} A MaplibreLayer layer * @public */ clone(newOptions) { return new MaplibreLayer(Object.assign(Object.assign({}, (this.get('options') || {})), (newOptions || {}))); } createRenderer() { return new MaplibreLayerRenderer(this); } detachFromMap() { unByKey(this.olEventsKeys); } disposeInternal() { const source = this.getSource(); super.disposeInternal(); // At this point mapLibreMap.style is undefined, so to avoid errors on layers removed after this one, // we set the mapLibreMap to null this.mapLibreMap = undefined; // We don't want the source removed this.setSource(source); } getStyle() { var _a; // If the style is a complete style object, use it directly. if (this.style && typeof this.style === 'object' && this.style.name && this.style.version) { return this.style; } // If the url set is already a complete style url, use it directly. if (this.url.includes('style.json')) { return this.url; } // If the user has defined the style by the maplibreOptions, we use it directly. const opts = this.get('options'); if ((_a = opts === null || opts === void 0 ? void 0 : opts.mapLibreOptions) === null || _a === void 0 ? void 0 : _a.style) { return opts.mapLibreOptions.style; } /// Otherwise build the complete style url. return buildStyleUrl(this.url, this.style, this.apiKey, this.apiKeyName); } setMapInternal(map) { if (map) { super.setMapInternal(map); this.attachToMap(); } else { this.detachFromMap(); super.setMapInternal(map); } } updateMaplibreMap() { var _a; try { (_a = this.mapLibreMap) === null || _a === void 0 ? void 0 : _a.setStyle(this.getStyle(), { diff: false }); } catch (e) { console.error('Error while updating MaplibreMap', e); } } } export default MaplibreLayer;