diff --git a/src/common/mapping/WebMapBase.js b/src/common/mapping/WebMapBase.js index d690e9357..5dcf5cf8b 100644 --- a/src/common/mapping/WebMapBase.js +++ b/src/common/mapping/WebMapBase.js @@ -449,7 +449,8 @@ return; } const sourceList = []; - for (const item of this._cacheCleanLayers) { + const layersToClean = this._cacheCleanLayers.filter(item => !item.reused); + for (const item of layersToClean) { item.renderLayers.forEach((layerId) => { if (this.map.getLayer(layerId)) { this.map.removeLayer(layerId); diff --git a/src/common/mapping/WebMapV2.js b/src/common/mapping/WebMapV2.js index 26b8757fc..faf4856f1 100644 --- a/src/common/mapping/WebMapV2.js +++ b/src/common/mapping/WebMapV2.js @@ -42,12 +42,6 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { this._appendLayers = false; } - /** - * @private - * @function WebMapV2.prototype.initializeMap - * @description 登陆窗口后添加地图图层。 - * @param {Object} mapInfo - map 信息。 - */ initializeMap(mapInfo, map) { if (map) { this._appendLayers = true; @@ -2226,7 +2220,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { } _rectifyLayersOrder(appreciableLayers, topLayerBeforeId) { - const renderLayers = appreciableLayers.reduce((layers, layer) => { + const renderLayers = appreciableLayers.filter(item => !item.reused).reduce((layers, layer) => { return layers.concat(layer.renderLayers); }, []); const labelLayerIds = []; @@ -2726,7 +2720,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { const { id } = layerInfo; if (this.map.getLayer(id)) { if (this.checkSameLayer && this._isSameRasterLayer(id, layerInfo)) { - this._setCacheLayer({ layerInfo, parentLayerId, id, ignore: true, beforeId }); + this._setCacheLayer({ layerInfo, parentLayerId, id, reused: true, beforeId }); return; } this._updateLayer(layerInfo); @@ -2737,8 +2731,8 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { this._setCacheLayer({ layerInfo, parentLayerId, id, beforeId }); } - _setCacheLayer({ parentLayerId, layerInfo, ignore = false, beforeId, subRenderLayers }) { - const renderLayers = subRenderLayers || [{ layerId: layerInfo.id, ignore }]; + _setCacheLayer({ parentLayerId, layerInfo, reused = false, beforeId, subRenderLayers }) { + const renderLayers = subRenderLayers || [{ layerId: layerInfo.id, reused }]; if (!this._cacheLayerId.has(parentLayerId)) { this._cacheLayerId.set(parentLayerId, renderLayers); } else { @@ -2763,7 +2757,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { layerInfo.visible === void 0 || layerInfo.visible === 'visible' || layerInfo.visible === true; const matchLayers = this._cacheLayerId.get(targetLayerId); if (matchLayers) { - const renderLayers = matchLayers.filter((item) => !item.ignore).map((item) => item.layerId); + const renderLayers = matchLayers.map((item) => item.layerId); if (!renderLayers.length) { return; } @@ -2771,14 +2765,15 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { ...layerInfo, id: targetLayerId, visible: targetLayerVisible, - renderLayers + renderLayers, + reused: matchLayers.some(item => item.reused) || void 0 }); } }); this._changeSourceListModel(layersFromMapInfo); const appreciableLayers = this.getLayers(); if (this.addLayersSucceededLen && this._cacheLayerId.size !== this.addLayersSucceededLen) { - const selfAppreciableLayers = this.getSelfAppreciableLayers(appreciableLayers) + const selfAppreciableLayers = this.getSelfAppreciableLayers(appreciableLayers); const topLayerBeforeId = this._findTopLayerBeforeId(selfAppreciableLayers); this._rectifyLayersOrder(selfAppreciableLayers, topLayerBeforeId); this.addLayersSucceededLen = this._cacheLayerId.size; @@ -2788,7 +2783,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) { _findTopLayerBeforeId(selfAppreciableLayers) { // fix 追加图层,异步的图层回来排序错乱 - const selfLayerIds = selfAppreciableLayers.reduce((ids, item) => ids.concat(item.renderLayers), []); + const selfLayerIds = selfAppreciableLayers.filter(item => !item.reused).reduce((ids, item) => ids.concat(item.renderLayers), []); const firstSelfLayerIdOnMap = selfLayerIds.find((id) => this.map.style._layers[id]); if (!firstSelfLayerIdOnMap) { return; diff --git a/src/common/mapping/utils/AppreciableLayerBase.js b/src/common/mapping/utils/AppreciableLayerBase.js index 850b7ece5..e1674015e 100644 --- a/src/common/mapping/utils/AppreciableLayerBase.js +++ b/src/common/mapping/utils/AppreciableLayerBase.js @@ -152,7 +152,8 @@ export class AppreciableLayerBase { title = name, visible = layer.visibility ? layer.visibility === 'visible' : true, CLASS_NAME, - CLASS_INSTANCE + CLASS_INSTANCE, + reused } = layerInfo; const sourceOnMap = this.map.getSource(layer.source); const fields = { @@ -179,6 +180,9 @@ export class AppreciableLayerBase { if (CLASS_INSTANCE) { fields.CLASS_INSTANCE = CLASS_INSTANCE; } + if (reused !== void 0) { + fields.reused = reused; + } return fields; } } diff --git a/src/common/mapping/utils/SourceModel.js b/src/common/mapping/utils/SourceModel.js index 8ef93ca46..68870e163 100644 --- a/src/common/mapping/utils/SourceModel.js +++ b/src/common/mapping/utils/SourceModel.js @@ -8,6 +8,9 @@ class SourceModel { this.type = options.type; this.themeSetting = options.themeSetting; this.visible = options.visible; + if (options.reused) { + this.reused = options.reused; + } } addLayer(layer) { diff --git a/test/common/mapping/utils/SourceListModelV2Spec.js b/test/common/mapping/utils/SourceListModelV2Spec.js index e37f48ca3..a64f4fada 100644 --- a/test/common/mapping/utils/SourceListModelV2Spec.js +++ b/test/common/mapping/utils/SourceListModelV2Spec.js @@ -1,186 +1,190 @@ import { SourceListModelV2 } from '../../../../src/common/mapping/utils/SourceListModelV2'; describe('SourceListV2', () => { - const layers = [ - { - id: 'background', - type: 'background', - layout: { - visibility: 'visible' + let layers, map; + + beforeEach(() => { + layers = [ + { + id: 'background', + type: 'background', + layout: { + visibility: 'visible' + }, + paint: { + 'background-color': '#065726', + 'background-opacity': 0.5 + } }, - paint: { - 'background-color': '#065726', - 'background-opacity': 0.5 - } - }, - { - id: 'CHINA_DARK', - type: 'raster', - source: 'CHINA_DARK', - minzoom: 0, - maxzoom: 12 - }, - { - id: 'test-id', - type: 'raster', - source: 'test-source', - minzoom: 0, - maxzoom: 12 - }, - { - id: 'test-id-label', - type: 'raster', - source: 'test-source', - minzoom: 0, - maxzoom: 12, - metadata: { parentLayerId: 'test-source' } - }, - { - id: 'tracklayer-1-line', - type: 'line', - source: 'tracklayer-1-line', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'CHINA_DARK', + type: 'raster', + source: 'CHINA_DARK', + minzoom: 0, + maxzoom: 12 }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'tdt-search-line', - type: 'line', - source: 'tdt-search-line', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'test-id', + type: 'raster', + source: 'test-source', + minzoom: 0, + maxzoom: 12 }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'tdt-route-line', - type: 'line', - source: 'tdt-route-line', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'test-id-label', + type: 'raster', + source: 'test-source', + minzoom: 0, + maxzoom: 12, + metadata: { parentLayerId: 'test-source' } }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'smmeasure', - type: 'line', - source: 'smmeasure', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'tracklayer-1-line', + type: 'line', + source: 'tracklayer-1-line', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } + }, + { + id: 'tdt-search-line', + type: 'line', + source: 'tdt-search-line', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } + }, + { + id: 'tdt-route-line', + type: 'line', + source: 'tdt-route-line', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } + }, + { + id: 'smmeasure', + type: 'line', + source: 'smmeasure', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'mapbox-gl-draw', - type: 'line', - source: 'mapbox-gl-draw', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'mapbox-gl-draw', + type: 'line', + source: 'mapbox-gl-draw', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'mapbox-gl-draw-line', - type: 'line', - source: 'mapbox-gl-draw', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'mapbox-gl-draw-line', + type: 'line', + source: 'mapbox-gl-draw', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 - } - }, - { - id: 'test-SM-highlight', - type: 'line', - source: 'mapbox-gl-draw', - layout: { - 'line-cap': 'round', - 'line-join': 'round' + { + id: 'test-SM-highlight', + type: 'line', + source: 'mapbox-gl-draw', + layout: { + 'line-cap': 'round', + 'line-join': 'round' + }, + paint: { + 'line-color': '#065726', + 'line-width': 5, + 'line-opacity': 0.8 + } }, - paint: { - 'line-color': '#065726', - 'line-width': 5, - 'line-opacity': 0.8 + { + id: 'graticuleLayer_1723443238046_line', + type: 'line', + source: 'graticuleLayer_1723443238046_line', + layout: { + 'line-join': 'round', + 'line-cap': 'round', + visibility: 'visible' + }, + paint: { + 'line-color': '#15eec2', + 'line-width': 2, + 'line-offset': 0, + 'line-translate-anchor': 'viewport', + 'line-dasharray': [0.5, 4] + } } - }, - { - id: 'graticuleLayer_1723443238046_line', - type: 'line', - source: 'graticuleLayer_1723443238046_line', - layout: { - 'line-join': 'round', - 'line-cap': 'round', - visibility: 'visible' + ]; + map = { + getStyle() { + return { + layers + }; }, - paint: { - 'line-color': '#15eec2', - 'line-width': 2, - 'line-offset': 0, - 'line-translate-anchor': 'viewport', - 'line-dasharray': [0.5, 4] - } - } - ]; - const map = { - getStyle() { - return { - layers - }; - }, - getSource() { - return { - type: 'geojson', - data: { - type: 'FeatureCollection', - features: [] + getSource() { + return { + type: 'geojson', + data: { + type: 'FeatureCollection', + features: [] + } + }; + }, + getLayer(id) { + return layers.find((layer) => layer.id === id); + }, + overlayLayersManager: { + graticuleLayer_1723443238046: { + id: 'graticuleLayer_1723443238046', + overlay: true, + renderingMode: '3d', + type: 'custom', + visible: true, + sourceId: 'graticuleLayer_1723443238046_line' } - }; - }, - getLayer(id) { - return layers.find((layer) => layer.id === id); - }, - overlayLayersManager: { - graticuleLayer_1723443238046: { - id: 'graticuleLayer_1723443238046', - overlay: true, - renderingMode: '3d', - type: 'custom', - visible: true, - sourceId: 'graticuleLayer_1723443238046_line' } - } - }; + }; + }); it('getLayers', (done) => { const sourceListModel = new SourceListModelV2({ map }); @@ -420,4 +424,66 @@ describe('SourceListV2', () => { expect(layerList[0].type).toBe('group'); done(); }); + + it('test mark reused', (done) => { + map.overlayLayersManager = {}; + layers = [ + { + id: '天地图影像', + type: 'raster', + source: '天地图影像', + metadata: { + parentLayerId: '天地图影像' + }, + minzoom: 0, + maxzoom: 22, + layout: { + visibility: 'visible' + } + }, + { + id: 'T202007210700', + type: 'raster', + source: 'T202007210700', + metadata: { + parentLayerId: 'T202007210700' + }, + minzoom: 0, + maxzoom: 22, + layout: { + visibility: 'none' + } + } + ]; + const sourceListModel = new SourceListModelV2({ + map, + layers: [ + { + layerType: 'TIANDITU_IMG_3857', + visible: true, + labelLayerVisible: true, + tk: '8c88eba266a165eac9c085724708f2f9', + name: '天地图影像', + id: '天地图影像', + renderLayers: ['天地图影像'], + reused: true + }, + { + layerType: 'TILE', + visible: true, + name: 'T202007210700', + id: 'T202007210700', + url: 'http://fakeurl', + renderLayers: ['T202007210700'] + } + ] + }); + const appreciableLayers = sourceListModel.getLayers(); + const selfAppreciableLayers = sourceListModel.getSelfLayers(); + expect(appreciableLayers.length).toBe(2); + expect(selfAppreciableLayers.length).toBe(2); + expect(appreciableLayers[0].reused).toBeTruthy(); + expect(appreciableLayers[1].reused).toBeUndefined(); + done(); + }); }); diff --git a/test/mapboxgl/mapping/WebMapV2Spec.js b/test/mapboxgl/mapping/WebMapV2Spec.js index de24dffa2..b068b518a 100644 --- a/test/mapboxgl/mapping/WebMapV2Spec.js +++ b/test/mapboxgl/mapping/WebMapV2Spec.js @@ -2682,4 +2682,56 @@ describe('mapboxgl_WebMapV2', () => { done(); }); }); + + it('test checkSameLayer', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } + if (url.indexOf('1209527958/map.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(qixiangLayer1))); + } + if (url.indexOf('106007908/map.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(qixiangLayer2))); + } + }); + datavizWebmap = new WebMap( + '', + { ...commonOption }, + { style: { version: 8, sources: {}, layers: [] }, center: [0, 0], zoom: 1, crs: 'EPSG:3857' } + ); + const callback = function (data) { + const appreciableLayers = datavizWebmap.getLayers(); + expect(appreciableLayers.length).toBe(0); + const webMap1 = new WebMap(1209527958, { ...commonOption, map: data.map, checkSameLayer: true }); + webMap1.once('mapcreatesucceeded', ({ layers }) => { + expect(layers.length).toBe(2); + expect(layers[0].reused).toBeUndefined(); + expect(layers[0].id).toBe('天地图影像'); + expect(layers[1].reused).toBeUndefined(); + const webMap2 = new WebMap(106007908, { ...commonOption, map: data.map, checkSameLayer: true }); + webMap2.once('mapcreatesucceeded', ({ layers, map }) => { + expect(layers.length).toBe(2); + expect(layers[0].reused).toBeTruthy(); + expect(layers[0].id).toBe('天地图影像'); + expect(layers[1].reused).toBeUndefined(); + let layersOnMap = map.getStyle().layers; + expect(layersOnMap.length).toBe(4); + expect(layersOnMap[0].id).toBe('天地图影像'); + expect(layersOnMap[1].id).toBe('天地图影像-tdt-label'); + expect(layersOnMap[2].id).toBe('T202007210600'); + expect(layersOnMap[3].id).toBe('T202007210700'); + webMap2.cleanLayers(); + layersOnMap = map.getStyle().layers; + expect(layersOnMap.length).toBe(3); + expect(layersOnMap[0].id).toBe('天地图影像'); + expect(layersOnMap[1].id).toBe('天地图影像-tdt-label'); + expect(layersOnMap[2].id).toBe('T202007210600'); + webMap1.cleanLayers(); + done(); + }); + }); + }; + datavizWebmap.once('mapcreatesucceeded', callback); + }); }); diff --git a/test/maplibregl/mapping/WebMapV2Spec.js b/test/maplibregl/mapping/WebMapV2Spec.js index 0ef5b2c3c..13dc38d96 100644 --- a/test/maplibregl/mapping/WebMapV2Spec.js +++ b/test/maplibregl/mapping/WebMapV2Spec.js @@ -2682,4 +2682,56 @@ describe('maplibregl_WebMapV2', () => { done(); }); }); + + it('test checkSameLayer', (done) => { + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } + if (url.indexOf('1209527958/map.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(qixiangLayer1))); + } + if (url.indexOf('106007908/map.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(qixiangLayer2))); + } + }); + datavizWebmap = new WebMap( + '', + { ...commonOption }, + { style: { version: 8, sources: {}, layers: [] }, center: [0, 0], zoom: 1, crs: 'EPSG:3857' } + ); + const callback = function (data) { + const appreciableLayers = datavizWebmap.getLayers(); + expect(appreciableLayers.length).toBe(0); + const webMap1 = new WebMap(1209527958, { ...commonOption, map: data.map, checkSameLayer: true }); + webMap1.once('mapcreatesucceeded', ({ layers }) => { + expect(layers.length).toBe(2); + expect(layers[0].reused).toBeUndefined(); + expect(layers[0].id).toBe('天地图影像'); + expect(layers[1].reused).toBeUndefined(); + const webMap2 = new WebMap(106007908, { ...commonOption, map: data.map, checkSameLayer: true }); + webMap2.once('mapcreatesucceeded', ({ layers, map }) => { + expect(layers.length).toBe(2); + expect(layers[0].reused).toBeTruthy(); + expect(layers[0].id).toBe('天地图影像'); + expect(layers[1].reused).toBeUndefined(); + let layersOnMap = map.getStyle().layers; + expect(layersOnMap.length).toBe(4); + expect(layersOnMap[0].id).toBe('天地图影像'); + expect(layersOnMap[1].id).toBe('天地图影像-tdt-label'); + expect(layersOnMap[2].id).toBe('T202007210600'); + expect(layersOnMap[3].id).toBe('T202007210700'); + webMap2.cleanLayers(); + layersOnMap = map.getStyle().layers; + expect(layersOnMap.length).toBe(3); + expect(layersOnMap[0].id).toBe('天地图影像'); + expect(layersOnMap[1].id).toBe('天地图影像-tdt-label'); + expect(layersOnMap[2].id).toBe('T202007210600'); + webMap1.cleanLayers(); + done(); + }); + }); + }; + datavizWebmap.once('mapcreatesucceeded', callback); + }); }); diff --git a/test/resources/WebMapV5.js b/test/resources/WebMapV5.js index 9f0aa5bed..2bd5a83ec 100644 --- a/test/resources/WebMapV5.js +++ b/test/resources/WebMapV5.js @@ -3378,3 +3378,82 @@ var restmapLayer = { "rootUrl": "http://localhost:8190/iportal/services/../" } +var qixiangLayer1 = { + "extent": { + "leftBottom": { + "x": -20037508.3427892, + "y": -20037508.3427892 + }, + "rightTop": { + "x": 20037508.3427892, + "y": 20037508.3427892 + } + }, + "maxScale": "1:1128.499", + "level": 4, + "center": { + "x": 10904880.84944567, + "y": 4221889.42915377 + }, + "baseLayer": { + "layerType": "TIANDITU_IMG_3857", + "visible": true, + "labelLayerVisible": true, + "tk": "8c88eba266a165eac9c085724708f2f9", + "name": "天地图影像" + }, + "layers": [ + { + "layerType": "TILE", + "visible": true, + "name": "T202007210600", + "url": "https://www.supermapol.com/proxy/iserver/services/map_qixiangyun_l93wywbb/rest/maps/T202007210600" + } + ], + "description": "", + "projection": "EPSG:3857", + "minScale": "1:591658710.909", + "title": "气象云202007210600", + "version": "2.2.1", + "rootUrl": "https://www.supermapol.com/" +} + +var qixiangLayer2 = { + "extent": { + "leftBottom": { + "x": -20037508.3427892, + "y": -20037508.3427892 + }, + "rightTop": { + "x": 20037508.3427892, + "y": 20037508.3427892 + } + }, + "maxScale": "1:1128.499", + "level": 4, + "center": { + "x": 10904880.84944567, + "y": 4221889.42915377 + }, + "baseLayer": { + "layerType": "TIANDITU_IMG_3857", + "visible": true, + "labelLayerVisible": true, + "tk": "8c88eba266a165eac9c085724708f2f9", + "name": "天地图影像" + }, + "layers": [ + { + "layerType": "TILE", + "visible": true, + "name": "T202007210700", + "url": "https://www.supermapol.com/proxy/iserver/services/map_qixiangyun_l93wywbb/rest/maps/T202007210700" + } + ], + "description": "", + "projection": "EPSG:3857", + "minScale": "1:591658710.909", + "title": "气象云202007210700", + "version": "2.2.1", + "rootUrl": "https://www.supermapol.com/" +} \ No newline at end of file diff --git a/test/tool/mock_mapboxgl_map.js b/test/tool/mock_mapboxgl_map.js index 171694e7a..5b9a21921 100644 --- a/test/tool/mock_mapboxgl_map.js +++ b/test/tool/mock_mapboxgl_map.js @@ -209,7 +209,13 @@ const Map = function (options) { return style; }); - this.removeLayer = function (layerId) {}; + this.removeLayer = function (layerId) { + delete this._layers[layerId]; + const matchIndex = this._layersList.findIndex(item => item.id === layerId); + if (matchIndex > -1) { + this._layersList.splice(matchIndex, 1); + } + }; this.moveLayer = function (layerId, beforeId) { const matchLayerIndex = this._layersList.findIndex(item => item.id === layerId); if (matchLayerIndex === -1) { diff --git a/test/tool/mock_maplibregl_map.js b/test/tool/mock_maplibregl_map.js index fe73b90b9..e7b19688e 100644 --- a/test/tool/mock_maplibregl_map.js +++ b/test/tool/mock_maplibregl_map.js @@ -209,7 +209,13 @@ const Map = function (options) { return style; }); - this.removeLayer = function (layerId) {}; + this.removeLayer = function (layerId) { + delete this._layers[layerId]; + const matchIndex = this._layersList.findIndex(item => item.id === layerId); + if (matchIndex > -1) { + this._layersList.splice(matchIndex, 1); + } + }; this.moveLayer = function (layerId, beforeId) { const matchLayerIndex = this._layersList.findIndex(item => item.id === layerId); if (matchLayerIndex === -1) {