Merge pull request 'feat: 新增Polyline的绘制与编辑(待完善)。fix: window下的Cesium,Viewer对象改成cesium,viewer小写' (#2) from dev-cbwu into dev
Reviewed-on: WuChengbo/GCSGUI#2pull/3/head
						commit
						3fc8da9da0
					
				| @ -0,0 +1,7 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-27 09:51:04 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-03-27 09:51:07 | ||||||
|  |  * @Description: 绘制点类 | ||||||
|  |  */ | ||||||
| @ -0,0 +1,197 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-27 08:43:44 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-04-02 13:33:25 | ||||||
|  |  * @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' | ||||||
|  | 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 | ||||||
|  |   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, options?: EntityOptions) { | ||||||
|  |     this.viewer = viewer | ||||||
|  |     this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) | ||||||
|  |     this.polyline = null | ||||||
|  |     this.trackingLine = null | ||||||
|  |     this.dashLine = null | ||||||
|  | 
 | ||||||
|  |     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) | ||||||
|  |     // console.log(pickedObject)
 | ||||||
|  |     if (pickedObject) { | ||||||
|  |       //点击同一位置,返回
 | ||||||
|  |       if ( | ||||||
|  |         pickedObject.id.id === | ||||||
|  |         this.polyline?.controlPointsID[this.positions.length - 1] | ||||||
|  |       ) { | ||||||
|  |         return | ||||||
|  |         // console.log('********click the same point')
 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |     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() //刷新
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // 移动回调事件
 | ||||||
|  |   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, | ||||||
|  |   ) => { | ||||||
|  |     // 清除可能已经设置的单击定时器
 | ||||||
|  |     // clearTimeout(this.clickTimeout)
 | ||||||
|  |     if (!this.polyline) return | ||||||
|  |     console.log('**************************** double click') | ||||||
|  |     this.bMove = false | ||||||
|  |     const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) | ||||||
|  |     if (cartesian3 != undefined) { | ||||||
|  |       // 移除追踪线
 | ||||||
|  |       if (!this.trackingLine) { | ||||||
|  |         this.viewer.entities.remove(this.trackingLine!) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.clearEvent() | ||||||
|  |     console.log('end:' + this.positions.length.toString()) | ||||||
|  |     console.log(this.positions) | ||||||
|  |     //结束绘制进入编辑模式
 | ||||||
|  |     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) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   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, | ||||||
|  |       }, | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,249 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-27 11:06:45 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-04-02 11:05:20 | ||||||
|  |  * @Description: 编辑几何体类。操作逻辑 | ||||||
|  |  */ | ||||||
|  | import { | ||||||
|  |   Viewer, | ||||||
|  |   ScreenSpaceEventHandler, | ||||||
|  |   PointGraphics, | ||||||
|  |   PolylineGraphics, | ||||||
|  |   Cartesian3, | ||||||
|  |   ConstantProperty, | ||||||
|  |   ScreenSpaceEventType, | ||||||
|  |   Entity, | ||||||
|  |   ConstantPositionProperty, | ||||||
|  |   defined, | ||||||
|  | } from 'cesium' | ||||||
|  | import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' | ||||||
|  | import { getClosestPoint, isOnLineSegment } from '@/utils/map/geocomputation' | ||||||
|  | import { PointEntity } from '@/utils/map/geometry/pointEntity' | ||||||
|  | export default class EditGeometry { | ||||||
|  |   viewer: Viewer | ||||||
|  |   editHandler: ScreenSpaceEventHandler | ||||||
|  |   geometry: Entity //要编辑的几何对象
 | ||||||
|  |   oldPositions: Cartesian3[] = [] //存储未修改前的坐标
 | ||||||
|  |   positions: Cartesian3[] = [] //要编辑的几个对象坐标
 | ||||||
|  |   controlPointsID: string[] = [] | ||||||
|  |   controlPoint: PointEntity | null = null | ||||||
|  |   clickedGeometry: Entity | null = null | ||||||
|  |   clickDownPosition: Cartesian3 | null = null | ||||||
|  |   moveSelectedPoint: PointEntity | null = null | ||||||
|  |   bDrag: boolean = false //拖动标识
 | ||||||
|  |   bLongClick: boolean = false //长按标识
 | ||||||
|  |   clickTimeout: any | ||||||
|  | 
 | ||||||
|  |   constructor(viewer: Viewer, editGeometry: Entity) { | ||||||
|  |     this.viewer = viewer | ||||||
|  |     this.editHandler = new ScreenSpaceEventHandler(this.viewer.scene.canvas) | ||||||
|  |     this.geometry = editGeometry | ||||||
|  |     this.positions = editGeometry.polyline?.positions?.getValue( | ||||||
|  |       this.viewer.clock.currentTime, | ||||||
|  |     ) | ||||||
|  |     this.oldPositions = this.positions | ||||||
|  |     // 创建控制点
 | ||||||
|  |     this.positions.forEach((value, index) => { | ||||||
|  |       this.createPoint(value, index) | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |   public start() { | ||||||
|  |     this.editHandler.setInputAction( | ||||||
|  |       this.leftDownClickCallBack, | ||||||
|  |       ScreenSpaceEventType.LEFT_DOWN, | ||||||
|  |     ) | ||||||
|  |     this.editHandler.setInputAction( | ||||||
|  |       this.moveCallBack, | ||||||
|  |       ScreenSpaceEventType.MOUSE_MOVE, | ||||||
|  |     ) | ||||||
|  |     this.editHandler.setInputAction( | ||||||
|  |       this.leftUpClickCallBack, | ||||||
|  |       ScreenSpaceEventType.LEFT_UP, | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |   //左键点击回调
 | ||||||
|  |   private leftClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     const pickedObject = this.viewer.scene.pick(event.position) | ||||||
|  |     // 点中控制点
 | ||||||
|  |     if ( | ||||||
|  |       defined(pickedObject) && | ||||||
|  |       defined(pickedObject.id) && | ||||||
|  |       pickedObject.id.point instanceof PointGraphics | ||||||
|  |     ) { | ||||||
|  |       console.log('You clicked a point entity.') | ||||||
|  |       this.controlPoint = pickedObject.id | ||||||
|  |       console.log(this.controlPoint?.subId) | ||||||
|  |       this.bDrag = true | ||||||
|  |       this.forbidDrawWorld(true) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //左键按下回调
 | ||||||
|  |   private leftDownClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     // 清除可能已经设置的单击定时器
 | ||||||
|  |     clearTimeout(this.clickTimeout) | ||||||
|  |     // 判断是不是长按
 | ||||||
|  |     this.clickTimeout = setTimeout(() => { | ||||||
|  |       this.bLongClick = true | ||||||
|  |     }, 100) | ||||||
|  |     const pickedObject = this.viewer.scene.pick(event.position) | ||||||
|  |     //点中实体对象
 | ||||||
|  |     if (defined(pickedObject) && defined(pickedObject.id)) { | ||||||
|  |       // 记录点击的几何对象及位置
 | ||||||
|  |       this.clickedGeometry = pickedObject.id | ||||||
|  |       this.clickDownPosition = this.viewer.scene.pickPosition(event.position) | ||||||
|  |       // // 判断是否同一实体
 | ||||||
|  |       // if (this.geometry != pickedObject.id) {
 | ||||||
|  |       //   this.geometry = pickedObject.id
 | ||||||
|  |       //   if (
 | ||||||
|  |       //     pickedObject instanceof PolylineGraphics &&
 | ||||||
|  |       //     pickedObject.positions
 | ||||||
|  |       //   ) {
 | ||||||
|  |       //     this.oldPositions = this.geometry!.polyline!.positions?.getValue(
 | ||||||
|  |       //       this.viewer.clock.currentTime,
 | ||||||
|  |       //     )
 | ||||||
|  |       //   }
 | ||||||
|  |       // }
 | ||||||
|  |       // 点中控制点
 | ||||||
|  |       if (pickedObject.id.point instanceof PointGraphics) { | ||||||
|  |         console.log('You clicked a point entity.') | ||||||
|  |         this.controlPoint = pickedObject.id | ||||||
|  |         console.log(this.controlPoint?.subId) | ||||||
|  |         this.bDrag = true | ||||||
|  |         this.forbidDrawWorld(true) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //移动回调
 | ||||||
|  |   private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { | ||||||
|  |     const pickedObject = this.viewer.scene.pick(event.endPosition) | ||||||
|  |     // 悬停控制点放大
 | ||||||
|  |     if ( | ||||||
|  |       pickedObject && | ||||||
|  |       pickedObject.id && | ||||||
|  |       pickedObject.id.point instanceof PointGraphics | ||||||
|  |     ) { | ||||||
|  |       if (pickedObject.id.point instanceof PointGraphics) { | ||||||
|  |         if ( | ||||||
|  |           this.moveSelectedPoint == null || | ||||||
|  |           this.moveSelectedPoint.id !== pickedObject.id.id | ||||||
|  |         ) { | ||||||
|  |           this.moveSelectedPoint = pickedObject.id | ||||||
|  |           this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( | ||||||
|  |             this.moveSelectedPoint!.options.pixelSize! + 2, | ||||||
|  |           ) | ||||||
|  |           // console.log(this.moveSelectedPoint)
 | ||||||
|  |         } | ||||||
|  |         this.viewer.scene.requestRender() //刷新
 | ||||||
|  |       } | ||||||
|  |     } else { | ||||||
|  |       // 离开控制点恢复原始大小
 | ||||||
|  |       if (this.moveSelectedPoint) { | ||||||
|  |         this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( | ||||||
|  |           this.moveSelectedPoint!.options.pixelSize! - 2, | ||||||
|  |         ) | ||||||
|  |         this.moveSelectedPoint = null | ||||||
|  |         this.viewer.scene.requestRender() //刷新
 | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!this.controlPoint || !this.bDrag) return | ||||||
|  |     console.log('************************left down') | ||||||
|  |     const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) | ||||||
|  |     if (cartesian3) { | ||||||
|  |       // 修改节点坐标
 | ||||||
|  |       this.modifyPoint(cartesian3, this.controlPoint.subId) | ||||||
|  |       // this.geometry?.modifyPoint(cartesian3, this.controlPoint.subId)
 | ||||||
|  |       this.viewer.scene.requestRender() //刷新
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   //左键松开回调
 | ||||||
|  |   private leftUpClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     clearTimeout(this.clickTimeout) | ||||||
|  |     // 单击添加点
 | ||||||
|  |     if ( | ||||||
|  |       !this.bLongClick && | ||||||
|  |       this.clickedGeometry?.polyline instanceof PolylineGraphics | ||||||
|  |     ) { | ||||||
|  |       console.log('点中线,加点') | ||||||
|  |       this.addPoint() | ||||||
|  |     } | ||||||
|  |     this.bLongClick = false | ||||||
|  |     this.bDrag = false | ||||||
|  |     this.forbidDrawWorld(false) | ||||||
|  |   } | ||||||
|  |   // 左键双击回调
 | ||||||
|  |   private leftDoubleClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     // this.geometry.
 | ||||||
|  |   } | ||||||
|  |   // Viewer操作控制
 | ||||||
|  |   forbidDrawWorld(isForbid: boolean) { | ||||||
|  |     this.viewer.scene.screenSpaceCameraController.enableRotate = !isForbid | ||||||
|  |     this.viewer.scene.screenSpaceCameraController.enableTilt = !isForbid | ||||||
|  |     this.viewer.scene.screenSpaceCameraController.enableTranslate = !isForbid | ||||||
|  |     this.viewer.scene.screenSpaceCameraController.enableInputs = !isForbid | ||||||
|  |   } | ||||||
|  |   // 添加点
 | ||||||
|  |   addPoint() { | ||||||
|  |     for (let i = 0; i < this.positions.length - 1; ++i) { | ||||||
|  |       if ( | ||||||
|  |         isOnLineSegment( | ||||||
|  |           this.positions[i], | ||||||
|  |           this.positions[i + 1], | ||||||
|  |           this.clickDownPosition!, | ||||||
|  |         ) | ||||||
|  |       ) { | ||||||
|  |         // 修改线坐标
 | ||||||
|  |         const pt = getClosestPoint( | ||||||
|  |           this.positions[i], | ||||||
|  |           this.positions[i + 1], | ||||||
|  |           this.clickDownPosition!, | ||||||
|  |         ) | ||||||
|  |         this.positions.splice(i + 1, 0, pt) | ||||||
|  |         // 新建控制点
 | ||||||
|  |         this.createPoint(pt, i + 1) | ||||||
|  |         // 修改控制点的subid
 | ||||||
|  |         for (let index = i + 2; index < this.controlPointsID.length; ++index) { | ||||||
|  |           const point = this.geometry.entityCollection.getById( | ||||||
|  |             this.controlPointsID[index], | ||||||
|  |           ) as PointEntity | ||||||
|  |           point!.subId = point!.subId + 1 | ||||||
|  |         } | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   /** | ||||||
|  |    * 修改某点的坐标 | ||||||
|  |    * @param pos 修改点的坐标 | ||||||
|  |    * @param index 修改点的位置 | ||||||
|  |    */ | ||||||
|  |   modifyPoint(pos: Cartesian3, index: number) { | ||||||
|  |     // 修改线坐标
 | ||||||
|  |     this.positions.splice(index, 1, pos) | ||||||
|  |     // 修改控制点坐标
 | ||||||
|  |     this.controlPoint!.position = new ConstantPositionProperty(pos) | ||||||
|  |   } | ||||||
|  |   /** | ||||||
|  |    * 新加一个点 | ||||||
|  |    * @param pos 点的坐标 | ||||||
|  |    * @param index 插入的位置,0起步 | ||||||
|  |    */ | ||||||
|  |   createPoint(pos: Cartesian3, index: number) { | ||||||
|  |     // if (this.geometry) {
 | ||||||
|  |     const point = new PointEntity(pos) | ||||||
|  |     point.parent = this.geometry | ||||||
|  |     point.subId = index | ||||||
|  |     this.geometry.entityCollection.add(point) | ||||||
|  |     this.controlPointsID.splice(index, 0, point.id) | ||||||
|  |     // }
 | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -0,0 +1,185 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-15 08:43:26 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-03-26 14:20:32 | ||||||
|  |  * @FilePath: \GCSMap\src\utils\drawer.ts | ||||||
|  |  * @Description: 矢量要素绘制工具类 | ||||||
|  |  */ | ||||||
|  | import { | ||||||
|  |   Viewer, | ||||||
|  |   ScreenSpaceEventHandler, | ||||||
|  |   ScreenSpaceEventType, | ||||||
|  |   CustomDataSource, | ||||||
|  |   Cartesian3, | ||||||
|  |   CallbackProperty, | ||||||
|  |   PolygonHierarchy, | ||||||
|  |   Color, | ||||||
|  | } from 'cesium' | ||||||
|  | import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' | ||||||
|  | import { | ||||||
|  |   PointEntity, | ||||||
|  |   PolylineEntity, | ||||||
|  |   PolygonEntity, | ||||||
|  | } from '@/utils/map/geometry' | ||||||
|  | class Drawer { | ||||||
|  |   viewer: Viewer | ||||||
|  |   type: string | ||||||
|  |   handler: ScreenSpaceEventHandler | ||||||
|  |   layer: CustomDataSource | ||||||
|  |   polyline: PolylineEntity | null | ||||||
|  |   polygon: PolygonEntity | null | ||||||
|  |   positions: Cartesian3[] = [] | ||||||
|  |   n_Points: number | ||||||
|  |   bMove: boolean | ||||||
|  |   clickTimeout: any | ||||||
|  |   constructor(viewer: Viewer, type: string) { | ||||||
|  |     this.viewer = viewer | ||||||
|  |     this.type = type | ||||||
|  |     this.handler = new ScreenSpaceEventHandler(this.viewer.canvas) | ||||||
|  |     this.polyline = null | ||||||
|  |     this.polygon = null | ||||||
|  |     this.n_Points = 0 | ||||||
|  |     this.bMove = false | ||||||
|  |     this.positions = [] | ||||||
|  |     this.clickTimeout = null | ||||||
|  |     if (viewer.dataSources.getByName(type).length === 0) { | ||||||
|  |       this.layer = new CustomDataSource(type) | ||||||
|  |       viewer.dataSources.add(this.layer) | ||||||
|  |     } else { | ||||||
|  |       this.layer = viewer.dataSources.getByName(type)[0] | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // 开始绘制
 | ||||||
|  |   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, | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |   public end() { | ||||||
|  |     this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) | ||||||
|  |   } | ||||||
|  |   //左单击回调事件
 | ||||||
|  |   private leftClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     // 清除可能已经设置的单击定时器
 | ||||||
|  |     clearTimeout(this.clickTimeout) | ||||||
|  |     console.log('**************************** click') | ||||||
|  |     // 设置一个新的定时器,用于判断是单击还是双击
 | ||||||
|  |     this.clickTimeout = setTimeout(() => { | ||||||
|  |       console.log('**************************** run') | ||||||
|  |       const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) | ||||||
|  |       if (cartesian3 != undefined) { | ||||||
|  |         if (this.bMove) { | ||||||
|  |           this.positions.pop() | ||||||
|  |           this.bMove = false | ||||||
|  |         } | ||||||
|  |         this.positions.push(cartesian3) | ||||||
|  |         this.createGeometry(this.type) | ||||||
|  |         // 创建控制点
 | ||||||
|  |         const point = new PointEntity( | ||||||
|  |           this.positions[this.positions.length - 1], | ||||||
|  |           { | ||||||
|  |             color: Color.WHITE, | ||||||
|  |             pixelSize: 6, | ||||||
|  |           }, | ||||||
|  |         ) | ||||||
|  |         point.parent = this.polygon! | ||||||
|  |         this.layer.entities.add(point) | ||||||
|  | 
 | ||||||
|  |         this.viewer.scene.requestRender() //刷新
 | ||||||
|  |       } | ||||||
|  |     }, 100) | ||||||
|  |   } | ||||||
|  |   // 移动回调事件
 | ||||||
|  |   private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { | ||||||
|  |     const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) | ||||||
|  |     if (cartesian3 != undefined) { | ||||||
|  |       if (this.positions.length >= 1) { | ||||||
|  |         if (!this.bMove) { | ||||||
|  |           this.positions.push(cartesian3) | ||||||
|  |           this.bMove = true | ||||||
|  |         } else { | ||||||
|  |           this.positions[this.positions.length - 1] = cartesian3 | ||||||
|  |         } | ||||||
|  |         if (this.type === 'Polygon') { | ||||||
|  |           // 多边形创建临时线
 | ||||||
|  |           if (this.positions.length === 2) { | ||||||
|  |             this.createGeometry('Polyline') | ||||||
|  |           } | ||||||
|  |           if (this.positions.length > 2) { | ||||||
|  |             this.polyline!.show = false | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |       this.viewer.scene.requestRender() //刷新
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // 左双击回调事件
 | ||||||
|  |   private leftDoubleClickCallBack = ( | ||||||
|  |     event: ScreenSpaceEventHandler.PositionedEvent, | ||||||
|  |   ) => { | ||||||
|  |     // 清除可能已经设置的单击定时器
 | ||||||
|  |     clearTimeout(this.clickTimeout) | ||||||
|  |     console.log('**************************** double click') | ||||||
|  |     const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) | ||||||
|  |     if (cartesian3 != undefined) { | ||||||
|  |       this.positions.pop() | ||||||
|  |       this.positions.push(cartesian3) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     this.clearEvent() | ||||||
|  |     console.log('end:' + this.positions.length.toString()) | ||||||
|  |     console.log(this.positions) | ||||||
|  |   } | ||||||
|  |   clearEvent() { | ||||||
|  |     this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK) | ||||||
|  |     this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE) | ||||||
|  |     this.handler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) | ||||||
|  |   } | ||||||
|  |   // 创建几何体
 | ||||||
|  |   createGeometry(type: string) { | ||||||
|  |     switch (type) { | ||||||
|  |       case 'Polyline': | ||||||
|  |         if (this.polyline == null) { | ||||||
|  |           this.polyline = new PolylineEntity( | ||||||
|  |             new CallbackProperty(() => { | ||||||
|  |               return this.positions | ||||||
|  |             }, false), | ||||||
|  |           ) | ||||||
|  |           this.layer.entities.add(this.polyline) | ||||||
|  |           // this.viewer.entities.add(this.polyline)
 | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       case 'Polygon': | ||||||
|  |         if (this.polygon == null) { | ||||||
|  |           this.polygon = new PolygonEntity( | ||||||
|  |             new CallbackProperty(() => { | ||||||
|  |               return new PolygonHierarchy(this.positions) | ||||||
|  |             }, false), | ||||||
|  |           ) | ||||||
|  |           this.layer.entities.add(this.polygon) | ||||||
|  |           // this.viewer.entities.add(this.polygon)
 | ||||||
|  |           console.log('Polygon created!') | ||||||
|  |         } | ||||||
|  |         break | ||||||
|  |       default: | ||||||
|  |         break | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { Drawer } | ||||||
| @ -1,134 +0,0 @@ | |||||||
| /* |  | ||||||
|  * @Author: cbwu 504-wuchengbo@htsdfp.com |  | ||||||
|  * @Date: 2024-03-20 08:55:59 |  | ||||||
|  * @LastEditors: cbwu |  | ||||||
|  * @LastEditTime: 2024-03-26 09:00:46 |  | ||||||
|  * @Description:几何类型类 |  | ||||||
|  */ |  | ||||||
| import { |  | ||||||
|   Entity, |  | ||||||
|   Cartesian3, |  | ||||||
|   Color, |  | ||||||
|   PrimitiveCollection, |  | ||||||
|   PointPrimitiveCollection, |  | ||||||
|   PolylineGeometry, |  | ||||||
|   PointGraphics, |  | ||||||
|   Property, |  | ||||||
|   PolylineGraphics, |  | ||||||
|   PolygonGraphics, |  | ||||||
| } from 'cesium' |  | ||||||
| type EntityOptions = { |  | ||||||
|   id?: string |  | ||||||
|   name?: string |  | ||||||
|   show?: boolean |  | ||||||
|   pixelSize?: number |  | ||||||
|   color?: Color |  | ||||||
|   fillColor?: Color |  | ||||||
|   fill?: boolean |  | ||||||
|   width?: number |  | ||||||
|   outlineWidth?: number |  | ||||||
| } |  | ||||||
| // 点
 |  | ||||||
| class PointEntity extends Entity { |  | ||||||
|   static id: number = 0 |  | ||||||
|   options: EntityOptions = { |  | ||||||
|     id: 'Point' + String(PointEntity.id), |  | ||||||
|     name: 'Point' + String(PointEntity.id + 1), |  | ||||||
|     show: true, |  | ||||||
|     pixelSize: 10, |  | ||||||
|     color: Color.GREEN, |  | ||||||
|     outlineWidth: 0, |  | ||||||
|   } |  | ||||||
|   constructor(position: Cartesian3, options?: EntityOptions) { |  | ||||||
|     super({ |  | ||||||
|       // id: options?.id || String(PointEntity.id),
 |  | ||||||
|       position: position, |  | ||||||
|     }) |  | ||||||
|     this.options = { ...this.options, ...options } |  | ||||||
|     this.name = this.options.name |  | ||||||
|     this.point = new PointGraphics({ ...this.options }) |  | ||||||
|     PointEntity.id++ |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| // 线
 |  | ||||||
| class PolylineEntity extends Entity { |  | ||||||
|   static id: number = 0 |  | ||||||
|   options: EntityOptions = { |  | ||||||
|     id: 'Polyline' + String(PolylineEntity.id), |  | ||||||
|     name: 'Polyline' + String(PolylineEntity.id + 1), |  | ||||||
|     show: true, |  | ||||||
|     width: 2, |  | ||||||
|     color: Color.GREEN, |  | ||||||
|   } |  | ||||||
|   constructor(ptArr: Cartesian3[] | Property, options?: EntityOptions) { |  | ||||||
|     super({ |  | ||||||
|       // id: options?.id || String(PolylineEntity.id),
 |  | ||||||
|     }) |  | ||||||
|     this.options = { ...this.options, ...options } |  | ||||||
|     this.name = this.options.name |  | ||||||
|     this.polyline = new PolylineGraphics({ |  | ||||||
|       positions: ptArr, |  | ||||||
|       show: this.options.show, |  | ||||||
|       width: this.options.width, |  | ||||||
|       material: this.options.color, |  | ||||||
|     }) |  | ||||||
|     PolylineEntity.id++ |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| // 多边形
 |  | ||||||
| class PolygonEntity extends Entity { |  | ||||||
|   static id: number = 0 |  | ||||||
|   options: EntityOptions = { |  | ||||||
|     id: 'Polygon' + String(PolygonEntity.id), |  | ||||||
|     name: 'Polygon' + String(PolygonEntity.id + 1), |  | ||||||
|     show: true, |  | ||||||
|     width: 2, |  | ||||||
|     color: Color.RED, |  | ||||||
|     fillColor: Color.RED.withAlpha(0.5), |  | ||||||
|     fill: true, |  | ||||||
|   } |  | ||||||
|   constructor(ptArr: Cartesian3[] | Property, options?: EntityOptions) { |  | ||||||
|     super({ |  | ||||||
|       // id: options?.id || String(PolygonEntity.id),
 |  | ||||||
|     }) |  | ||||||
|     this.options = { ...this.options, ...options } |  | ||||||
|     this.name = this.options.name |  | ||||||
|     this.polygon = new PolygonGraphics({ |  | ||||||
|       show: this.options.show, |  | ||||||
|       hierarchy: ptArr, |  | ||||||
|       material: this.options.fillColor, //填充颜色
 |  | ||||||
|       fill: this.options.fill, //是否填充
 |  | ||||||
|       outlineWidth: this.options.width, //线宽
 |  | ||||||
|       outlineColor: this.options.color, //线颜色
 |  | ||||||
|     }) |  | ||||||
|     PolygonEntity.id++ |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| // 线
 |  | ||||||
| class Polyline extends PrimitiveCollection { |  | ||||||
|   constructor(ptArr: Cartesian3[]) { |  | ||||||
|     super() |  | ||||||
|     this.add(this.createPoints(ptArr)) |  | ||||||
|     this.add(this.createPolyline(ptArr)) |  | ||||||
|     // this.id
 |  | ||||||
|   } |  | ||||||
|   private createPoints(posArr: Cartesian3[]) { |  | ||||||
|     const points = new PointPrimitiveCollection() |  | ||||||
|     for (const pos in posArr) { |  | ||||||
|       points.add({ |  | ||||||
|         position: pos, |  | ||||||
|         color: Color.RED, |  | ||||||
|         pixelSize: 10, |  | ||||||
|       }) |  | ||||||
|     } |  | ||||||
|     return points |  | ||||||
|   } |  | ||||||
|   private createPolyline(posArr: Cartesian3[]) { |  | ||||||
|     return new PolylineGeometry({ |  | ||||||
|       positions: posArr, |  | ||||||
|       width: 2, |  | ||||||
|       colors: new Array(posArr.length).fill(Color.fromCssColorString('green')), |  | ||||||
|     }) |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| export { PointEntity, Polyline, PolylineEntity, PolygonEntity } |  | ||||||
| @ -0,0 +1,69 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-28 16:35:33 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-03-30 22:06:23 | ||||||
|  |  * @Description: 封装的点几何类 | ||||||
|  |  */ | ||||||
|  | import { | ||||||
|  |   Entity, | ||||||
|  |   Cartesian3, | ||||||
|  |   Color, | ||||||
|  |   PointGraphics, | ||||||
|  |   PositionProperty, | ||||||
|  |   LabelGraphics, | ||||||
|  |   Cartesian2, | ||||||
|  |   CallbackProperty, | ||||||
|  |   Property, | ||||||
|  | } from 'cesium' | ||||||
|  | type EntityOptions = { | ||||||
|  |   id?: string | ||||||
|  |   name?: string | ||||||
|  |   show?: boolean | ||||||
|  |   pixelSize?: number | ||||||
|  |   outlineColor?: Color | ||||||
|  |   color?: Color | ||||||
|  |   fillColor?: Color | ||||||
|  |   fill?: boolean | ||||||
|  |   width?: number | ||||||
|  |   outlineWidth?: number | ||||||
|  |   text?: string | ||||||
|  |   font?: string | ||||||
|  |   pixelOffset?: Cartesian2 | ||||||
|  | } | ||||||
|  | // 点
 | ||||||
|  | class PointEntity extends Entity { | ||||||
|  |   static ID: number = 0 | ||||||
|  |   public subId: number = 0 //用于作为其他几何体的控制点时标记节点号
 | ||||||
|  |   options: EntityOptions = { | ||||||
|  |     id: 'Point' + String(PointEntity.ID), | ||||||
|  |     name: 'Point' + String(PointEntity.ID + 1), | ||||||
|  |     show: true, | ||||||
|  |     pixelSize: 10, | ||||||
|  |     color: Color.GREEN, | ||||||
|  |     outlineWidth: 0, | ||||||
|  |   } | ||||||
|  |   constructor(position: Cartesian3, options?: EntityOptions) { | ||||||
|  |     super({ | ||||||
|  |       position: position, | ||||||
|  |     }) | ||||||
|  |     this.options = { ...this.options, ...options } | ||||||
|  |     //点对象
 | ||||||
|  |     this.point = new PointGraphics({ | ||||||
|  |       pixelSize: this.options.pixelSize, | ||||||
|  |       color: this.options.color, | ||||||
|  |       outlineColor: this.options.outlineColor, | ||||||
|  |       outlineWidth: this.options.outlineWidth, | ||||||
|  |     }) | ||||||
|  |     // 标注对象
 | ||||||
|  |     this.label = new LabelGraphics({ | ||||||
|  |       text: this.options.text, | ||||||
|  |       font: this.options.font, | ||||||
|  |       pixelOffset: this.options.pixelOffset, | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     PointEntity.ID++ | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { PointEntity, type EntityOptions } | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | /* | ||||||
|  |  * @Author: cbwu 504-wuchengbo@htsdfp.com | ||||||
|  |  * @Date: 2024-03-28 16:49:02 | ||||||
|  |  * @LastEditors: cbwu | ||||||
|  |  * @LastEditTime: 2024-04-01 17:04:55 | ||||||
|  |  * @Description: 封装的Polyline类 | ||||||
|  |  */ | ||||||
|  | import { Entity, Cartesian3, Color, CallbackProperty } from 'cesium' | ||||||
|  | import { BaseGeometry } from './baseGeometry' | ||||||
|  | import { type EntityOptions } from './pointEntity' | ||||||
|  | export class PolylineEntity extends BaseGeometry { | ||||||
|  |   static ID: number = 0 | ||||||
|  |   //   positions: Cartesian3[] = []
 | ||||||
|  |   controlPointsID: string[] = [] | ||||||
|  |   options: EntityOptions = { | ||||||
|  |     // id: 'Polyline' + String(PolylineEntity.ID),
 | ||||||
|  |     name: 'Polyline' + String(PolylineEntity.ID + 1), | ||||||
|  |     show: true, | ||||||
|  |     width: 3, | ||||||
|  |     color: Color.GREEN, | ||||||
|  |   } | ||||||
|  |   constructor(ptArr: Cartesian3[], options?: EntityOptions) { | ||||||
|  |     super() | ||||||
|  |     this.options = { ...this.options, ...options } | ||||||
|  |     // console.log(this.options)
 | ||||||
|  |     this.positions = ptArr | ||||||
|  |     // console.log(this.positions)
 | ||||||
|  |     // 创建线实体对象
 | ||||||
|  |     this.geometry = new Entity({ | ||||||
|  |       name: this.options.name, | ||||||
|  |       polyline: { | ||||||
|  |         positions: new CallbackProperty(() => { | ||||||
|  |           return this.positions | ||||||
|  |         }, false), | ||||||
|  |         show: this.options.show, | ||||||
|  |         width: this.options.width, | ||||||
|  |         material: this.options.color, | ||||||
|  |       }, | ||||||
|  |     }) | ||||||
|  |     this.entities.add(this.geometry) | ||||||
|  |     // 添加控制点
 | ||||||
|  |     ptArr.forEach((pt, index) => { | ||||||
|  |       this.createPoint(pt, index) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     PolylineEntity.ID++ | ||||||
|  |   } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in New Issue