From 94a563b25e0f61e24c4ea9bd10c3921da43f213a Mon Sep 17 00:00:00 2001 From: thinkinggis Date: Sun, 9 Feb 2020 13:07:37 +0800 Subject: [PATCH] =?UTF-8?q?improvement(markerlayer):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E7=BC=A9=E6=94=BE=E8=8C=83=E5=9B=B4=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=8E=B7=E5=8F=96=E8=81=9A=E5=90=88=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- packages/component/src/markerlayer.ts | 45 +++++++++++---------------- packages/utils/__tests__/geo.spec.ts | 43 +++++++++++++++++++++---- packages/utils/src/geo.ts | 32 +++++++++++++++++++ 4 files changed, 89 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 525010130d..87c2d5c404 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "release-cdn": "antv-bin upload -n @antv/l7", "storybook": "start-storybook -p 6006", "test": "cross-env BABEL_ENV=test jest", - "test-live": "cross-env BABEL_ENV=test DEBUG_MODE=1 jest --watch packages/scene/__tests__/index.spec.ts ", + "test-live": "cross-env BABEL_ENV=test DEBUG_MODE=1 jest --watch", "coveralls": "jest --coverage && cat ./tests/coverage/lcov.info | coveralls", "tsc": "tsc", "watch": "yarn clean && lerna exec --parallel -- cross-env BABEL_ENV=cjs babel --watch src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments", diff --git a/packages/component/src/markerlayer.ts b/packages/component/src/markerlayer.ts index 1bbbc9ca21..8ff6bdc002 100644 --- a/packages/component/src/markerlayer.ts +++ b/packages/component/src/markerlayer.ts @@ -1,5 +1,12 @@ import { IMapService, IMarker, TYPES } from '@antv/l7-core'; -import { bindAll, DOM, Satistics } from '@antv/l7-utils'; +import { + bindAll, + boundsContains, + DOM, + IBounds, + padBounds, + Satistics, +} from '@antv/l7-utils'; import { EventEmitter } from 'eventemitter3'; import { Container } from 'inversify'; import { merge } from 'lodash'; @@ -39,6 +46,7 @@ export default class MarkerLayer extends EventEmitter { private mapsService: IMapService; private scene: Container; private zoom: number; + private bbox: IBounds; constructor(option?: Partial) { super(); @@ -141,11 +149,7 @@ export default class MarkerLayer extends EventEmitter { this.clusterIndex.load(this.points); } - private getClusterMarker(zoom: number) { - // 之前的参数为 [-180, -85, 180, 85],基本等于全地图的范围 - // 优化后的逻辑为: - // 取当前视野范围 * 2,只渲染视野内 * 2 范围的点 - const viewBounds = this.mapsService.getBounds(); + private getClusterMarker(viewBounds: IBounds, zoom: number) { const viewBBox = viewBounds[0].concat(viewBounds[1]) as GeoJSON.BBox; const clusterPoint = this.clusterIndex.getClusters(viewBBox, zoom); this.clusterMarkers.forEach((marker: IMarker) => { @@ -168,14 +172,10 @@ export default class MarkerLayer extends EventEmitter { const column = Satistics.getColumn(columnData as any, field); const stat = Satistics.getSatByColumn(method, column); const fieldName = 'point_' + method; - feature.properties[fieldName] = stat; + feature.properties[fieldName] = stat.toFixed(2); } } const marker = this.clusterMarker(feature); - // feature.properties && feature.properties.hasOwnProperty('point_count') - // ? this.clusterMarker(feature) - // : this.normalMarker(feature); - this.clusterMarkers.push(marker); marker.addTo(this.scene); }); @@ -211,14 +211,15 @@ export default class MarkerLayer extends EventEmitter { private update() { const zoom = this.mapsService.getZoom(); - // 在 zoom 变化的时候,通过控制触发的阈值 (0.4),减少小层级的 zoom 变化引起的频繁重绘 - if (zoom !== this.zoom && Math.abs(zoom - this.zoom) > 0.4) { - // 按照当前地图的放大层级向下取整,进行聚合点的绘制 + const bbox = this.mapsService.getBounds(); + if ( + !this.bbox || + Math.abs(zoom - this.zoom) >= 1 || + !boundsContains(this.bbox, bbox) + ) { + this.bbox = padBounds(bbox, 0.5); this.zoom = Math.floor(zoom); - this.getClusterMarker(Math.floor(zoom)); - } else if (zoom === this.zoom) { - // 如果 zoom 没有变化,只是平移,进行重新计算渲染加载s - this.getClusterMarker(Math.floor(zoom)); + this.getClusterMarker(this.bbox, this.zoom); } } @@ -234,14 +235,6 @@ export default class MarkerLayer extends EventEmitter { ? feature.properties['point_' + method] || feature.properties[field] : feature.properties.point_count; span.textContent = text; - // const elStyle = isFunction(style) - // ? style(feature.properties.point_count) - // : style; - - // Object.keys(elStyle).forEach((key: string) => { - // // @ts-ignore - // el.style[key] = elStyle[key]; - // }); return el; } } diff --git a/packages/utils/__tests__/geo.spec.ts b/packages/utils/__tests__/geo.spec.ts index 1e2eb32431..bd46bc29e7 100644 --- a/packages/utils/__tests__/geo.spec.ts +++ b/packages/utils/__tests__/geo.spec.ts @@ -1,8 +1,39 @@ -import { aProjectFlat, lngLatToMeters, project } from '../src/geo'; -describe('aProjectFlat', () => { - it('aProjectFlat', () => { - // console.log(aProjectFlat([112, 32])); - // console.log(lngLatToMeters([112, 32])); - // console.log(project([112, 32])); +import { + aProjectFlat, + boundsContains, + IBounds, + lngLatToMeters, + padBounds, + project, +} from '../src/geo'; + +describe('geo', () => { + it('padBounds', () => { + const bounds: IBounds = [ + [112, 30], + [116, 34], + ]; + const bounds2 = padBounds(bounds, 0.5); + expect(bounds2).toEqual([ + [110, 28], + [118, 36], + ]); + }); + + it('boundContain', () => { + const bounds: IBounds = [ + [112, 30], + [116, 34], + ]; + const b2: IBounds = [ + [113, 30], + [115, 33], + ]; + const b3: IBounds = [ + [110, 30], + [115, 33], + ]; + expect(boundsContains(bounds, b2)).toEqual(true); + expect(boundsContains(bounds, b3)).toEqual(false); }); }); diff --git a/packages/utils/src/geo.ts b/packages/utils/src/geo.ts index 61c6ae1778..be21ce19e5 100644 --- a/packages/utils/src/geo.ts +++ b/packages/utils/src/geo.ts @@ -7,6 +7,15 @@ import { Units, } from '@turf/helpers'; +export type IBounds = [[number, number], [number, number]]; +export interface ILngLat { + lng: number; + lat: number; +} +export interface IPoint { + x: number; + y: number; +} const originShift = (2 * Math.PI * 6378137) / 2.0; export type Point = number[]; /** @@ -207,3 +216,26 @@ export function project(lnglat: [number, number]) { return [x, y]; } + +export function padBounds(b: IBounds, bufferRatio: number): IBounds { + const heightBuffer = Math.abs(b[1][1] - b[0][1]) * bufferRatio; + const widthBuffer = Math.abs(b[1][0] - b[0][0]) * bufferRatio; + + return [ + [b[0][0] - widthBuffer, b[0][1] - heightBuffer], + [b[1][0] + widthBuffer, b[1][1] + heightBuffer], + ]; +} +/** + * b1 包含 b2 返回 true 否则false + * @param b1 bounds1 + * @param b2 bounds2 + */ +export function boundsContains(b1: IBounds, b2: IBounds): boolean { + return ( + b1[0][0] <= b2[0][0] && + b1[0][1] <= b2[0][1] && + b1[1][0] >= b2[1][0] && + b1[1][1] >= b2[1][1] + ); +}