improvement(cluster marker): 针对聚合点只渲染视野范围内的元素,提高性能

通过传递视野范围坐标范围,只渲染视野范围内的
This commit is contained in:
ParryQiu 2020-01-20 17:03:20 +08:00
parent cc7ddae9bc
commit 31446172fc
2 changed files with 30 additions and 14 deletions

View File

@ -1,5 +1,11 @@
import { Scene, Marker, MarkerLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import {
Scene,
Marker,
MarkerLayer
} from '@antv/l7';
import {
GaodeMap
} from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
@ -23,7 +29,9 @@ function addMarkers() {
cluster: true
});
for (let i = 0; i < nodes.features.length; i++) {
const { coordinates } = nodes.features[i].geometry;
const {
coordinates
} = nodes.features[i].geometry;
const marker = new Marker().setLnglat({
lng: coordinates[0],
lat: coordinates[1]
@ -31,6 +39,6 @@ function addMarkers() {
markerLayer.addMarker(marker);
}
scene.addMarkerLayer(markerLayer);
scene.addMarkerLayer(markerLayer);
// scene.addMarkerLayer(markerLayer);
});
}

View File

@ -68,8 +68,8 @@ export default class MarkerLayer extends EventEmitter {
if (this.markerLayerOption.cluster) {
this.initCluster();
this.update();
this.mapsService.on('zoom', this.update);
this.mapsService.on('zoomchange', this.update);
// 地图视野变化时,重新计算视野内的聚合点。
this.mapsService.on('camerachange', this.update);
}
this.addMarkers();
return this;
@ -104,8 +104,7 @@ export default class MarkerLayer extends EventEmitter {
this.markers.forEach((marker: IMarker) => {
marker.remove();
});
this.mapsService.off('zoom', this.update);
this.mapsService.off('zoomchange', this.update);
this.mapsService.off('camerachange', this.update);
this.markers = [];
}
@ -142,10 +141,12 @@ export default class MarkerLayer extends EventEmitter {
}
private getClusterMarker(zoom: number) {
const clusterPoint = this.clusterIndex.getClusters(
[-180, -85, 180, 85],
zoom,
);
// 之前的参数为 [-180, -85, 180, 85],基本等于全地图的范围
// 优化后的逻辑为:
// 取当前视野范围 * 2只渲染视野内 * 2 范围的点
const viewBounds = this.mapsService.getBounds();
const viewBBox = viewBounds[0].concat(viewBounds[1]) as GeoJSON.BBox;
const clusterPoint = this.clusterIndex.getClusters(viewBBox, zoom);
this.clusterMarkers.forEach((marker: IMarker) => {
marker.remove();
});
@ -180,13 +181,20 @@ export default class MarkerLayer extends EventEmitter {
});
return marker;
}
private update() {
const zoom = this.mapsService.getZoom();
if (Math.abs(zoom - this.zoom) > 1) {
this.getClusterMarker(Math.floor(zoom));
// 在 zoom 变化的时候,通过控制触发的阈值 (0.4),减少小层级的 zoom 变化引起的频繁重绘
if (zoom !== this.zoom && Math.abs(zoom - this.zoom) > 0.4) {
// 按照当前地图的放大层级向下取整,进行聚合点的绘制
this.zoom = Math.floor(zoom);
this.getClusterMarker(Math.floor(zoom));
} else if (zoom === this.zoom) {
// 如果 zoom 没有变化只是平移进行重新计算渲染加载s
this.getClusterMarker(Math.floor(zoom));
}
}
private generateElement(feature: any) {
const el = DOM.create('div', 'l7-marker-cluster');
const label = DOM.create('div', '', el);