diff --git a/src/common/mapping/WebMapV3.js b/src/common/mapping/WebMapV3.js index 6503006e0..5674d6d81 100644 --- a/src/common/mapping/WebMapV3.js +++ b/src/common/mapping/WebMapV3.js @@ -2,7 +2,7 @@ * 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 { FetchRequest } from '../util/FetchRequest'; -import { getLayerInfosFromCatalogs, isSameRasterLayer, mergeFeatures, transformUrl } from './utils/util'; +import { getLayerInfosFromCatalogs, getMainLayerFromCatalog, isSameRasterLayer, mergeFeatures, transformUrl } from './utils/util'; import { SourceListModelV3 } from './utils/SourceListModelV3'; const LEGEND_RENDER_TYPE = { @@ -710,9 +710,7 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, mapRe if (!renderer) { continue; } - const layerFromMapInfo = this._mapInfo.layers.find((item) => { - return item.id === layer.id; - }); + const layerFromMapInfo = getMainLayerFromCatalog(layer.layersContent, layer.id, this._mapInfo.layers); let themeField; const sourceInfo = this._mapInfo.sources[layerFromMapInfo.source]; if ('clusterField' in sourceInfo) { diff --git a/src/common/mapping/utils/SourceListModelV3.js b/src/common/mapping/utils/SourceListModelV3.js index 79c35535a..82b1ca0cd 100644 --- a/src/common/mapping/utils/SourceListModelV3.js +++ b/src/common/mapping/utils/SourceListModelV3.js @@ -1,6 +1,6 @@ import { AppreciableLayerBase } from './AppreciableLayerBase'; -import { getLayerInfosFromCatalogs } from './util'; +import { getLayerCatalogRenderLayers, getLayerInfosFromCatalogs, getMainLayerFromCatalog } from './util'; export class SourceListModelV3 extends AppreciableLayerBase { constructor(options = {}) { @@ -50,7 +50,7 @@ export class SourceListModelV3 extends AppreciableLayerBase { _createSourceCatalogs(catalogs, appreciableLayers) { const formatCatalogs = catalogs.map((catalog) => { let formatItem; - const { id, title = id, type, visible, children } = catalog; + const { id, title = id, type, visible, children, parts } = catalog; if (type === 'group') { formatItem = { children: this._createSourceCatalogs(children, appreciableLayers), @@ -60,7 +60,8 @@ export class SourceListModelV3 extends AppreciableLayerBase { visible }; } else { - const matchLayer = appreciableLayers.find((layer) => layer.id === id); + const renderLayers = getLayerCatalogRenderLayers(parts, id, this._mapInfo.layers); + const matchLayer = appreciableLayers.find((layer) => layer.id === renderLayers[0]); this.removeLayerExtralFields([matchLayer]); formatItem = Object.assign({}, matchLayer); } @@ -75,8 +76,9 @@ export class SourceListModelV3 extends AppreciableLayerBase { const metadataCatalogs = getLayerInfosFromCatalogs(this._mapInfo.metadata.layerCatalog); const l7MarkerLayers = this._l7LayerUtil.getL7MarkerLayers(); const layerDatas = metadataCatalogs.map(layerCatalog => { - const layer = this._mapInfo.layers.find(item => item.id === layerCatalog.id) || {}; - const layerInfo = { id: layer.id, title: layerCatalog.title, renderLayers: this._getRenderLayers(layerCatalog.parts, layerCatalog.id), reused: layer.metadata && layer.metadata.reused }; + const renderLayers = getLayerCatalogRenderLayers(layerCatalog.parts, layerCatalog.id, this._mapInfo.layers); + const layer = getMainLayerFromCatalog(layerCatalog.parts, layerCatalog.id, this._mapInfo.layers); + const layerInfo = { id: layer.id, title: layerCatalog.title, renderLayers, reused: layer.metadata && layer.metadata.reused }; const matchProjectCatalog = projectCataglogs.find((item) => item.id === layerCatalog.id) || {}; const { msDatasetId } = matchProjectCatalog; let dataSource = {}; @@ -133,16 +135,4 @@ export class SourceListModelV3 extends AppreciableLayerBase { layerDatas.reverse(); return layerDatas; } - - _getRenderLayers(layerIds, layerId) { - if (layerIds) { - if (layerIds.includes(layerId)) { - return layerIds; - } else { - return [layerId, ...layerIds]; - } - } else { - return [layerId]; - } - } } diff --git a/src/common/mapping/utils/util.js b/src/common/mapping/utils/util.js index f18c4d764..bc61ef7e3 100644 --- a/src/common/mapping/utils/util.js +++ b/src/common/mapping/utils/util.js @@ -185,4 +185,18 @@ export function createAppreciableLayerId(layer) { // 针对 MapboxStyle 或者其它额外的 layer // type: background 和某些 overlaymanager layers 只有 id return layer.sourceLayer || layer.source || layer.id; +} + +export function getLayerCatalogRenderLayers(parts, catalogId, layersOnMap) { + // ms 3.0.5以下的版本 layerCatalogs layersContent/parts 不包括自身的上图layerid 只包含复合图层的id + const renderLayers = layersOnMap.some(item => item.id === catalogId) ? [catalogId] : []; + if (parts) { + renderLayers.push(...parts); + } + return Array.from(new Set(renderLayers)).filter(item => !!item); +} + +export function getMainLayerFromCatalog(layerParts, catalogId, layersOnMap) { + const renderLayers = getLayerCatalogRenderLayers(layerParts, catalogId, layersOnMap); + return layersOnMap.find(item => item.id === renderLayers[0]); } \ No newline at end of file diff --git a/test/common/mapping/utils/SourceListModelV3Spec.js b/test/common/mapping/utils/SourceListModelV3Spec.js index e398fd25e..821248a14 100644 --- a/test/common/mapping/utils/SourceListModelV3Spec.js +++ b/test/common/mapping/utils/SourceListModelV3Spec.js @@ -271,6 +271,66 @@ describe('SourceListV3', () => { done(); }); + it('layerCatalog parts not include self layer and ui id is layerId on Map', (done) => { + const mapInfo = JSON.parse(mapstudioWebMap_symbol); + const sourceListModel = new SourceListModelV3({ + map, + mapInfo, + mapResourceInfo: {}, + legendList: [], + l7LayerUtil: { + isL7Layer, + getL7MarkerLayers: () => ({}) + } + }); + const layerList = sourceListModel.getLayerCatalog(); + expect(layerList.length).toBe(mapInfo.metadata.layerCatalog.length + 4); + const selfIds = mapInfo.metadata.layerCatalog.map(item => item.id); + const selfLayerCatalogs = layerList.filter(layer => selfIds.includes(layer.id)); + expect(selfLayerCatalogs.some(layer => !layer.renderLayers.includes(layer.id))).toBe(false); + done(); + }); + + it('layerCatalog parts include self layer', (done) => { + const mapInfo = JSON.parse(mapstudioWebMap_labelLegend); + const sourceListModel = new SourceListModelV3({ + map, + mapInfo, + mapResourceInfo: {}, + legendList: [], + l7LayerUtil: { + isL7Layer, + getL7MarkerLayers: () => ({}) + } + }); + const layerList = sourceListModel.getLayerCatalog(); + expect(layerList.length).toBe(mapInfo.metadata.layerCatalog.length + 3); + const selfIds = mapInfo.metadata.layerCatalog.map(item => item.id); + const selfLayerCatalogs = layerList.filter(layer => selfIds.includes(layer.id)); + expect(selfLayerCatalogs.some(layer => !layer.renderLayers.includes(layer.id))).toBe(false); + done(); + }); + + it('layerCatalog parts not include self layer and ui id is not layerId on Map', (done) => { + const mapInfo = JSON.parse(mapstudioWebMap_separate_layerCatalogId); + const sourceListModel = new SourceListModelV3({ + map, + mapInfo, + mapResourceInfo: {}, + legendList: [], + l7LayerUtil: { + isL7Layer, + getL7MarkerLayers: () => ({}) + } + }); + const layerList = sourceListModel.getLayerCatalog(); + expect(layerList.length).toBe(mapInfo.metadata.layerCatalog.length + 4); + const selfIds = mapInfo.metadata.layerCatalog.filter(item => item.parts).map(item => item.id); + const selfLayerCatalogs = layerList.filter(layer => selfIds.includes(layer.id)); + expect(selfLayerCatalogs.some(layer => layer.renderLayers.includes(layer.id))).toBe(false); + done(); + }); + it('destroy', (done) => { const mapInfo = JSON.parse(mapstudioWebMap_chart); const sourceListModel = new SourceListModelV3({ diff --git a/test/mapboxgl/mapping/WebMapV3Spec.js b/test/mapboxgl/mapping/WebMapV3Spec.js index 834068d09..e107ca3bb 100644 --- a/test/mapboxgl/mapping/WebMapV3Spec.js +++ b/test/mapboxgl/mapping/WebMapV3Spec.js @@ -1370,4 +1370,42 @@ describe('mapboxgl-webmap3.0', () => { mapstudioWebmap.setLayersVisible([layers[0]], 'visible'); }); }); + + it('layerCatalog separate ui id and render id', (done) => { + spyOn(MapManagerUtil, 'default').and.callFake(mbglmap); + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('web/config/portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } + if (url.indexOf('map.json') > -1) { + return Promise.resolve(new Response(mapstudioWebMap_separate_layerCatalogId)); + } + if (url.indexOf('617580084.json') > -1) { + return Promise.resolve(new Response(msProjectINfo_separate_layerCatalogId)); + } + if (url.indexOf('/sprite') > -1) { + return Promise.resolve(new Response(msSpriteInfo)); + } + return Promise.resolve(); + }); + mapstudioWebmap = new WebMap(id, { + server: server + }); + + mapstudioWebmap.on('mapcreatesucceeded', ({ map }) => { + expect(map).not.toBeUndefined(); + expect(mapstudioWebmap.map).toEqual(map); + const style = map.getStyle(); + const webMapV3 = mapstudioWebmap._getWebMapInstance(); + const mapInfo = JSON.parse(mapstudioWebMap_separate_layerCatalogId); + expect(style.layers.length).toBe(mapInfo.layers.length); + expect(webMapV3.getLegends().length).not.toBe(0); + const layerCatalogs = webMapV3.getLayerCatalog(); + expect(layerCatalogs.length).not.toBe(0); + expect(layerCatalogs.length).toBe(mapInfo.metadata.layerCatalog.length); + const appreciableLayers = webMapV3.getLayers(); + expect(layerCatalogs.length).toBe(appreciableLayers.length); + done(); + }); + }); }); diff --git a/test/maplibregl/mapping/WebMapV3Spec.js b/test/maplibregl/mapping/WebMapV3Spec.js index 35e0d3d8b..02b0b6a66 100644 --- a/test/maplibregl/mapping/WebMapV3Spec.js +++ b/test/maplibregl/mapping/WebMapV3Spec.js @@ -1323,4 +1323,42 @@ describe('maplibregl-webmap3.0', () => { mapstudioWebmap.setLayersVisible([layers[0]], 'visible'); }); }); + + it('layerCatalog separate ui id and render id', (done) => { + spyOn(MapManagerUtil, 'default').and.callFake(mbglmap); + spyOn(FetchRequest, 'get').and.callFake((url) => { + if (url.indexOf('web/config/portal.json') > -1) { + return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy))); + } + if (url.indexOf('map.json') > -1) { + return Promise.resolve(new Response(mapstudioWebMap_separate_layerCatalogId)); + } + if (url.indexOf('617580084.json') > -1) { + return Promise.resolve(new Response(msProjectINfo_separate_layerCatalogId)); + } + if (url.indexOf('/sprite') > -1) { + return Promise.resolve(new Response(msSpriteInfo)); + } + return Promise.resolve(); + }); + mapstudioWebmap = new WebMap(id, { + server: server + }); + + mapstudioWebmap.on('mapcreatesucceeded', ({ map }) => { + expect(map).not.toBeUndefined(); + expect(mapstudioWebmap.map).toEqual(map); + const style = map.getStyle(); + const webMapV3 = mapstudioWebmap._getWebMapInstance(); + const mapInfo = JSON.parse(mapstudioWebMap_separate_layerCatalogId); + expect(style.layers.length).toBe(mapInfo.layers.length); + expect(webMapV3.getLegends().length).not.toBe(0); + const layerCatalogs = webMapV3.getLayerCatalog(); + expect(layerCatalogs.length).not.toBe(0); + expect(layerCatalogs.length).toBe(mapInfo.metadata.layerCatalog.length); + const appreciableLayers = webMapV3.getLayers(); + expect(layerCatalogs.length).toBe(appreciableLayers.length); + done(); + }); + }); }); diff --git a/test/resources/WebMapV3.js b/test/resources/WebMapV3.js index d0d864871..7ec77789a 100644 --- a/test/resources/WebMapV3.js +++ b/test/resources/WebMapV3.js @@ -3237,4 +3237,168 @@ var msProjectINfo_chart = JSON.stringify({ "isDefaultBottomMap": false, "status": null, "favoriteCount": 0 -}) \ No newline at end of file +}) + +var mapstudioWebMap_separate_layerCatalogId = JSON.stringify({ + metadata: { + layerCatalog: [ + { + visible: true, + parts: ['北京轨道交通分布.geojson'], + id: 'layer_北京轨道交通分布.geojson', + title: '北京轨道交通分布.geojson', + type: 'composite' + }, + { + visible: true, + parts: ['北京住宅小区分布.geojson'], + id: 'layer_北京住宅小区分布.geojson', + title: '北京住宅小区分布.geojson', + type: 'composite' + }, + { + visible: true, + id: 'ms-background', + title: '纯色底图', + type: 'basic' + } + ] + }, + sources: { + ms_1731639917_1731394669710_25: { + tiles: [ + 'ttp://localhost:8190/iportal/web/datas/1731639917/structureddata/tiles/{z}/{x}/{y}.mvt?epsgCode=3857&returnedFieldNames=%5B%22smpid%22%2C%22%E5%B0%8F%E5%8C%BA%E5%90%8D%22%2C%22SmGeometrySize%22%2C%22%E5%B9%B4%E4%BB%A3%22%2C%22%E5%8D%95%E4%BB%B7%22%2C%22%E6%A5%BC%E5%B1%82%22%2C%22SmID%22%2C%22%E6%80%BB%E4%BB%B7%22%2C%22SmUserID%22%2C%22%E6%88%B7%E5%9E%8B%22%2C%22%E6%9C%9D%E5%90%91%22%2C%22%E5%9C%B0%E5%9D%80%22%2C%22SmY%22%2C%22SmX%22%2C%22SmLibTileID%22%2C%22%E9%9D%A2%E7%A7%AF%22%5D&geometryFieldName=geometry' + ], + bounds: [115.89763001613301, 39.40605999999998, 117.48732001635403, 40.65001000642029], + type: 'vector' + }, + ms_318218382_1731394700155_28: { + tiles: [ + 'ttp://localhost:8190/iportal/web/datas/318218382/structureddata/tiles/{z}/{x}/{y}.mvt?epsgCode=3857&returnedFieldNames=%5B%22smpid%22%2C%22SmID%22%2C%22%E6%A0%87%E5%87%86%E5%90%8D%E7%A7%B0%22%5D&geometryFieldName=geometry' + ], + bounds: [116.1021443681324, 39.67036946821773, 116.6890734187427, 40.206933499104196], + type: 'vector' + } + }, + crs: 'EPSG:3857', + center: [116.3956088934375, 39.93917738600356], + zoom: 9.986952543786419, + glyphs: {}, + version: '3.2.2', + rootUrl: 'http://localhost:8190/iportal/', + maxzoom: 12, + name: '无标题地图', + viewExtent: [115.84407357731546, 39.702628586353086, 116.94714420955526, 40.17491130005204], + layers: [ + { + paint: { + 'background-color': '#242424' + }, + id: 'ms-background', + type: 'background' + }, + { + metadata: {}, + maxzoom: 24, + paint: { + 'circle-color': '#EE4D5A', + 'circle-opacity': 0.9, + 'circle-translate-anchor': 'map', + 'circle-radius': 4, + 'circle-translate': [0, 0] + }, + id: '北京住宅小区分布.geojson', + source: 'ms_1731639917_1731394669710_25', + 'source-layer': '1731639917$geometry', + type: 'circle', + minzoom: 0 + }, + { + metadata: {}, + maxzoom: 24, + paint: { + 'line-width': 2, + 'line-color': '#4CC8A3' + }, + id: '北京轨道交通分布.geojson', + source: 'ms_318218382_1731394700155_28', + 'source-layer': '318218382$geometry', + type: 'line', + minzoom: 0 + } + ], + sprite: 'ttp://localhost:8190/iportal/web/maps/1090355953/sprites/sprite', + pitch: 0, + minzoom: 0 +}); + +var msProjectINfo_separate_layerCatalogId = JSON.stringify({ + extent: { + top: 40.17491130005204, + left: 115.84407357731546, + bottom: 39.702628586353086, + leftBottom: { + x: 115.84407357731546, + y: 39.702628586353086 + }, + right: 116.94714420955526, + rightTop: { + x: 116.94714420955526, + y: 40.17491130005204 + } + }, + controls: null, + extentString: + '{"top":40.17491130005204,"left":115.84407357731546,"bottom":39.702628586353086,"leftBottom":{"x":115.84407357731546,"y":39.702628586353086},"right":116.94714420955526,"rightTop":{"x":116.94714420955526,"y":40.17491130005204}}', + description: '', + verifyReason: null, + units: null, + title: '无标题地图', + resolution: 0, + checkStatus: 'SUCCESSFUL', + projectInfo: + '{"images":"ttp://localhost:8190/iportal/web/maps/1090355953/sprites/sprite","catalogs":[{"visualization":{"renderer":[{"lineDasharray":{"type":"simple","value":[1,0]},"color":{"type":"simple","value":"#4CC8A3"},"lineTranslateAnchor":{"type":"simple","value":"map"},"lineMiterLimit":{"type":"simple","value":2},"lineOffset":{"type":"simple","value":0},"lineJoin":{"type":"simple","value":"miter"},"lineRoundLimit":{"type":"simple","value":1.05},"lineTranslate":{"type":"simple","value":[0,0]},"styleRenderMode":"mapboxgl","symbolsContent":{"type":"simple","value":{"symbolId":"line-0","style":{"layout":{"visibility":"visible"},"paint":{"line-width":2,"line-color":"#4CC8A3"}}}},"lineGapWidth":{"type":"simple","value":0},"lineCap":{"type":"simple","value":"butt"},"width":{"type":"simple","value":2},"opacity":{"type":"simple","value":1}}]},"visible":true,"catalogType":"layer","msDatasetId":"ms_datasetId_1731394700150_26","bounds":[116.1021443681324,39.67036946821773,116.6890734187427,40.206933499104196],"id":"layer_北京轨道交通分布.geojson","popupInfo":{"elements":[{"fieldName":"smpid","type":"FIELD"},{"fieldName":"SmID","type":"FIELD"},{"fieldName":"标准名称","type":"FIELD"},{"fieldName":"geometry","type":"FIELD"}],"title":"北京轨道交通分布.geojson"},"title":"北京轨道交通分布.geojson","layerSourceType":"Data","zoomRange":[0,24],"layersContent":["北京轨道交通分布.geojson"]},{"visualization":{"renderer":[{"symbolsContent":{"type":"simple","value":{"symbolId":"circle","style":{"layout":{"icon-image":"circle"}}}},"size":{"type":"simple","value":8},"color":{"type":"simple","value":"#EE4D5A"},"translateAnchor":{"type":"simple","value":"map"},"opacity":{"type":"simple","value":0.9},"translate":{"type":"simple","value":[0,0]},"styleRenderMode":"mapboxgl"}]},"visible":true,"catalogType":"layer","msDatasetId":"ms_datasetId_1731394669706_23","bounds":[115.89763001613301,39.40605999999998,117.48732001635403,40.65001000642029],"id":"layer_北京住宅小区分布.geojson","popupInfo":{"elements":[{"fieldName":"smpid","type":"FIELD"},{"fieldName":"小区名","type":"FIELD"},{"fieldName":"SmGeometrySize","type":"FIELD"},{"fieldName":"年代","type":"FIELD"},{"fieldName":"单价","type":"FIELD"},{"fieldName":"楼层","type":"FIELD"},{"fieldName":"SmID","type":"FIELD"},{"fieldName":"总价","type":"FIELD"},{"fieldName":"SmUserID","type":"FIELD"},{"fieldName":"户型","type":"FIELD"},{"fieldName":"朝向","type":"FIELD"},{"fieldName":"地址","type":"FIELD"},{"fieldName":"SmY","type":"FIELD"},{"fieldName":"SmX","type":"FIELD"},{"fieldName":"SmLibTileID","type":"FIELD"},{"fieldName":"面积","type":"FIELD"},{"fieldName":"geometry","type":"FIELD"}],"title":"北京住宅小区分布.geojson"},"title":"北京住宅小区分布.geojson","layerSourceType":"Data","zoomRange":[0,24],"layersContent":["北京住宅小区分布.geojson"]}],"datas":[{"sourceType":"STRUCTURE_DATA","datasets":[{"datasetTitle":"长江三角洲省级区划面.geojson","msDatasetId":"ms_datasetId_1731394462325_18","datasetId":"985604117"}],"title":"长江三角洲省级区划面.geojson"},{"sourceType":"STRUCTURE_DATA","datasets":[{"datasetTitle":"长江三角洲省级区划面.geojson","msDatasetId":"ms_datasetId_1731394495175_19","datasetId":"985604117","geometryField":"geometry"}],"title":"长江三角洲省级区划面.geojson"},{"sourceType":"STRUCTURE_DATA","datasets":[{"datasetTitle":"北京住宅小区分布.geojson","msDatasetId":"ms_datasetId_1731394669706_23","datasetId":"1731639917","geometryField":"geometry"}],"title":"北京住宅小区分布.geojson"},{"sourceType":"STRUCTURE_DATA","datasets":[{"datasetTitle":"北京轨道交通分布.geojson","msDatasetId":"ms_datasetId_1731394700150_26","datasetId":"318218382","geometryField":"geometry"}],"title":"北京轨道交通分布.geojson"}],"baseLayer":{"color":"#242424","projection":"EPSG:3857","type":"BACKGROUND"},"version":"3.0.5"}', + visitCount: 26, + centerString: '{"x":116.3956088934375,"y":39.93917738600356}', + epsgCode: 3857, + nickname: 'admin_123', + layers: null, + id: 1090355953, + searchSetting: null, + thumbnail: 'ttp://localhost:8190/iportal/resources/thumbnail/map/map1090355953.png', + level: 9, + center: { + x: 116.3956088934375, + y: 39.93917738600356 + }, + authorizeSetting: [ + { + permissionType: 'DELETE', + aliasName: 'admin_123', + entityRoles: ['ADMIN', 'SYSTEM'], + entityType: 'USER', + entityName: 'admin_123', + entityId: null + }, + { + permissionType: 'READWRITE', + aliasName: 'GUEST', + entityRoles: [], + entityType: 'USER', + entityName: 'GUEST', + entityId: null + } + ], + updateTime: 1731416707750, + userName: 'admin_123', + tags: [], + checkUser: null, + checkUserNick: null, + checkTime: null, + sourceType: 'MAPSTUDIO', + createTime: 1731394506912, + controlsString: '', + isDefaultBottomMap: false, + status: null, + favoriteCount: 0 +}); \ No newline at end of file