UNPKG

@supermap/iclient-maplibregl

Version:

@supermap/iclient-maplibregl 是一套基于 Maplibre GL 的云 GIS 网络客户端开发平台, 支持访问 SuperMap iServer / iEdge / iPortal / iManager / Online 的地图、服务和资源,为用户提供了完整专业的 GIS 能力, 同时提供了优秀的可视化功能。

362 lines (331 loc) 11.5 kB
/* Copyright© 2000 - 2023 SuperMap Software Co.Ltd. All rights reserved. * This program are made available under the terms of the Apache License, Version 2.0 * which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/ import maplibregl from 'maplibre-gl'; import SymbolHandler from './SymbolHandler'; import { FetchRequest } from "@supermap/iclient-common/util/FetchRequest"; import { Util } from '@supermap/iclient-common/commontypes/Util'; /** * @function MapExtendSymbol * @description 扩展了 maplibregl.Map 对图层相关的操作。 * @private */ function MapExtendSymbol(){ /** * 获取symbol管理 * @param {*} map * @returns {object} */ const getSymbolHandler = (map) => { if (!maplibregl.Map.prototype.symbolHandler) { maplibregl.Map.prototype.symbolHandler = new SymbolHandler(map); } return maplibregl.Map.prototype.symbolHandler._update(map); } if (maplibregl.Map.prototype.addLayerBySymbolBak === undefined) { maplibregl.Map.prototype.addLayerBySymbolBak = maplibregl.Map.prototype.addLayer; maplibregl.Map.prototype.addLayer = function (layer, before) { const symbolHandler = getSymbolHandler(this); if(symbolHandler.getLayerIds(layer.id).length > 0) { this.fire('error', { error: new Error('A layer with this id already exists.') }); return; } if (layer.symbol) { symbolHandler.addLayer(layer, before); return this; } this.addLayerBySymbolBak(layer, before); return this; }; } if (maplibregl.Map.prototype.getLayerBySymbolBak === undefined) { maplibregl.Map.prototype.getLayerBySymbolBak = maplibregl.Map.prototype.getLayer; maplibregl.Map.prototype.getLayer = function (id) { return getSymbolHandler(this).getLayer(id); }; } if (maplibregl.Map.prototype.moveLayerBySymbolBak === undefined) { maplibregl.Map.prototype.moveLayerBySymbolBak = maplibregl.Map.prototype.moveLayer; maplibregl.Map.prototype.moveLayer = function (id, beforeId) { if (this.style.getLayer(id) && (!beforeId || this.style.getLayer(beforeId))) { return this.moveLayerBySymbolBak(id, beforeId); } getSymbolHandler(this).moveLayer(id, beforeId); return this._update(true); } } if (maplibregl.Map.prototype.removeLayerBySymbolBak === undefined) { maplibregl.Map.prototype.removeLayerBySymbolBak = maplibregl.Map.prototype.removeLayer; maplibregl.Map.prototype.removeLayer = function (id) { if (this.style.getLayer(id)) { return this.removeLayerBySymbolBak(id); } return getSymbolHandler(this).removeLayer(id); }; } if (maplibregl.Map.prototype.setLayoutPropertyBySymbolBak === undefined) { //目前扩展的overlayer,只支持显示或隐藏图层操作 maplibregl.Map.prototype.setLayoutPropertyBySymbolBak = maplibregl.Map.prototype.setLayoutProperty; maplibregl.Map.prototype.setLayoutProperty = function (layerID, name, value, options) { if (this.overlayLayersManager[layerID] || this.style.getLayer(layerID)) { return this.setLayoutPropertyBySymbolBak(layerID, name, value, options); } getSymbolHandler(this).setLayoutProperty(layerID, name, value, options); return this._update(true); }; } /** * 指定图层设置符号 * @param {string} layerId * @param {string | array} symbol */ maplibregl.Map.prototype.setSymbol = function (layerId, symbol) { getSymbolHandler(this).setSymbol(layerId, symbol); }; /** * Layer新增symbol属性 */ if (!(maplibregl.Map.prototype).setStyleBak) { (maplibregl.Map.prototype).setStyleBak = maplibregl.Map.prototype.setStyle; maplibregl.Map.prototype.setStyle = function (style, options) { this.setStyleBak(style, options); this.style && this.style.once('style.load', () => { const symbolLayers = style.layers.filter(l => l.symbol); symbolLayers.forEach((l) => { this.setSymbol(l.id, l.symbol); }); }); return this; } } /** * 加载Web符号 * @param {string | string[]} id * @param {function} callback */ maplibregl.Map.prototype.loadSymbol = async function (id, callback) { if (typeof id === 'string') { const symbolInfo = await loadSymbol(id, this); let message = null; if(!symbolInfo) { message = `Symbol ${id} is not exists`; } callback(message, symbolInfo); } else if (Util.isArray(id)) { const promises = id.map(i => loadSymbol(i, this)); const symbolInfo = await Promise.all(promises); let message = null; const errorIds = id.filter((_i, index) => !symbolInfo[index]); if(errorIds.length > 0){ message = `Symbol ${errorIds.join(',')} is not exists`; } callback(message, symbolInfo); } else { callback({ message: 'Symbol id must be a string or string[].' }); } }; /** * 添加符号 * @param {string} id * @param {object} symbol */ maplibregl.Map.prototype.addSymbol = function (id, symbol) { getSymbolHandler(this).addSymbol(id, symbol); }; /** * 获取符号信息 * @param {string} id */ maplibregl.Map.prototype.getSymbol = function (id) { return getSymbolHandler(this).getSymbol(id); }; /** * 判断符号是否存在 * @param {string} id */ maplibregl.Map.prototype.hasSymbol = function (id) { if (!id) { this.fire('error', { error: new Error('Missing required symbol id') }); return false; } return !!this.getSymbol(id); }; /** * 删除符号 * @param {string} id */ maplibregl.Map.prototype.removeSymbol = function (id) { getSymbolHandler(this).removeSymbol(id); }; /** * 更新符号 * @param {string} id * @param {object} symbol */ maplibregl.Map.prototype.updateSymbol = function (id, symbol) { getSymbolHandler(this).updateSymbol(id, symbol); }; /** * 设置symbol属性值 * @param {string} id * @param {number} index * @param {string} name * @param {any} value */ maplibregl.Map.prototype.setSymbolProperty = function (id, index, name, value) { getSymbolHandler(this).setSymbolProperty(id, index, name, value); }; /** * 获取symbol的属性值 * @param {string} id * @param {number} index * @param {string} name * @returns {any} */ maplibregl.Map.prototype.getSymbolProperty = function (id, index, name) { return getSymbolHandler(this).getSymbolProperty(id, index, name); }; maplibregl.Map.prototype.getStyle = function () { if (this.style) { return getSymbolHandler(this).getStyle(); } }; maplibregl.Map.prototype.setFilter = function (layerId, filter, options) { if (this.style.getLayer(layerId)) { this.style.setFilter(layerId, filter, options); return this._update(true); } getSymbolHandler(this).setFilter(layerId, filter, options); return this._update(true); }; maplibregl.Map.prototype.getFilter = function (layerId) { if (this.style.getLayer(layerId)) { return this.style.getFilter(layerId); } return getSymbolHandler(this).getFilter(layerId); }; maplibregl.Map.prototype.setLayerZoomRange = function (layerId, minzoom, maxzoom) { if (this.style.getLayer(layerId)) { this.style.setLayerZoomRange(layerId, minzoom, maxzoom); return this._update(true); } getSymbolHandler(this).setLayerZoomRange(layerId, minzoom, maxzoom); return this._update(true); }; maplibregl.Map.prototype.setPaintProperty = function (layerId, name, value, options) { if (this.style.getLayer(layerId)) { this.style.setPaintProperty(layerId, name, value, options); return this._update(true); } getSymbolHandler(this).setPaintProperty(layerId, name, value, options); return this._update(true); }; maplibregl.Map.prototype.getPaintProperty = function (layerId, name) { if (this.style.getLayer(layerId)) { return this.style.getPaintProperty(layerId, name); } return getSymbolHandler(this).getPaintProperty(layerId, name); }; maplibregl.Map.prototype.getLayoutProperty = function (layerId, name) { if (this.style.getLayer(layerId)) { return this.style.getLayoutProperty(layerId, name); } return getSymbolHandler(this).getLayoutProperty(layerId, name); }; if (maplibregl.Map.prototype.onBak === undefined) { maplibregl.Map.prototype.onBak = maplibregl.Map.prototype.on; maplibregl.Map.prototype.on = function (type, layerId, listener) { if (listener === undefined || this.style.getLayer(layerId)) { return this.onBak(type, layerId, listener); } const layerIds = getSymbolHandler(this).getLayerIds(layerId); layerIds.forEach(id => this.onBak(type, id, listener)); return this; }; } if (maplibregl.Map.prototype.onceBak === undefined) { maplibregl.Map.prototype.onceBak = maplibregl.Map.prototype.once; maplibregl.Map.prototype.once = function (type, layerId, listener) { if (listener === undefined || this.style.getLayer(layerId)) { return this.onceBak(type, layerId, listener); } const layerIds = getSymbolHandler(this).getLayerIds(layerId); layerIds.forEach(id => this.onceBak(type, id, listener)); return this; }; } if (maplibregl.Map.prototype.offBak === undefined) { maplibregl.Map.prototype.offBak = maplibregl.Map.prototype.off; maplibregl.Map.prototype.off = function (type, layerId, listener) { if (listener === undefined || this.style.getLayer(layerId)) { return this.offBak(type, layerId, listener); } const layerIds = getSymbolHandler(this).getLayerIds(layerId); layerIds.forEach(id => this.offBak(type, id, listener)); return this; }; } /** * @function WebSymbol.prototype.getSymbol * @param {string} id - 符号ID。 * @description 获取符号信息。 * @returns {object} 符号信息。 * @private */ async function getSymbol(id, map) { let url = `${map.basePath}/${id}/${id}`; if (process.env.NODE_ENV === 'development') { url = `../../dist/resources/symbols/${id}/${id}`; } const value = await FetchRequest.get(`${url}.json`).then(response => { if (!response.ok) { return null; } return response.json(); }) .catch(() => null); if (!value) { return null; } const paint = value.paint || {}; const layout = value.layout || {}; const hasImage = paint['fill-pattern'] || paint['line-pattern'] || layout['icon-image']; const image = hasImage && await new Promise((resolve) => { const image = new Image(); image.src = `${url}.png`; image.onload = (content) => { resolve(content ? image : null); }; image.onerror = () => { resolve(null); }; }); return { value, image } } /** * 加载单个Web符号 * @param {string} id * @param {Mapboxgl.Map} map * @returns {object} symbol对象 */ function loadSymbol(id, map) { return getSymbol(id, map).then((symbolResult) => { if (!symbolResult) { return null; } const { value, image } = symbolResult; image && getSymbolHandler(map).addSymbolImageToMap(value, image); return value; }) } } export default MapExtendSymbol