Skip to content

Commit 9a5f616

Browse files
【update】提取优化 l7layer 公共代码
1 parent 6ed7afd commit 9a5f616

File tree

5 files changed

+395
-388
lines changed

5 files changed

+395
-388
lines changed
File renamed without changes.

src/common/overlay/l7/L7LayerBase.js

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
import { Util as CommonUtil } from '../../commontypes/Util';
2+
import { CustomOverlayLayer } from '../Base';
3+
4+
/**
5+
* @class L7Layer
6+
* @category Visualization L7
7+
* @version 11.2.0
8+
* @classdesc L7Layer对接了@antv/L7的图层类型,能够通过mapbox-gl操作@antv/L7的图层。
9+
* @param {Object} options - 图层配置项,包括以下参数:
10+
* @param {string} options.type - @antv/L7的图层类型,详情参见: {@link https://l7.antv.antgroup.com/api/point_layer/pointlayer}。
11+
* @param {Object} options.options - @antv/L7图层的配置项,详情参见: {@link https://l7.antv.antgroup.com/api/point_layer/options}。
12+
* @param {string} [options.layerID] - 图层 ID。默认使用 CommonUtil.createUniqueID("l7_layer_") 创建图层 ID。
13+
* @param {string} [options.source] - source ID。
14+
* @usage
15+
*/
16+
17+
export class L7LayerBase extends CustomOverlayLayer {
18+
constructor({ type, options = {} }) {
19+
const id = options.layerID ? options.layerID : CommonUtil.createUniqueID('l7_layer_');
20+
const events = [
21+
'inited',
22+
'add',
23+
'remove',
24+
'legend:color',
25+
'legend:size',
26+
'click',
27+
'dblclick',
28+
'mousemove',
29+
'mouseover',
30+
'mouseout',
31+
'mouseup',
32+
'mousedown',
33+
'mouseenter',
34+
'mouseleave',
35+
'contextmenu',
36+
'dblclick',
37+
'unclick',
38+
'unmousemove',
39+
'unmouseup',
40+
'unmousedown',
41+
'uncontextmenu',
42+
'unpick',
43+
'touchstart',
44+
'touchend'
45+
];
46+
super({ type, sourceId: options.source || id, query: true, interaction: true, events });
47+
this.id = id;
48+
this.eventListeners = {};
49+
this.selectedDatas = [];
50+
this.setSelectedDatasFn = this.setSelectedDatas.bind(this);
51+
this.reRenderFn = this.reRender.bind(this);
52+
}
53+
/**
54+
* @function L7Layer.prototype.getL7Layer
55+
* @description 获取@antv/L7的layer实例。
56+
* @returns {Object} @antv/L7的layer实例。
57+
*/
58+
getL7Layer() {
59+
return this.l7layer;
60+
}
61+
62+
/**
63+
* @function L7Layer.prototype.reRender
64+
* @description 当修改@antv/L7的layer的配置时,重新渲染。
65+
*/
66+
reRender() {
67+
if (this.scene && this.scene.getLayer(this.l7layer.id)) {
68+
this.scene.layerService.renderLayer(this.l7layer.id);
69+
}
70+
this.map && this.map.triggerRepaint();
71+
}
72+
73+
moveLayer(id, beforeId) {
74+
this.map.style.moveLayer(id, beforeId);
75+
}
76+
77+
setVisibility(visibility) {
78+
if (this.animateStatus) {
79+
this.cancelAnimationFrame();
80+
}
81+
visibility ? this.l7layer.show() : this.l7layer.hide();
82+
this.map.style.setLayoutProperty(this.id, 'visibility', visibility ? 'visible' : 'none');
83+
}
84+
85+
addSceneLayer(scene) {
86+
this.scene = scene;
87+
this.scene.addLayer(this.l7layer);
88+
this.updateSourceEffect();
89+
}
90+
91+
updateSourceEffect() {
92+
const source = this.l7layer.getSource();
93+
source &&
94+
source.on('update', () => {
95+
this.reRender();
96+
});
97+
}
98+
99+
getLayer() {
100+
if (!this.l7layer) {
101+
return;
102+
}
103+
const rawConfig = this.l7layer.rawConfig;
104+
const layerInfo = {
105+
...rawConfig,
106+
layout: { ...rawConfig.layout, visibility: this.l7layer.isVisible() ? 'visible' : 'none' },
107+
minzoom: this.l7layer.minZoom,
108+
maxzoom: this.l7layer.maxZoom,
109+
id: this.id,
110+
l7layer: this.l7layer,
111+
scene: this.scene,
112+
setSelectedDatas: this.setSelectedDatasFn,
113+
reRender: this.reRenderFn
114+
};
115+
delete layerInfo.sourceId;
116+
delete layerInfo.layerID;
117+
delete layerInfo.minZoom;
118+
delete layerInfo.maxZoom;
119+
return layerInfo;
120+
}
121+
122+
getFilter() {
123+
if (!this.l7layer) {
124+
return;
125+
}
126+
const { filter } = this.l7layer.rawConfig;
127+
let { field: filterFields = [], values } = this._getL7Filter(filter, this.id) || {};
128+
if (!filterFields.length && this.selectedDatas[0]) {
129+
filterFields = Object.keys(this.selectedDatas[0].properties || {});
130+
}
131+
const fields = filterFields;
132+
const transformFilterValuesFn = this._transformFilterValues.bind(this, {
133+
fields,
134+
values,
135+
selectedDatas: this.selectedDatas
136+
});
137+
return {
138+
field: fields,
139+
values: transformFilterValuesFn
140+
};
141+
}
142+
143+
setFilter(filter) {
144+
if (!this.l7layer) {
145+
return;
146+
}
147+
if (!filter) {
148+
this.l7layer.filter(true);
149+
return;
150+
}
151+
if (filter instanceof Array) {
152+
const { field: filterFields, values: filterValues } = this._getL7Filter(filter);
153+
this.l7layer.filter(filterFields, filterValues);
154+
return;
155+
}
156+
this.l7layer.filter(filter.field, filter.values);
157+
}
158+
159+
getPaintProperty(name) {
160+
if (!this.l7layer) {
161+
return;
162+
}
163+
const { paint = {} } = this.l7layer.rawConfig;
164+
return paint[name];
165+
}
166+
167+
getLayoutProperty(name) {
168+
if (!this.l7layer) {
169+
return;
170+
}
171+
const { layout = {} } = this.l7layer.rawConfig;
172+
return layout[name];
173+
}
174+
175+
// 目前只支持显示或隐藏图层操作
176+
setLayoutProperty(name, value) {
177+
if (name === 'visibility') {
178+
this.setVisibility(value === 'visible');
179+
}
180+
}
181+
182+
getSource() {
183+
if (!this.l7layer) {
184+
return;
185+
}
186+
const layerSource = this.l7layer.layerSource;
187+
const { parser } = layerSource;
188+
const sourceInfo = {
189+
id: this.sourceId,
190+
type: parser.type,
191+
map: this.map
192+
};
193+
switch (parser.type) {
194+
case 'mvt':
195+
sourceInfo.type = 'vector';
196+
break;
197+
case 'geojson':
198+
sourceInfo._data = layerSource.originData;
199+
sourceInfo.getData = () => layerSource.originData;
200+
sourceInfo.setData = this.setDataFn;
201+
break;
202+
}
203+
return sourceInfo;
204+
}
205+
206+
isSourceLoaded() {
207+
if (!this.l7layer) {
208+
return;
209+
}
210+
const layerSource = this.l7layer.layerSource;
211+
return !layerSource.tileset ? true : layerSource.tileset.isLoaded;
212+
}
213+
214+
remove() {
215+
this.scene && this.scene.removeLayer(this.l7layer);
216+
}
217+
onRemove() {
218+
this.cancelAnimationFrame();
219+
this.scene && this.scene.removeLayer(this.l7layer);
220+
}
221+
cancelAnimationFrame() {
222+
this.requestAnimationFrameId && window.cancelAnimationFrame(this.requestAnimationFrameId);
223+
this.animateStatus = false;
224+
}
225+
render() {
226+
if (this.scene && this.scene.getLayer(this.l7layer.id)) {
227+
this.scene.layerService.renderLayer(this.l7layer.id);
228+
if (this.l7layer.animateStatus || (this.l7layer.layerModel && this.l7layer.layerModel.spriteAnimate)) {
229+
const requestAnimationFrame = () => {
230+
this.requestAnimationFrameId = window.requestAnimationFrame(requestAnimationFrame);
231+
this.map.triggerRepaint();
232+
};
233+
if (!this.animateStatus) {
234+
requestAnimationFrame();
235+
this.animateStatus = true;
236+
}
237+
}
238+
} else {
239+
this.cancelAnimationFrame();
240+
}
241+
}
242+
243+
on(type, listener) {
244+
if (!this.l7layer) {
245+
return;
246+
}
247+
const _this = this;
248+
this.eventListeners[listener] = function (e) {
249+
listener(_this._formateEvent(e));
250+
};
251+
this.l7layer.on(this._formatListenType(type), this.eventListeners[listener]);
252+
}
253+
254+
once(type, listener) {
255+
if (!this.l7layer) {
256+
return;
257+
}
258+
const _this = this;
259+
this.eventListeners[listener] = function (e) {
260+
listener(_this._formateEvent(e));
261+
};
262+
this.l7layer.once(this._formatListenType(type), this.eventListeners[listener]);
263+
}
264+
265+
off(type, listener) {
266+
if (!this.l7layer) {
267+
return;
268+
}
269+
this.l7layer.off(this._formatListenType(type), this.eventListeners[listener]);
270+
}
271+
272+
querySourceFeatures() {
273+
if (!this.l7layer || !this.l7layer.isVisible()) {
274+
return [];
275+
}
276+
const { layerSource, pickingService } = this.l7layer;
277+
let datas = pickingService.handleRawFeature(layerSource.data.dataArray, this.l7layer);
278+
const { parser: { type } } = layerSource;
279+
if (type === 'mvt') {
280+
const { tileset: { cacheTiles = [] } = {} } = layerSource;
281+
const { sourceLayer, featureId = 'id' } = this.l7layer.rawConfig;
282+
const mvtDatas = [];
283+
cacheTiles.forEach((sourceTile) => {
284+
const cacheFeatures = (sourceTile.data && sourceTile.data.vectorLayerCache[sourceLayer]) || [];
285+
const features = cacheFeatures.filter(
286+
(item) =>
287+
(!item[featureId] || !mvtDatas.some((feature) => feature[featureId] === item[featureId])) &&
288+
(!(item.properties || {})[featureId] ||
289+
!mvtDatas.some((feature) => feature.properties[featureId] === item.properties[featureId]))
290+
);
291+
mvtDatas.push(...pickingService.handleRawFeature(features, this.l7layer));
292+
});
293+
datas = datas.length > mvtDatas.length ? datas : mvtDatas;
294+
}
295+
if (!datas.length) {
296+
const cb = (result = []) => {
297+
datas = result;
298+
};
299+
const bounds = [
300+
[0, 0],
301+
[this.map.transform.width - 1, this.map.transform.height - 1] // -1 是解决报错问题
302+
];
303+
this.queryRenderedFeatures(bounds, { layerCapture: false }, cb);
304+
}
305+
return datas;
306+
}
307+
308+
setSelectedDatas(datas) {
309+
this.selectedDatas = datas instanceof Array ? datas : [datas];
310+
}
311+
312+
_formatListenType(type) {
313+
switch (type) {
314+
case 'mouseover':
315+
return 'mouseenter';
316+
case 'mouseleave':
317+
return 'mouseout';
318+
default:
319+
return type;
320+
}
321+
}
322+
323+
_transformFilterValues(options, ...args) {
324+
const { fields, values, selectedDatas } = options;
325+
const argValues = args.filter((item) => item !== void 0);
326+
const selectedValues = selectedDatas.map((feature) => {
327+
return fields.map((name) => (feature.properties || {})[name]).filter((item) => item !== void 0);
328+
});
329+
return (
330+
(!values || values(...args)) &&
331+
!selectedValues.some((values) => JSON.stringify(values) === JSON.stringify(argValues))
332+
);
333+
}
334+
}

src/mapboxgl/core/MapExtend.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import mapboxgl from 'mapbox-gl';
55
import { decryptSources } from './decryptSource';
66
import { getServiceKey } from '@supermapgis/iclient-common/util/EncryptRequest';
7-
import { CustomOverlayLayer } from '../overlay/Base';
7+
import { CustomOverlayLayer } from '@supermapgis/iclient-common/overlay/Base';
88

99
/**
1010
* @function MapExtend

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy