feat: 自定义图层 - marker&markerLayer - 多个marker节点性能优化 (#1300)

* chore: 新增marker开发demo

* style: 增加格式化空格

* marker性能优化 - 缓存计算变量:ignore (#1298)

Co-authored-by: linlb <linlb@homeking365.com>

* feat: 自定义图层 - marker&markerLayer - markerLayer多节点kmarker性能优化

* feat: 添加demo

* feat: 删除冗余代码

Co-authored-by: Dreammy23 <echo.cmy@antgroup.com>
Co-authored-by: bolry <909559682@qq.com>
Co-authored-by: linlb <linlb@homeking365.com>
This commit is contained in:
Dreammy23 2022-08-30 16:24:02 +08:00 committed by GitHub
parent 6672caaa6d
commit 16b6abc01f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 47 deletions

View File

@ -1,40 +1,43 @@
### markerLayer
### marker-layer
```tsx
import { Marker, MarkerLayer, Scene } from '@antv/l7';
import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps';
import { GaodeMap } from '@antv/l7-maps';
import React, { useEffect } from 'react';
export default () => {
useEffect(() => {
const gaodeV1Scene = new Scene({
id: 'gaodeV1',
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [105, 30.258134],
zoom: 2,
zoom: 3,
}),
});
// const gaodeV2Scene = new Scene({
// id: 'gaodeV2',
// map: new GaodeMapV2({
// center: [105, 30.258134],
// zoom: 3,
// }),
// });
const mapboxScene = new Scene({
id: 'mapbox',
map: new Mapbox({
center: [120, 30],
zoom: 2,
}),
});
addMarkers(gaodeV1Scene);
// addMarkers(gaodeV2Scene);
addMarkers(mapboxScene);
// addMarkers1(scene);
addMarkers2(scene);
}, []);
const addMarkers = (s) => {
const addMarkers1 = (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();
for (let i = 0; i < 400; i++) {
const { coordinates } = nodes.features[i].geometry;
const marker = new Marker().setLnglat({
lng: coordinates[0],
lat: coordinates[1],
});
markerLayer.addMarker(marker);
}
scene.addMarkerLayer(markerLayer);
});
};
const addMarkers2 = (scene) => {
fetch(
'https://gw.alipayobjects.com/os/basement_prod/d3564b06-670f-46ea-8edb-842f7010a7c6.json',
)
@ -56,7 +59,7 @@ export default () => {
});
markerLayer.addMarker(marker);
}
s.addMarkerLayer(markerLayer);
scene.addMarkerLayer(markerLayer);
});
};
@ -89,15 +92,13 @@ export default () => {
};
return (
<>
<h2>400 个节点测试</h2>
<h4>高德V1</h4>
<div id="gaodeV1" style={{ height: '500px', position: 'relative' }} />
<h4>Mapbox</h4>
<div id="mapbox" style={{ height: '500px', position: 'relative' }} />
</>
<div
id="map"
style={{
height: '500px',
position: 'relative',
}}
/>
);
};
```

View File

@ -1,4 +1,9 @@
import { IMapService, IMarker, TYPES } from '@antv/l7-core';
import {
IMapService,
IMarker,
IMarkerContainerAndBounds,
TYPES,
} from '@antv/l7-core';
import {
bindAll,
boundsContains,
@ -23,7 +28,6 @@ interface IPointFeature {
};
properties: any;
}
export default class MarkerLayer extends EventEmitter {
private markers: IMarker[] = [];
private markerLayerOption: IMarkerLayerOption;
@ -34,6 +38,7 @@ export default class MarkerLayer extends EventEmitter {
private scene: Container;
private zoom: number;
private bbox: IBounds;
private containerSize: IMarkerContainerAndBounds;
constructor(option?: Partial<IMarkerLayerOption>) {
super();
@ -65,11 +70,30 @@ export default class MarkerLayer extends EventEmitter {
this.mapsService.on('camerachange', this.update); // amap1.x 更新事件
this.mapsService.on('viewchange', this.update); // amap2.0 更新事件
}
this.mapsService.on('camerachange', this.setContainerSize.bind(this)); // amap1.x 更新事件
this.mapsService.on('viewchange', this.setContainerSize.bind(this)); // amap2.0 更新事件
this.addMarkers();
return this;
}
private setContainerSize() {
if (!this.mapsService) return;
const container = this.mapsService.getContainer();
this.containerSize = {
containerWidth: container?.scrollWidth || 0,
containerHeight: container?.scrollHeight || 0,
bounds: this.mapsService.getBounds(),
};
}
private getContainerSize() {
return this.containerSize;
}
public addMarker(marker: IMarker) {
const cluster = this.markerLayerOption.cluster;
marker.getMarkerLayerContainerSize = this.getContainerSize.bind(this);
if (cluster) {
this.addPoint(marker, this.markers.length);
if (this.mapsService) {
@ -136,6 +160,8 @@ export default class MarkerLayer extends EventEmitter {
clusterMarker.remove();
});
this.mapsService.off('camerachange', this.update);
this.mapsService.off('camerachange', this.setContainerSize.bind(this));
this.mapsService.off('viewchange', this.setContainerSize.bind(this));
this.markers = [];
this.points=[];
this.clusterMarkers = [];

View File

@ -1,6 +1,7 @@
import {
ILngLat,
IMapService,
IMarkerContainerAndBounds,
IMarkerOption,
IPoint,
IPopup,
@ -16,7 +17,6 @@ import {
} from '@antv/l7-utils';
import { EventEmitter } from 'eventemitter3';
import { Container } from 'inversify';
// marker 支持 dragger 未完成
export default class Marker extends EventEmitter {
private markerOption: IMarkerOption;
@ -27,6 +27,8 @@ export default class Marker extends EventEmitter {
private lngLat: ILngLat;
private scene: Container;
private added: boolean = false;
public getMarkerLayerContainerSize(): IMarkerContainerAndBounds | void {}
constructor(option?: Partial<IMarkerOption>) {
super();
this.markerOption = {
@ -219,25 +221,28 @@ export default class Marker extends EventEmitter {
}
}
private getCurrentContainerSize() {
const container = this.mapsService.getContainer();
return {
containerHeight: container?.scrollHeight || 0,
containerWidth: container?.scrollWidth || 0,
bounds: this.mapsService.getBounds(),
};
}
private updatePosition() {
if (!this.mapsService) {
return;
}
const { element, offsets } = this.markerOption;
const { lng, lat } = this.lngLat;
const bounds = this.mapsService.getBounds();
const pos = this.mapsService.lngLatToContainer([lng, lat]);
if (element) {
element.style.display = 'block';
element.style.whiteSpace = 'nowrap';
const container = this.mapsService.getContainer();
let containerWidth = 0;
let containerHeight = 0;
if (container) {
containerWidth = container.scrollWidth;
containerHeight = container.scrollHeight;
}
const { containerHeight, containerWidth, bounds } =
this.getMarkerLayerContainerSize() || this.getCurrentContainerSize();
if (!bounds) return;
// 当前可视区域包含跨日界线
if (Math.abs(bounds[0][0]) > 180 || Math.abs(bounds[1][0]) > 180) {
if (pos.x > containerWidth) {

View File

@ -1,4 +1,4 @@
import { anchorType } from '@antv/l7-utils';
import { anchorType, IBounds } from '@antv/l7-utils';
import { Container } from 'inversify';
import { ILngLat, IMapService, IPoint } from '../map/IMapService';
import { IPopup } from './IPopupService';
@ -19,6 +19,13 @@ export interface IMarkerOption {
extData?: any;
style?: CSSStyleDeclaration;
}
export interface IMarkerContainerAndBounds {
containerWidth: number;
containerHeight: number;
bounds: IBounds;
}
export interface IMarker {
addTo(scene: Container): void;
remove(): void;
@ -32,6 +39,7 @@ export interface IMarker {
openPopup(): this;
closePopup(): this;
setElement(el: HTMLElement): this;
getMarkerLayerContainerSize: () => IMarkerContainerAndBounds | void;
}
export interface IMarkerService {
container: HTMLElement;