import { EventEmitter } from "eventemitter3"; import HPaaSDeckGL from "../HPaaSDeckGL"; import { Feature, featureCollection, FeatureCollection, LineString, nearestPoint, point, Point, Position, } from "@turf/turf"; import IBaseUnit from "./IBaseUnit"; import { HpaasEventKey } from "../types"; import { lineStyle, pointStyle } from "./unitStyles"; class BaseUnitDeckGL extends EventEmitter implements IBaseUnit { private hpaas: HPaaSDeckGL; public segmentsIsShow = false; private segmentLayer?: any; private pointLayer?: any; // 当前视图里所有的路段控制点 public allPoints: Position[] = []; public allPointsCollection: FeatureCollection = featureCollection([]); constructor(hpaas: HPaaSDeckGL) { super(); this.hpaas = hpaas; this.initLayer(); setTimeout(() => { this.bindEvent(); }); } initLayer(data?: FeatureCollection) { this.segmentLayer = this.hpaas.scene.createLayer("LineString", lineStyle); this.pointLayer = this.hpaas.scene.createLayer("Point", pointStyle); this.hpaas.scene.addLayer(this.segmentLayer); this.hpaas.scene.addLayer(this.pointLayer); } private bindEvent() { this.hpaas.scene.layerEvent.on(this.segmentLayer, "click", (e) => { console.log("SEGMENT_PICK", e.feature); this.hpaas.events.emit(HpaasEventKey.SEGMENT_PICK, e.feature as Feature); }); this.hpaas.scene.sceneEvent.on("zoomend", (e) => { const minZoom = this.hpaas.options.showBaseUnitMinZoom as number; if (e.zoom >= minZoom) { this.segmentsIsShow = true; this.show(); this.loadSegmentsInViewport(); } else { this.segmentsIsShow = false; this.hide(); } }); this.hpaas.scene.sceneEvent.on("moveend", (e) => { // const { viewState } = e; this.loadSegmentsInViewport(); }); } /** * 渲染区域内的路段 * @param areaUid 区域uid * @param areaData 区域信息 * @param forceRefresh 默认fasle优先取indexDB中的数据,设置true则强制请求http接口获取数据 */ async loadSegmentsInViewport() { if (!this.segmentsIsShow) return; const viewport = this.hpaas.deckgl.getViewports()[0]; const bounds: [number, number, number, number] = viewport.getBounds(); const segments = await this.hpaas.wfsApi.querySegmentFeaturesAtBounds(bounds); this.segmentLayer?.updateState({ props: { data: segments }, changeFlags: { dataChanged: true }, }); this.allPoints = []; segments.features.forEach((f: Feature) => { f.geometry.coordinates.forEach((c) => { this.allPoints.push(c); }); }); const features: Feature[] = []; this.allPoints.forEach((p) => { features.push(point(p)); }); this.allPointsCollection = featureCollection(features); this.pointLayer?.updateState({ props: { data: this.allPointsCollection }, changeFlags: { dataChanged: true }, }); this.hpaas.events.emit(HpaasEventKey.SEGMENT_DATA_LOADED, segments); } show() {} hide() { this.segmentLayer?.updateState({ props: { data: featureCollection([]) }, changeFlags: { dataChanged: true }, }); this.pointLayer?.updateState({ props: { data: featureCollection([]) }, changeFlags: { dataChanged: true }, }); } /** * 获取离此点最近的点 */ getNearestPoint(sourcePoint: Position) { if (this.allPointsCollection.features.length == 0) { return null; } return nearestPoint(sourcePoint, this.allPointsCollection); } } export default BaseUnitDeckGL;