/* * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-27 08:43:44 * @LastEditors: cbwu * @LastEditTime: 2024-04-13 10:46:58 * @Description: 绘制Polyline类 */ import { Viewer, ScreenSpaceEventHandler, Cartesian3, Color, ScreenSpaceEventType, Entity, CallbackProperty, PolylineDashMaterialProperty, } from 'cesium' import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' // import { PointEntity, PolylineEntity } from '@/utils/map/geometry' import { PolylineEntity } from '../geometry/polylineEntity' import { PointEntity } from '@/utils/map/geometry/pointEntity' import EditGeometry from '@/utils/map/draw/editGeometry' import {getDistance} from "@/utils/map/geocomputation.ts"; import {Angle} from "@/utils/map/angle.ts"; import {TextLabel} from "@/utils/map/geometry/textLabel.ts"; type EntityOptions = { id?: string name?: string show?: boolean pixelSize?: number color?: Color fillColor?: Color fill?: boolean width?: number outlineWidth?: number } export default class CreatePolyline { viewer: Viewer handler: ScreenSpaceEventHandler polyline: PolylineEntity | null dashLine: Entity | null trackingLine: Entity | null trackingLinePositions: Cartesian3[] = [] controlPoints: Entity[] | null modifyPoint: any = null clickedGeometry: Entity | null = null moveSelectedPoint: PointEntity | null = null positions: Cartesian3[] = [] bMove: boolean = false bMeasure: boolean | undefined = false //是否处于测距模式 totalDistance: number = 0 bLongClick: boolean = false clickTimeout: any // layer: CustomDataSource defaultStyle: EntityOptions = { // id: 'Polyline' + String(PolylineEntity.id), // name: 'Polyline' + String(PolylineEntity.id + 1), show: true, width: 2, color: Color.GREEN, } constructor(viewer: Viewer, bMeasure: boolean=false,options?: EntityOptions) { this.viewer = viewer this.bMeasure = bMeasure; this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) this.polyline = null this.trackingLine = null this.dashLine = null this.totalDistance = 0 this.controlPoints = [] this.defaultStyle = { ...this.defaultStyle, ...options } } // 开始绘制 public start() { // 左单击加点 this.handler.setInputAction( this.leftClickCallBack, ScreenSpaceEventType.LEFT_CLICK, ) // 移动动态绘制 this.handler.setInputAction( this.moveCallBack, ScreenSpaceEventType.MOUSE_MOVE, ) // 左双击结束 this.handler.setInputAction( this.leftDoubleClickCallBack, ScreenSpaceEventType.LEFT_DOUBLE_CLICK, ) // 右击回退上一步 this.handler.setInputAction( this.rightClickCallBack, ScreenSpaceEventType.RIGHT_CLICK, ) } public end() { this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) } //左单击回调事件 private leftClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent) => { const pickedObject = this.viewer.scene.pick(event.position) if (pickedObject) { //点击同一位置,返回 if (pickedObject.id.id === this.polyline?.controlPointsID[this.positions.length - 1]) return } const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) if (cartesian3 != undefined) { if (!this.polyline) { this.polyline = new PolylineEntity(this.positions) this.dashLine = this.createTrackingLine(this.positions) this.viewer.entities.add(this.dashLine) this.viewer.dataSources.add(this.polyline) } this.polyline.addPoint(cartesian3) this.trackingLinePositions[0] = cartesian3 this.bMove = true this.viewer.scene.requestRender() //刷新 // 计算2点距离 if(this.positions.length>=2 && this.bMeasure){ let distance = getDistance(this.positions[this.positions.length-1],this.positions[this.positions.length-2]) this.totalDistance += distance // 计算2点方位角 let azimuth = Angle.getAzimuth(this.positions[this.positions.length-2],this.positions[this.positions.length-1]) // 计算2点的中间点 let midPoint = Cartesian3.midpoint(this.positions[this.positions.length-1],this.positions[this.positions.length-2],new Cartesian3()) // 添加label let labelText = `距离: ${distance.toFixed(2)}km, 方位角: ${azimuth}°` new TextLabel(this.viewer, midPoint,labelText) } } } // 移动回调事件 private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { if (this.bMove) { const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) if (cartesian3 != undefined) { //更新追踪线坐标 this.trackingLinePositions[1] = cartesian3 if (!this.trackingLine) { //创建追踪线对象 this.trackingLine = this.createTrackingLine( this.trackingLinePositions, ) this.viewer.entities.add(this.trackingLine) } } this.viewer.scene.requestRender() //刷新 } } // 左双击回调事件 private leftDoubleClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent,) => { if (!this.polyline) return this.bMove = false const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) if (cartesian3 != undefined) { // 移除追踪线 if (!this.trackingLine) { this.viewer.entities.remove(this.trackingLine!) } } if(this.bMeasure){ // 添加总距离label new TextLabel(this.viewer,this.positions[this.positions.length-1], `总距离: ${this.totalDistance.toFixed(2)}km`) } this.clearEvent() //结束绘制进入编辑模式 this.polyline.removeControlPoints() const editTool = new EditGeometry(this.viewer, this.polyline.geometry!) editTool.start() } // 右击回调事件 private rightClickCallBack = () => { if (!this.controlPoints) return if (this.controlPoints.length > 1) { const lastPoint = this.positions.pop() this.positions[this.positions.length - 1] = lastPoint! this.viewer.entities.remove(this.controlPoints.pop() as Entity) } } private clearEvent() { this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) } //创建追踪线 createTrackingLine(positions: Cartesian3[]) { return new Entity({ polyline: { positions: new CallbackProperty(() => { return positions }, false), width: 2, material: new PolylineDashMaterialProperty({ color: Color.GREEN, dashLength: 15, //短划线长度 }), clampToGround: true, }, }) } }