mirror of https://gitee.com/antv-l7/antv-l7
fix: 自定义图层 - markerLayer - 修复图层执行clear后聚合能力失效问题 (#1333)
Co-authored-by: Dreammy23 <echo.cmy@antgroup.com>
This commit is contained in:
parent
5225675cbe
commit
16df259e61
|
@ -14,11 +14,12 @@ export default () => {
|
|||
zoom: 3,
|
||||
}),
|
||||
});
|
||||
// addMarkers1(scene);
|
||||
addMarkers2(scene);
|
||||
// addMarkers(scene);
|
||||
testRemoveMarkerLayer(scene);
|
||||
// testClearMarkerLayer(scene);
|
||||
}, []);
|
||||
|
||||
const addMarkers1 = (scene) => {
|
||||
const addMarkers = (scene) => {
|
||||
fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
|
||||
)
|
||||
|
@ -37,29 +38,67 @@ export default () => {
|
|||
});
|
||||
};
|
||||
|
||||
const addMarkers2 = (scene) => {
|
||||
// bugfix验证:执行scene.removeMarkerLayer后,缩放图层marker数据还原
|
||||
const testRemoveMarkerLayer = (scene) => {
|
||||
fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((nodes) => {
|
||||
const markerLayer = new MarkerLayer({ cluster: true });
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
const markerLayer = new MarkerLayer({
|
||||
cluster: true,
|
||||
});
|
||||
for (let i = 0; i < nodes.features.length; i++) {
|
||||
const { coordinates } = nodes.features[i].geometry;
|
||||
const el = document.createElement('label');
|
||||
el.textContent = coordinates[1];
|
||||
el.style.background = getColor(coordinates[1]);
|
||||
el.style.borderColor = getColor(coordinates[1]);
|
||||
|
||||
const marker = new Marker({
|
||||
element: el,
|
||||
}).setLnglat({
|
||||
const marker = new Marker().setLnglat({
|
||||
lng: coordinates[0],
|
||||
lat: coordinates[1],
|
||||
});
|
||||
markerLayer.addMarker(marker);
|
||||
}
|
||||
scene.addMarkerLayer(markerLayer);
|
||||
// 3秒后删除图层
|
||||
setTimeout(() => {
|
||||
scene.removeMarkerLayer(markerLayer);
|
||||
}, 3000);
|
||||
});
|
||||
};
|
||||
|
||||
// bugfix验证:执行markerLayer.clear后,图层聚合能力失效
|
||||
const testClearMarkerLayer = (scene) => {
|
||||
fetch(
|
||||
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((nodes) => {
|
||||
const markerLayer = new MarkerLayer({
|
||||
cluster: true,
|
||||
});
|
||||
|
||||
for (let i = 0; i < nodes.features.length; i++) {
|
||||
const { coordinates } = nodes.features[i].geometry;
|
||||
const marker = new Marker().setLnglat({
|
||||
lng: coordinates[0],
|
||||
lat: coordinates[1],
|
||||
});
|
||||
markerLayer.addMarker(marker);
|
||||
}
|
||||
scene.addMarkerLayer(markerLayer);
|
||||
|
||||
setTimeout(() => {
|
||||
if (markerLayer.getMarkers().length > 0) {
|
||||
markerLayer.clear();
|
||||
}
|
||||
|
||||
for (let i = 0; i < 200; i++) {
|
||||
const { coordinates } = nodes.features[i].geometry;
|
||||
const marker = new Marker().setLnglat({
|
||||
lng: coordinates[0],
|
||||
lat: coordinates[1],
|
||||
});
|
||||
markerLayer.addMarker(marker);
|
||||
}
|
||||
}, 3 * 1000);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -29,11 +29,11 @@ interface IPointFeature {
|
|||
properties: any;
|
||||
}
|
||||
export default class MarkerLayer extends EventEmitter {
|
||||
private markers: IMarker[] = [];
|
||||
private markers: IMarker[] = []; // 原始的marker列表
|
||||
private markerLayerOption: IMarkerLayerOption;
|
||||
private clusterIndex: Supercluster;
|
||||
private points: IPointFeature[] = [];
|
||||
private clusterMarkers: IMarker[] = [];
|
||||
private clusterMarkers: IMarker[] = []; // 聚合后的marker列表
|
||||
private mapsService: IMapService<unknown>;
|
||||
private scene: Container;
|
||||
private zoom: number;
|
||||
|
@ -46,6 +46,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
bindAll(['update'], this);
|
||||
this.zoom = this.markerLayerOption.clusterOption?.zoom || -99;
|
||||
}
|
||||
|
||||
public getDefault() {
|
||||
return {
|
||||
cluster: false,
|
||||
|
@ -59,6 +60,8 @@ export default class MarkerLayer extends EventEmitter {
|
|||
},
|
||||
};
|
||||
}
|
||||
|
||||
// 执行scene.addMarkerLayer时调用
|
||||
public addTo(scene: Container) {
|
||||
// this.remove();
|
||||
this.scene = scene;
|
||||
|
@ -76,6 +79,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
return this;
|
||||
}
|
||||
|
||||
// 设置容器大小
|
||||
private setContainerSize() {
|
||||
if (!this.mapsService) return;
|
||||
const container = this.mapsService.getContainer();
|
||||
|
@ -86,10 +90,12 @@ export default class MarkerLayer extends EventEmitter {
|
|||
};
|
||||
}
|
||||
|
||||
// 获取容器尺寸
|
||||
private getContainerSize() {
|
||||
return this.containerSize;
|
||||
}
|
||||
|
||||
// 在图层添加单个marker
|
||||
public addMarker(marker: IMarker) {
|
||||
const cluster = this.markerLayerOption.cluster;
|
||||
marker.getMarkerLayerContainerSize = this.getContainerSize.bind(this);
|
||||
|
@ -142,16 +148,20 @@ export default class MarkerLayer extends EventEmitter {
|
|||
});
|
||||
}
|
||||
|
||||
// 返回当下的markers数据,有聚合图时返回聚合的marker列表,否则返回原始maerker列表
|
||||
public getMarkers() {
|
||||
const cluster = this.markerLayerOption.cluster;
|
||||
return cluster ? this.clusterMarkers : this.markers;
|
||||
}
|
||||
|
||||
// 批量添加marker到scene
|
||||
public addMarkers() {
|
||||
this.getMarkers().forEach((marker: IMarker) => {
|
||||
marker.addTo(this.scene);
|
||||
});
|
||||
}
|
||||
|
||||
// 清除图层里的marker
|
||||
public clear() {
|
||||
this.markers.forEach((marker: IMarker) => {
|
||||
marker.remove();
|
||||
|
@ -159,10 +169,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
this.clusterMarkers.forEach((clusterMarker: IMarker) => {
|
||||
clusterMarker.remove();
|
||||
});
|
||||
this.mapsService.off('camerachange', this.update);
|
||||
this.mapsService.off('viewchange', this.update);
|
||||
this.mapsService.off('camerachange', this.setContainerSize.bind(this));
|
||||
this.mapsService.off('viewchange', this.setContainerSize.bind(this));
|
||||
|
||||
this.markers = [];
|
||||
this.points = [];
|
||||
this.clusterMarkers = [];
|
||||
|
@ -171,8 +178,13 @@ export default class MarkerLayer extends EventEmitter {
|
|||
public destroy() {
|
||||
this.clear();
|
||||
this.removeAllListeners();
|
||||
this.mapsService.off('camerachange', this.update);
|
||||
this.mapsService.off('viewchange', this.update);
|
||||
this.mapsService.off('camerachange', this.setContainerSize.bind(this));
|
||||
this.mapsService.off('viewchange', this.setContainerSize.bind(this));
|
||||
}
|
||||
|
||||
// 将marker数据保存在point中
|
||||
private addPoint(marker: IMarker, id: number) {
|
||||
const { lng, lat } = marker.getLnglat();
|
||||
const feature: IPointFeature = {
|
||||
|
@ -196,8 +208,11 @@ export default class MarkerLayer extends EventEmitter {
|
|||
if (!this.markerLayerOption.cluster) {
|
||||
return;
|
||||
}
|
||||
const { radius, minZoom = 0, maxZoom } = this.markerLayerOption
|
||||
.clusterOption as IMarkerStyleOption;
|
||||
const {
|
||||
radius,
|
||||
minZoom = 0,
|
||||
maxZoom,
|
||||
} = this.markerLayerOption.clusterOption;
|
||||
this.clusterIndex = new Supercluster({
|
||||
radius,
|
||||
minZoom,
|
||||
|
@ -217,7 +232,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
clusterPoint.forEach((feature: any) => {
|
||||
const { field, method } = this.markerLayerOption.clusterOption;
|
||||
// 处理聚合数据
|
||||
if (feature.properties && feature.properties?.cluster_id) {
|
||||
if (feature.properties?.cluster_id) {
|
||||
const clusterData = this.getLeaves(feature.properties?.cluster_id);
|
||||
feature.properties.clusterData = clusterData;
|
||||
if (field && method) {
|
||||
|
@ -238,6 +253,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
marker.addTo(this.scene);
|
||||
});
|
||||
}
|
||||
|
||||
private getLeaves(
|
||||
clusterId: number,
|
||||
limit: number = Infinity,
|
||||
|
@ -248,6 +264,7 @@ export default class MarkerLayer extends EventEmitter {
|
|||
}
|
||||
return this.clusterIndex.getLeaves(clusterId, limit, offset);
|
||||
}
|
||||
|
||||
private clusterMarker(feature: any) {
|
||||
const clusterOption = this.markerLayerOption.clusterOption;
|
||||
|
||||
|
@ -262,17 +279,20 @@ export default class MarkerLayer extends EventEmitter {
|
|||
});
|
||||
return marker;
|
||||
}
|
||||
|
||||
private normalMarker(feature: any) {
|
||||
const marker_id = feature.properties.marker_id;
|
||||
return this.markers[marker_id];
|
||||
}
|
||||
|
||||
private update() {
|
||||
if (!this.mapsService) {
|
||||
return;
|
||||
}
|
||||
if (!this.mapsService) return;
|
||||
// 当图层中无marker时,无需更新
|
||||
if (this.markers.length === 0) return;
|
||||
|
||||
const zoom = this.mapsService.getZoom();
|
||||
const bbox = this.mapsService.getBounds();
|
||||
|
||||
if (
|
||||
!this.bbox ||
|
||||
Math.abs(zoom - this.zoom) >= 1 ||
|
||||
|
|
|
@ -2,11 +2,7 @@ import { Container, injectable } from 'inversify';
|
|||
import 'reflect-metadata';
|
||||
import { TYPES } from '../../types';
|
||||
import { IMapService } from '../map/IMapService';
|
||||
import {
|
||||
IMarker,
|
||||
IMarkerLayer,
|
||||
IMarkerService,
|
||||
} from './IMarkerService';
|
||||
import { IMarker, IMarkerLayer, IMarkerService } from './IMarkerService';
|
||||
|
||||
@injectable()
|
||||
export default class MarkerService implements IMarkerService {
|
||||
|
|
Loading…
Reference in New Issue