Skip to content

Commit a5f1509

Browse files
[fix]webmap新增获取原地图的图例信息
AI-GEN: 70% MiniMax-M2.7
1 parent c17f31f commit a5f1509

8 files changed

Lines changed: 593 additions & 3 deletions

File tree

src/common/mapping/MapBase.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ export function createMapClassExtending(SuperClass = class {}) {
8888
}
8989
}
9090
Array.from(new Set(sourceList)).forEach((sourceId) => {
91-
this.map.removeSource(sourceId);
91+
if (this.map.getSource(sourceId)) {
92+
this.map.removeSource(sourceId);
93+
}
9294
});
9395
}
9496
};

src/common/mapping/WebMapBase.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ export function createWebMapBaseExtending(SuperClass, { mapRepo }) {
382382
return (this._handler && this._handler._getPopupInfos()) || [];
383383
}
384384

385+
/**
386+
* @version 11.3.0
387+
* @function WebMapBase.prototype.getLegendInfos
388+
* @description 获取地图本身所有图层的legend状态。
389+
* @returns {Array} 图例信息数组,包含 showLegend、id、title 三个属性。
390+
*/
391+
getLegendInfos() {
392+
return (this._handler && this._handler._getLegendInfos()) || [];
393+
}
394+
385395
/**
386396
* @version 11.2.1
387397
* @function WebMapBase.prototype.getLayers

src/common/mapping/WebMapV2.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,18 @@ export function createWebMapV2Extending(SuperClass, { MapManager, mapRepo, DataF
236236
}).filter(item => item !== null);
237237
}
238238

239+
_getLegendInfos() {
240+
const { layers = [] } = this._mapInfo;
241+
return layers.map((layer) => {
242+
const { legendSetting, name, layerID: layerId } = layer;
243+
return {
244+
showLegend: legendSetting ? legendSetting?.isShow !== false : false,
245+
id: layerId,
246+
title: name
247+
};
248+
});
249+
}
250+
239251
_handleLayerInfo(mapInfo, _taskID) {
240252
mapInfo = this._setLayerID(mapInfo);
241253
this._mapInfo = mapInfo;

src/common/mapping/WebMapV3.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,32 @@ _getFieldCaption(msDatasetId) {
401401
})
402402
return res;
403403
}
404+
405+
_getLegendInfoByCatalog(catalog, res = []) {
406+
const { catalogType, children, showLegend, title, id } = catalog;
407+
if (catalogType === 'group' && children) {
408+
children.forEach(child => {
409+
this._getLegendInfoByCatalog(child, res);
410+
});
411+
}
412+
if (catalogType === 'layer') {
413+
res.push({
414+
showLegend: showLegend !== false,
415+
id: id,
416+
title: title
417+
});
418+
}
419+
}
420+
421+
_getLegendInfos(_mapResourceInfo = this._mapResourceInfo) {
422+
const { catalogs = [] } = _mapResourceInfo;
423+
const res = [];
424+
catalogs.forEach((item) => {
425+
this._getLegendInfoByCatalog(item, res);
426+
});
427+
return res;
428+
}
429+
404430
/**
405431
* @private
406432
* @function WebMapV3.prototype._initLayers

test/common/mapping/MapBaseSpec.js

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,113 @@ describe('MapBase', () => {
8888

8989
it('should return empty array when _sourceListModel is null', () => {
9090
instance._sourceListModel = null;
91-
91+
9292
expect(instance.getLayers()).toEqual([]);
9393
});
9494
});
95+
96+
describe('cleanLayers', () => {
97+
beforeEach(() => {
98+
instance.map = jasmine.createSpyObj('map', [
99+
'getLayer',
100+
'removeLayer',
101+
'getSource',
102+
'removeSource'
103+
]);
104+
});
105+
106+
it('should remove layers from map', () => {
107+
const layers = [
108+
{
109+
renderLayers: ['layer1', 'layer2'],
110+
renderSource: { id: 'source1' },
111+
l7Layer: false
112+
}
113+
];
114+
instance.map.getLayer.and.callFake((layerId) => {
115+
if (layerId === 'layer1' || layerId === 'layer2') {
116+
return { source: 'source1' };
117+
}
118+
return undefined;
119+
});
120+
instance.map.getSource.and.returnValue(true);
121+
122+
instance.cleanLayers(layers);
123+
124+
expect(instance.map.removeLayer).toHaveBeenCalledWith('layer1');
125+
expect(instance.map.removeLayer).toHaveBeenCalledWith('layer2');
126+
});
127+
128+
it('should remove sources from map when layers are removed', () => {
129+
const layers = [
130+
{
131+
renderLayers: ['layer1'],
132+
renderSource: { id: 'source1' },
133+
l7Layer: false
134+
}
135+
];
136+
instance.map.getLayer.and.returnValue({ source: 'source1' });
137+
instance.map.getSource.and.returnValue(true);
138+
139+
instance.cleanLayers(layers);
140+
141+
expect(instance.map.removeSource).toHaveBeenCalledWith('source1');
142+
});
143+
144+
it('should not remove source when renderSource.id is falsy', () => {
145+
const layers = [
146+
{
147+
renderLayers: ['layer1'],
148+
renderSource: { id: null },
149+
l7Layer: false
150+
}
151+
];
152+
instance.map.getLayer.and.returnValue({ source: null });
153+
// getSource(null) returns falsy, so source won't be added to list
154+
instance.map.getSource.and.returnValue(false);
155+
156+
instance.cleanLayers(layers);
157+
158+
expect(instance.map.removeSource).not.toHaveBeenCalled();
159+
});
160+
161+
it('should not remove source when layer is l7Layer', () => {
162+
const layers = [
163+
{
164+
renderLayers: ['layer1'],
165+
renderSource: { id: 'source1' },
166+
l7Layer: true
167+
}
168+
];
169+
instance.map.getLayer.and.returnValue({ source: 'source1' });
170+
instance.map.getSource.and.returnValue(true);
171+
172+
instance.cleanLayers(layers);
173+
174+
expect(instance.map.removeSource).not.toHaveBeenCalled();
175+
});
176+
177+
it('should deduplicate sources before removal', () => {
178+
const layers = [
179+
{
180+
renderLayers: ['layer1'],
181+
renderSource: { id: 'source1' },
182+
l7Layer: false
183+
},
184+
{
185+
renderLayers: ['layer2'],
186+
renderSource: { id: 'source1' },
187+
l7Layer: false
188+
}
189+
];
190+
instance.map.getLayer.and.returnValue({ source: 'source1' });
191+
instance.map.getSource.and.returnValue(true);
192+
193+
instance.cleanLayers(layers);
194+
195+
// Should only call removeSource once due to deduplication
196+
expect(instance.map.removeSource).toHaveBeenCalledTimes(1);
197+
expect(instance.map.removeSource).toHaveBeenCalledWith('source1');
198+
});
199+
});
95200
});

test/common/mapping/WebMapBaseSpec.js

Lines changed: 149 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,156 @@ describe('WebMapBase - MapBase Methods', () => {
7474

7575
it('should return empty array when _sourceListModel is null', () => {
7676
instance._sourceListModel = null;
77-
77+
7878
expect(instance.getLayers()).toEqual([]);
7979
});
8080
});
8181
});
82+
83+
describe('WebMapBase - Handler Methods', () => {
84+
let instance;
85+
let mockHandler;
86+
87+
beforeEach(() => {
88+
const MapBase = createMapClassExtending();
89+
instance = new MapBase();
90+
instance.getLegendInfos = function() {
91+
return (this._handler && this._handler._getLegendInfos()) || [];
92+
};
93+
// Mock WebMapV2 handler
94+
mockHandler = {
95+
_getLegendInfos: jasmine.createSpy('_getLegendInfos').and.callFake(() => {
96+
return [
97+
{ showLegend: true, id: 'layer1', title: 'Layer 1' },
98+
{ showLegend: false, id: 'layer2', title: 'Layer 2' }
99+
];
100+
})
101+
};
102+
instance._handler = mockHandler;
103+
});
104+
105+
describe('getLegendInfos', () => {
106+
it('should call handler._getLegendInfos and return result', () => {
107+
const result = instance.getLegendInfos();
108+
109+
expect(mockHandler._getLegendInfos).toHaveBeenCalled();
110+
expect(result).toEqual([
111+
{ showLegend: true, id: 'layer1', title: 'Layer 1' },
112+
{ showLegend: false, id: 'layer2', title: 'Layer 2' }
113+
]);
114+
});
115+
116+
it('should return empty array when handler._getLegendInfos returns null', () => {
117+
mockHandler._getLegendInfos.and.returnValue(null);
118+
119+
const result = instance.getLegendInfos();
120+
121+
expect(result).toEqual([]);
122+
});
123+
124+
it('should return empty array when handler._getLegendInfos returns undefined', () => {
125+
mockHandler._getLegendInfos.and.returnValue(undefined);
126+
127+
const result = instance.getLegendInfos();
128+
129+
expect(result).toEqual([]);
130+
});
131+
132+
it('should return empty array when handler is null', () => {
133+
instance._handler = null;
134+
135+
const result = instance.getLegendInfos();
136+
137+
expect(result).toEqual([]);
138+
});
139+
});
140+
141+
describe('getLegendInfos with WebMapV2-like handler', () => {
142+
it('should return legend info from _mapInfo.layers (WebMapV2)', () => {
143+
const webMapV2Handler = {
144+
_getLegendInfos: jasmine.createSpy('_getLegendInfos').and.callFake(function() {
145+
const { layers = [] } = this._mapInfo || {};
146+
return layers.map((layer) => {
147+
const { legendSetting, name, layerID: layerId } = layer;
148+
return {
149+
showLegend: legendSetting?.isShow !== false,
150+
id: layerId,
151+
title: name
152+
};
153+
});
154+
}),
155+
_mapInfo: {
156+
layers: [
157+
{ name: 'Layer1', layerID: 'layer1', legendSetting: { isShow: true } },
158+
{ name: 'Layer2', layerID: 'layer2', legendSetting: { isShow: false } }
159+
]
160+
}
161+
};
162+
instance._handler = webMapV2Handler;
163+
164+
const result = instance.getLegendInfos();
165+
166+
expect(webMapV2Handler._getLegendInfos).toHaveBeenCalled();
167+
expect(result).toEqual([
168+
{ showLegend: true, id: 'layer1', title: 'Layer1' },
169+
{ showLegend: false, id: 'layer2', title: 'Layer2' }
170+
]);
171+
});
172+
});
173+
174+
describe('getLegendInfos with WebMapV3-like handler', () => {
175+
it('should return legend info from catalogs (WebMapV3)', () => {
176+
const webMapV3Handler = {
177+
_getLegendInfos: jasmine.createSpy('_getLegendInfos').and.callFake(function() {
178+
const { catalogs = [] } = this._mapResourceInfo || {};
179+
const res = [];
180+
const processCatalog = (catalog) => {
181+
const { catalogType, children, showLegend, title, layersContent, id } = catalog;
182+
if (catalogType === 'group' && children) {
183+
children.forEach(child => processCatalog(child));
184+
}
185+
if (catalogType === 'layer') {
186+
res.push({
187+
showLegend: showLegend !== false,
188+
id: layersContent || id,
189+
title: title
190+
});
191+
}
192+
};
193+
catalogs.forEach(item => processCatalog(item));
194+
return res;
195+
}),
196+
_mapResourceInfo: {
197+
catalogs: [
198+
{
199+
catalogType: 'layer',
200+
title: 'Layer1',
201+
showLegend: true,
202+
layersContent: 'layer1'
203+
},
204+
{
205+
catalogType: 'group',
206+
children: [
207+
{
208+
catalogType: 'layer',
209+
title: 'Layer2',
210+
showLegend: false,
211+
layersContent: 'layer2'
212+
}
213+
]
214+
}
215+
]
216+
}
217+
};
218+
instance._handler = webMapV3Handler;
219+
220+
const result = instance.getLegendInfos();
221+
222+
expect(webMapV3Handler._getLegendInfos).toHaveBeenCalled();
223+
expect(result).toEqual([
224+
{ showLegend: true, id: 'layer1', title: 'Layer1' },
225+
{ showLegend: false, id: 'layer2', title: 'Layer2' }
226+
]);
227+
});
228+
});
229+
});

0 commit comments

Comments
 (0)