fix: 自定义图层 - markerLayer - 修复图层执行clear后聚合能力失效问题 (#1333)

Co-authored-by: Dreammy23 <echo.cmy@antgroup.com>
This commit is contained in:
Dreammy23 2022-09-09 21:41:20 +08:00 committed by GitHub
parent 5225675cbe
commit 16df259e61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 31 deletions

View File

@ -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);
});
};

View File

@ -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 ||

View File

@ -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 {