|
|
|
@ -13,14 +13,13 @@ import { AnimationService } from './animation.service' |
|
|
|
|
|
|
|
import type { MarkerData, MapProps } from '../types/map.types' |
|
|
|
import { createMarkerStyle, getClusterMarkerData, getStatusColor } from '../utils/map.utils' |
|
|
|
import { ANIMATION_CONFIG } from '../constants/map.constants' |
|
|
|
|
|
|
|
// 防抖
|
|
|
|
import { debounce } from 'lodash-es' |
|
|
|
export class MarkerService { |
|
|
|
private map: Map | null = null |
|
|
|
markerLayer: VectorLayer<VectorSource | Cluster> | null = null |
|
|
|
// 当前图层模式(single或cluster聚合):避免重复创建图层
|
|
|
|
private currentLayerMode: 'single' | 'cluster' | '' = '' |
|
|
|
markerLayer: VectorLayer<Cluster> | null = null |
|
|
|
|
|
|
|
private vectorSource: VectorSource |
|
|
|
private animationService: AnimationService | null = null |
|
|
|
|
|
|
|
@ -28,6 +27,7 @@ export class MarkerService { |
|
|
|
this.map = map |
|
|
|
this.vectorSource = new VectorSource() |
|
|
|
this.animationService = new AnimationService(map) |
|
|
|
this.createMarkerLayer() |
|
|
|
} |
|
|
|
show() { |
|
|
|
this.markerLayer?.setVisible(true) |
|
|
|
@ -37,27 +37,14 @@ export class MarkerService { |
|
|
|
this.markerLayer?.setVisible(false) |
|
|
|
this.animationService?.hide() |
|
|
|
} |
|
|
|
/** |
|
|
|
* 创建标记图层 |
|
|
|
*/ |
|
|
|
createMarkerLayer = debounce((props: MapProps) => { |
|
|
|
console.time('updateData') |
|
|
|
this.updateData(props) |
|
|
|
console.timeEnd('updateData') |
|
|
|
console.time('createMarkerLayerFromProps') |
|
|
|
|
|
|
|
this.createMarkerLayerFromProps(props) |
|
|
|
|
|
|
|
console.timeEnd('createMarkerLayerFromProps') |
|
|
|
}, 1000) |
|
|
|
/** |
|
|
|
* 更新标记数据 |
|
|
|
*/ |
|
|
|
updateData(props: MapProps): void { |
|
|
|
updateData(markers: MarkerData[]): void { |
|
|
|
this.animationService?.clear() |
|
|
|
this.vectorSource.clear() |
|
|
|
// 添加标记
|
|
|
|
const markers = props.markers || [] |
|
|
|
// debugger
|
|
|
|
const features: Feature<Point>[] = [] |
|
|
|
markers.forEach((marker) => { |
|
|
|
const feature = new Feature({ |
|
|
|
@ -72,7 +59,7 @@ export class MarkerService { |
|
|
|
this.vectorSource.addFeatures(features) |
|
|
|
this.getSinglePointsInView() |
|
|
|
} |
|
|
|
setClusterDistance= debounce(()=> { |
|
|
|
setClusterDistance = debounce(() => { |
|
|
|
if (!this.map) return |
|
|
|
const clusterLayer = this.markerLayer |
|
|
|
if (!clusterLayer) return |
|
|
|
@ -82,18 +69,18 @@ export class MarkerService { |
|
|
|
let distance = 2 |
|
|
|
if (zoom <= 4) { |
|
|
|
distance = 100 |
|
|
|
}else if (zoom <= 6) { |
|
|
|
} else if (zoom <= 6) { |
|
|
|
distance = 80 |
|
|
|
} else if (zoom <= 10) { |
|
|
|
distance = 30 |
|
|
|
} else if (zoom <= 16) { |
|
|
|
distance = 30 |
|
|
|
}else if (zoom <= 17) { |
|
|
|
} else if (zoom <= 17) { |
|
|
|
distance = 10 |
|
|
|
} |
|
|
|
console.log('zoom',zoom,'distance',distance) |
|
|
|
console.log('zoom', zoom, 'distance', distance) |
|
|
|
clusterSource?.setDistance(distance) |
|
|
|
},200) |
|
|
|
}, 200) |
|
|
|
/** |
|
|
|
* 获取视图内聚合图层中没有聚合的单个点 |
|
|
|
* @returns {Array} 单个点要素数组 |
|
|
|
@ -107,6 +94,7 @@ export class MarkerService { |
|
|
|
|
|
|
|
// 获取聚合图层的源
|
|
|
|
const clusterSource = clusterLayer.getSource() |
|
|
|
if (!clusterSource) return |
|
|
|
|
|
|
|
// 获取当前视图范围
|
|
|
|
const view = map.getView() |
|
|
|
@ -127,33 +115,17 @@ export class MarkerService { |
|
|
|
} |
|
|
|
}) |
|
|
|
this.animationService?.addAll(singlePoints || []) |
|
|
|
return singlePoints |
|
|
|
},300) |
|
|
|
|
|
|
|
}, 300) |
|
|
|
|
|
|
|
/** |
|
|
|
* 从props创建markerLayer(内部方法) |
|
|
|
* |
|
|
|
*/ |
|
|
|
// : VectorLayer<VectorSource | Cluster>
|
|
|
|
createMarkerLayerFromProps(props: MapProps) { |
|
|
|
// console.log('createMarkerLayerFromProps')
|
|
|
|
createMarkerLayer() { |
|
|
|
let newLayer: VectorLayer<Cluster> | null = null |
|
|
|
|
|
|
|
// this.updateData(props)
|
|
|
|
|
|
|
|
// 检查是否应该强制使用单个marker模式
|
|
|
|
const shouldForceSingleMark = () => { |
|
|
|
if (!props.forceSingleMark || !this.map) return false |
|
|
|
const currentZoom = this.map.getView().getZoom() |
|
|
|
|
|
|
|
return currentZoom && currentZoom >= ANIMATION_CONFIG.clusterThreshold |
|
|
|
} |
|
|
|
|
|
|
|
let newLayer: VectorLayer<VectorSource | Cluster> | null = null |
|
|
|
// 如果启用聚合且不强制使用单个marker模式
|
|
|
|
if (props.enableCluster && !shouldForceSingleMark()) { |
|
|
|
if (this.currentLayerMode === 'cluster') return |
|
|
|
this.currentLayerMode = 'cluster' |
|
|
|
// this.animationService?.clear()
|
|
|
|
console.log('聚合图层') |
|
|
|
|
|
|
|
const clusterSource = new Cluster({ |
|
|
|
@ -161,7 +133,6 @@ export class MarkerService { |
|
|
|
distance: 20 // 单位是像素
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
newLayer = new VectorLayer({ |
|
|
|
source: clusterSource, |
|
|
|
zIndex: 1, |
|
|
|
@ -189,27 +160,6 @@ export class MarkerService { |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
} else { |
|
|
|
if (this.currentLayerMode === 'single') return |
|
|
|
this.currentLayerMode = 'single' |
|
|
|
|
|
|
|
console.log('基础marker图层') |
|
|
|
|
|
|
|
newLayer = new VectorLayer({ |
|
|
|
source: this.vectorSource, |
|
|
|
zIndex: 1, |
|
|
|
renderOrder: (a, b) => { |
|
|
|
// 按xxx属性排列
|
|
|
|
return b.get('markerData').statusPriority - a.get('markerData').statusPriority |
|
|
|
} |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
if (this.markerLayer) { |
|
|
|
const isVisible = this.markerLayer?.getVisible() || false |
|
|
|
newLayer.setVisible(isVisible) // 新图层保持当前可见状态
|
|
|
|
this.map?.removeLayer(this.markerLayer) |
|
|
|
} |
|
|
|
|
|
|
|
this.markerLayer = newLayer |
|
|
|
this.map?.addLayer(this.markerLayer) |
|
|
|
@ -230,8 +180,7 @@ export class MarkerService { |
|
|
|
destroy(): void { |
|
|
|
this.markerLayer = null |
|
|
|
this.animationService?.destroy() |
|
|
|
// this.currentProps = null
|
|
|
|
this.createMarkerLayer.cancel() |
|
|
|
|
|
|
|
this.map = null |
|
|
|
} |
|
|
|
} |
|
|
|
|