Skip to content

Commit e5a2a79

Browse files
committed
【feature】mapstyle webmapv3 新增 checkSameLayer 逻辑
1 parent ad83fcf commit e5a2a79

File tree

15 files changed

+538
-44
lines changed

15 files changed

+538
-44
lines changed

src/common/mapping/MapStyle.js

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { WebMapService } from './WebMapService';
22
import { SourceListModelV2 } from './utils/SourceListModelV2';
3+
import { createAppreciableLayerId, isSameRasterLayer } from './utils/util';
34

45
export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
56
return class MapStyle extends SuperClass {
@@ -70,6 +71,10 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
7071
_addLayersToMap() {
7172
const { sources, layers, layerIdMapList } = this._setUniqueId(this.mapOptions.style);
7273
layers.forEach((layer) => {
74+
const matchRenameLayer = layerIdMapList.find(sub => sub.renderId === layer.id);
75+
if (matchRenameLayer && matchRenameLayer.reused) {
76+
return;
77+
}
7378
layer.source && !this.map.getSource(layer.source) && this.map.addSource(layer.source, sources[layer.source]);
7479
this.map.addLayer(layer);
7580
});
@@ -81,13 +86,15 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
8186
_setUniqueId(style) {
8287
const layersToMap = JSON.parse(JSON.stringify(style.layers));
8388
const nextSources = {};
89+
const sourcesIdChangedMap = {};
8490
const layerIdToChange = [];
8591
const timestamp = `_${+new Date()}`;
8692
for (const sourceId in style.sources) {
8793
let nextSourceId = sourceId;
8894
if (this.map.getSource(sourceId)) {
8995
nextSourceId = sourceId + timestamp;
9096
}
97+
sourcesIdChangedMap[nextSourceId] = sourceId;
9198
nextSources[nextSourceId] = style.sources[sourceId];
9299
for (const layer of layersToMap) {
93100
if (layer.source === sourceId) {
@@ -97,11 +104,22 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
97104
}
98105
for (const layer of layersToMap) {
99106
const originId = layer.id;
100-
if (this.map.getLayer(layer.id)) {
101-
const layerId = layer.id + timestamp;
102-
layer.id = layerId;
107+
let reused;
108+
const existLayer = this.map.getLayer(layer.id);
109+
if (existLayer) {
110+
// 此时用 getSource(xx).tiles 为空
111+
if (
112+
this.options.checkSameLayer &&
113+
isSameRasterLayer(nextSources[layer.source], this.map.getStyle().sources[existLayer.source])
114+
) {
115+
reused = true;
116+
layer.source = sourcesIdChangedMap[layer.source];
117+
} else {
118+
const layerId = layer.id + timestamp;
119+
layer.id = layerId;
120+
}
103121
}
104-
layerIdToChange.push({ originId: originId, renderId: layer.id });
122+
layerIdToChange.push({ originId: originId, renderId: layer.id, reused });
105123
}
106124
return {
107125
sources: nextSources,
@@ -112,7 +130,8 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
112130

113131
_generateAppreciableLayers() {
114132
return this.mapOptions.style.layers.reduce((layers, layer) => {
115-
const id = layer['source-layer'] || layer.source || layer.id;
133+
const nameLayer = layer['source-layer'] ? layer : { ...layer, layerInfo: { id: layer.id } };
134+
const id = createAppreciableLayerId(nameLayer);
116135
const matchLayer = layers.find(item => item.id === id);
117136
if (matchLayer) {
118137
matchLayer.renderLayers.push(layer.id);
@@ -122,7 +141,8 @@ export function createMapStyleExtending(SuperClass, { MapManager, mapRepo }) {
122141
...layer,
123142
id,
124143
name: matchRenameLayer && matchRenameLayer.originId,
125-
renderLayers: [layer.id]
144+
renderLayers: [layer.id],
145+
reused: matchRenameLayer && matchRenameLayer.reused
126146
});
127147
}
128148
return layers;

src/common/mapping/WebMapBase.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@
266266
}
267267

268268
/**
269-
* @function WebMapBase.prototype.setRasterTileSize
269+
* @function WebMapBase.prototype.setStyle
270270
* @description 更新地图样式。
271271
* @param {Object} style - 地图 style 样式
272272
*/

src/common/mapping/WebMapV2.js

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Util } from '../commontypes/Util';
88
import { ArrayStatistic } from '../util/ArrayStatistic';
99
import { FetchRequest } from '../util/FetchRequest';
1010
import { SourceListModelV2 } from './utils/SourceListModelV2';
11-
import { mergeFeatures } from './utils/util';
11+
import { isSameRasterLayer, mergeFeatures } from './utils/util';
1212

1313
export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) {
1414
return class WebMapV2 extends SuperClass {
@@ -2766,7 +2766,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) {
27662766
id: targetLayerId,
27672767
visible: targetLayerVisible,
27682768
renderLayers,
2769-
reused: matchLayers.some(item => item.reused) || void 0
2769+
reused: matchLayers.some(item => item.reused)
27702770
});
27712771
}
27722772
});
@@ -2819,16 +2819,7 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo }) {
28192819
}
28202820

28212821
_isSameRasterLayer(id, layerInfo) {
2822-
const {
2823-
source: { type, tiles }
2824-
} = layerInfo;
2825-
if (type === 'raster') {
2826-
const source = this.map.getSource(id);
2827-
if (type === source.type && tiles && source.tiles && tiles[0] === source.tiles[0]) {
2828-
return true;
2829-
}
2830-
}
2831-
return false;
2822+
return isSameRasterLayer(layerInfo.source, this.map.getSource(id));
28322823
}
28332824

28342825
_centerValid(center) {

src/common/mapping/WebMapV3.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* This program are made available under the terms of the Apache License, Version 2.0
33
* which accompanies this distribution and is available at http://www.apache.org/licenses/LICENSE-2.0.html.*/
44
import { FetchRequest } from '../util/FetchRequest';
5-
import { getLayerInfosFromCatalogs, mergeFeatures, transformUrl } from './utils/util';
5+
import { getLayerInfosFromCatalogs, isSameRasterLayer, mergeFeatures, transformUrl } from './utils/util';
66
import { SourceListModelV3 } from './utils/SourceListModelV3';
77

88
const LEGEND_RENDER_TYPE = {
@@ -421,6 +421,9 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, mapRe
421421
Object.assign(this._mapResourceInfo, { catalogs });
422422
const mapboxglLayers = layers.filter((layer) => !l7LayerUtil.isL7Layer(layer));
423423
mapboxglLayers.forEach((layer) => {
424+
if (layer.metadata && layer.metadata.reused) {
425+
return;
426+
}
424427
layer.source && !this.map.getSource(layer.source) && this.map.addSource(layer.source, sources[layer.source]);
425428
// L7才会用到此属性
426429
if (layer.type === 'symbol' && layer.layout['text-z-offset'] === 0) {
@@ -461,13 +464,15 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, mapRe
461464
return !unspportedLayers.includes(layer.id);
462465
});
463466
const nextSources = {};
467+
const sourcesIdChangedMap = {};
464468
const layerIdToChange = [];
465469
const timestamp = `_${+new Date()}`;
466470
for (const sourceId in style.sources) {
467471
let nextSourceId = sourceId;
468472
if (this.map.getSource(sourceId)) {
469473
nextSourceId = sourceId + timestamp;
470474
}
475+
sourcesIdChangedMap[nextSourceId] = sourceId;
471476
nextSources[nextSourceId] = style.sources[sourceId];
472477
for (const layer of layersToMap) {
473478
if (layer.source === sourceId) {
@@ -477,9 +482,19 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, mapRe
477482
}
478483
for (const layer of layersToMap) {
479484
const originId = layer.id;
480-
if (this._getLayerOnMap(layer.id)) {
481-
const layerId = layer.id + timestamp;
482-
layer.id = layerId;
485+
const existLayer = this._getLayerOnMap(layer.id);
486+
if (existLayer) {
487+
if (
488+
this.options.checkSameLayer &&
489+
isSameRasterLayer(nextSources[layer.source], this.map.getSource(existLayer.source))
490+
) {
491+
layer.metadata = layer.metadata || {};
492+
layer.metadata.reused = true;
493+
layer.source = sourcesIdChangedMap[layer.source];
494+
} else {
495+
const layerId = layer.id + timestamp;
496+
layer.id = layerId;
497+
}
483498
}
484499
layerIdToChange.push({ originId: originId, renderId: layer.id });
485500
}
@@ -573,6 +588,7 @@ export function createWebMapV3Extending(SuperClass, { MapManager, mapRepo, mapRe
573588
if (matchLayer) {
574589
const catalog = this._findLayerCatalog(catalogs, id);
575590
catalog.id = matchLayer.renderId;
591+
catalog.reused = matchLayer.reused;
576592
if (catalog[layerIdsField]) {
577593
catalog[layerIdsField] = this._renameLayerIdsContent(catalog[layerIdsField], layerIdMapList);
578594
}

src/common/mapping/utils/AppreciableLayerBase.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import SourceModel from './SourceModel';
2+
import { createAppreciableLayerId } from './util';
23

34
export class AppreciableLayerBase {
45
constructor(options = {}) {
@@ -29,24 +30,10 @@ export class AppreciableLayerBase {
2930
return this.filterExpectedLayers(selfLayers.concat(extraLayers));
3031
}
3132

32-
_createAppreciableLayerId(layer) {
33-
// 针对传入 layers
34-
if (layer.layerInfo && layer.layerInfo.id) {
35-
return layer.layerInfo.id;
36-
}
37-
// 往空地图上追加图层 且 只有一个webmap this.layers是空
38-
if (layer.metadata && layer.metadata.parentLayerId) {
39-
return layer.metadata.parentLayerId;
40-
}
41-
// 针对 MapboxStyle 或者其它额外的 layer
42-
// type: background 和某些 overlaymanager layers 只有 id
43-
return layer.sourceLayer || layer.source || layer.id;
44-
}
45-
4633
_initAppreciableLayers(detailLayers) {
4734
// dv 没有关联一个可感知图层对应对个渲染图层的关系,默认相同source的layer就是渲染图层
4835
return detailLayers.reduce((layers, layer) => {
49-
const layerId = this._createAppreciableLayerId(layer);
36+
const layerId = createAppreciableLayerId(layer);
5037
let matchLayer = layers.find((item) => {
5138
return item.id === layerId;
5239
});
@@ -180,7 +167,7 @@ export class AppreciableLayerBase {
180167
if (CLASS_INSTANCE) {
181168
fields.CLASS_INSTANCE = CLASS_INSTANCE;
182169
}
183-
if (reused !== void 0) {
170+
if (reused) {
184171
fields.reused = reused;
185172
}
186173
return fields;

src/common/mapping/utils/SourceListModelV3.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class SourceListModelV3 extends AppreciableLayerBase {
6464
visible
6565
};
6666
} else {
67-
formatItem = appreciableLayers.find((layer) => layer.id === id);
67+
formatItem = Object.assign({}, appreciableLayers.find((layer) => layer.id === id));
6868
}
6969
return formatItem;
7070
});
@@ -78,7 +78,7 @@ export class SourceListModelV3 extends AppreciableLayerBase {
7878
const l7MarkerLayers = this._l7LayerUtil.getL7MarkerLayers();
7979
const layerDatas = metadataCatalogs.map(layerCatalog => {
8080
const layer = this._mapInfo.layers.find(item => item.id === layerCatalog.id) || {};
81-
const layerInfo = { id: layer.id, title: layerCatalog.title, renderLayers: this._getRenderLayers(layerCatalog.parts, layerCatalog.id) };
81+
const layerInfo = { id: layer.id, title: layerCatalog.title, renderLayers: this._getRenderLayers(layerCatalog.parts, layerCatalog.id), reused: layer.metadata && layer.metadata.reused };
8282
const matchProjectCatalog = projectCataglogs.find((item) => item.id === layerCatalog.id) || {};
8383
const { msDatasetId } = matchProjectCatalog;
8484
let dataSource = {};

src/common/mapping/utils/util.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,26 @@ export function getLayerInfosFromCatalogs(catalogs, catalogTypeField = 'type') {
163163
}
164164
}
165165
return results;
166+
}
167+
168+
export function isSameRasterLayer(sourceInfo, compareSource) {
169+
const { type, tiles } = sourceInfo;
170+
if (type === 'raster') {
171+
return type === compareSource.type && tiles && compareSource.tiles && (tiles[0].includes(compareSource.tiles[0]) || compareSource.tiles[0].includes(tiles[0]))
172+
}
173+
return false;
174+
}
175+
176+
export function createAppreciableLayerId(layer) {
177+
// 针对传入 layers
178+
if (layer.layerInfo && layer.layerInfo.id) {
179+
return layer.layerInfo.id;
180+
}
181+
// 往空地图上追加图层 且 只有一个webmap this.layers是空
182+
if (layer.metadata && layer.metadata.parentLayerId) {
183+
return layer.metadata.parentLayerId;
184+
}
185+
// 针对 MapboxStyle 或者其它额外的 layer
186+
// type: background 和某些 overlaymanager layers 只有 id
187+
return layer.sourceLayer || layer.source || layer.id;
166188
}

test/mapboxgl/mapping/WebMapSpec.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,4 +1183,50 @@ describe('mapboxgl_WebMap', () => {
11831183
done();
11841184
});
11851185
});
1186+
1187+
it('test mapstyle checkSameLayer', (done) => {
1188+
const commonOption = {
1189+
server: 'http://fack:8190/iportal/',
1190+
target: 'map',
1191+
withCredentials: false
1192+
};
1193+
datavizWebmap = new WebMap(
1194+
'',
1195+
{ ...commonOption },
1196+
{ style: { version: 8, sources: {}, layers: [] }, center: [0, 0], zoom: 1, crs: 'EPSG:3857' }
1197+
);
1198+
const callback = function (data) {
1199+
const appreciableLayers = datavizWebmap.getLayers();
1200+
expect(appreciableLayers.length).toBe(0);
1201+
const webMap1 = new WebMap('', { ...commonOption, map: data.map, checkSameLayer: true }, mapOptionsList[0]);
1202+
webMap1.once('mapcreatesucceeded', ({ layers }) => {
1203+
expect(layers.length).toBe(2);
1204+
expect(layers[0].reused).toBeUndefined();
1205+
expect(layers[0].id).toBe('China4269@DataSource');
1206+
expect(layers[1].reused).toBeUndefined();
1207+
expect(layers[1].id).toBe('424149619$geometry');
1208+
const webMap2 = new WebMap('', { ...commonOption, map: data.map, checkSameLayer: true }, mapOptionsList[1]);
1209+
webMap2.once('mapcreatesucceeded', ({ layers, map }) => {
1210+
expect(layers.length).toBe(2);
1211+
expect(layers[0].reused).toBeTruthy();
1212+
expect(layers[0].id).toBe('China4269@DataSource');
1213+
expect(layers[1].reused).toBeUndefined();
1214+
expect(layers[1].id).toContain('424149619$geometry');
1215+
let layersOnMap = map.getStyle().layers;
1216+
expect(layersOnMap.length).toBe(3);
1217+
expect(layersOnMap[0].id).toBe('China4269@DataSource');
1218+
expect(layersOnMap[1].id).toBe('未命名数据');
1219+
expect(layersOnMap[2].id).toContain('未命名数据_');
1220+
webMap2.cleanLayers();
1221+
layersOnMap = map.getStyle().layers;
1222+
expect(layersOnMap.length).toBe(2);
1223+
expect(layersOnMap[0].id).toBe('China4269@DataSource');
1224+
expect(layersOnMap[1].id).toBe('未命名数据');
1225+
webMap1.cleanLayers();
1226+
done();
1227+
});
1228+
});
1229+
};
1230+
datavizWebmap.once('mapcreatesucceeded', callback);
1231+
});
11861232
});

test/mapboxgl/mapping/WebMapV2Spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,7 @@ describe('mapboxgl_WebMapV2', () => {
26832683
});
26842684
});
26852685

2686-
it('test checkSameLayer', (done) => {
2686+
it('test webmapv2 checkSameLayer', (done) => {
26872687
spyOn(FetchRequest, 'get').and.callFake((url) => {
26882688
if (url.indexOf('portal.json') > -1) {
26892689
return Promise.resolve(new Response(JSON.stringify(iportal_serviceProxy)));

0 commit comments

Comments
 (0)