From eb3d03220c0028d15239321c1d8cfda536f3105d Mon Sep 17 00:00:00 2001 From: cbwu <504-wuchengbo@htsdfp.com> Date: Tue, 2 Apr 2024 14:16:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9EPolyline=E7=9A=84?= =?UTF-8?q?=E7=BB=98=E5=88=B6=E4=B8=8E=E7=BC=96=E8=BE=91(=E5=BE=85?= =?UTF-8?q?=E5=AE=8C=E5=96=84)=E3=80=82fix:=20window=E4=B8=8B=E7=9A=84Cesi?= =?UTF-8?q?um,Viewer=E5=AF=B9=E8=B1=A1=E6=94=B9=E6=88=90cesium,viewer?= =?UTF-8?q?=E5=B0=8F=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 - index.html | 7 + src/components/map/SceneViewer.vue | 20 +- src/global.d.ts | 6 +- src/utils/map/TDTProvider.ts | 11 +- src/utils/map/coordinate.ts | 23 ++- src/utils/map/draw/drawPoint.ts | 7 + src/utils/map/draw/drawPolyline.ts | 197 ++++++++++++++++++ src/utils/map/draw/editGeometry.ts | 249 +++++++++++++++++++++++ src/utils/map/draw/geometry.ts | 231 +++++++++++++++++++++ src/utils/map/drawer.ts | 185 +++++++++++++++++ src/utils/map/geocomputation.ts | 83 +++++++- src/utils/map/geometry.ts | 134 ------------ src/utils/map/geometry/baseGeometry.ts | 109 ++++++++++ src/utils/map/geometry/pointEntity.ts | 69 +++++++ src/utils/map/geometry/polylineEntity.ts | 48 +++++ src/utils/map/sceneViewer.ts | 9 +- 17 files changed, 1234 insertions(+), 156 deletions(-) create mode 100644 src/utils/map/draw/drawPoint.ts create mode 100644 src/utils/map/draw/drawPolyline.ts create mode 100644 src/utils/map/draw/editGeometry.ts create mode 100644 src/utils/map/draw/geometry.ts create mode 100644 src/utils/map/drawer.ts delete mode 100644 src/utils/map/geometry.ts create mode 100644 src/utils/map/geometry/baseGeometry.ts create mode 100644 src/utils/map/geometry/pointEntity.ts create mode 100644 src/utils/map/geometry/polylineEntity.ts diff --git a/README.md b/README.md index 35d49d0..1f13dad 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,6 @@ commit 提交信息时,必须是 **git commit -m 'fix: xxx'** 符合类型的 'build',//编译相关的修改,例如发布版本、对项目构建或者依赖的改动 ``` - - ## 地图库 - 地图采用开源的Cesium.js库,版本为1.108.注:不要随意升级版本,天地图三维地形服务目前只支持1.108,实测1.109也能用,更高版本则无法使用。 diff --git a/index.html b/index.html index 23a9f5e..d4f18e4 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,10 @@ +
diff --git a/src/components/map/SceneViewer.vue b/src/components/map/SceneViewer.vue index 5a99579..e7a0ccc 100644 --- a/src/components/map/SceneViewer.vue +++ b/src/components/map/SceneViewer.vue @@ -1,11 +1,17 @@ + diff --git a/src/global.d.ts b/src/global.d.ts index 3c68547..ec27446 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -4,11 +4,11 @@ import type { Cesium, Viewer } from 'cesium' // 扩展全局变量 declare global { // 定义全局Cesium类型 - const Cesium: Cesium + // const Cesium: Cesium // 允许扩展 Window interface Window { - Cesium: Cesium + cesium: Cesium CESIUM_BASE_URL: string - Viewer: Viewer + viewer: Viewer } } diff --git a/src/utils/map/TDTProvider.ts b/src/utils/map/TDTProvider.ts index 04f122c..28279ce 100644 --- a/src/utils/map/TDTProvider.ts +++ b/src/utils/map/TDTProvider.ts @@ -1,3 +1,10 @@ +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-07 16:04:55 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-02 14:01:22 + * @Description: + */ // 天地图影像服务 import { WebMapTileServiceImageryProvider, @@ -27,7 +34,7 @@ const subdomains = ['0', '1', '2', '3', '4', '5', '6', '7'] /** * 获取天地图影像服务 * @param layerType :影像类型 - * @param projectionType :投影类型,注WGS84下有问题 + * @param projectionType :投影类型 * @param minimumLevel :最小缩放级别 * @param maximumLevel :最大缩放级别 * @returns :ImageryProvider @@ -79,7 +86,7 @@ export function getTDTTerrainProvider() { terrainUrls.push(url) } - const provider = new Cesium.GeoTerrainProvider({ + const provider = new window.cesium.GeoTerrainProvider({ urls: terrainUrls, }) return provider diff --git a/src/utils/map/coordinate.ts b/src/utils/map/coordinate.ts index eba3975..d98bf59 100644 --- a/src/utils/map/coordinate.ts +++ b/src/utils/map/coordinate.ts @@ -2,12 +2,12 @@ * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-22 09:11:54 * @LastEditors: cbwu - * @LastEditTime: 2024-03-26 13:33:42 + * @LastEditTime: 2024-04-01 09:21:17 * @Description: 坐标系转化 */ -import { Cartesian2, Viewer, Math, Cartographic } from 'cesium' +import { Cartesian2, Viewer, Math, Cartographic, Cartesian3 } from 'cesium' /** - * 屏幕坐标转笛卡尔坐标 + * 屏幕坐标转笛卡尔坐标,注:获取的是地表坐标 * @param viewer * @param windowPosition :屏幕二维坐标 * @returns :笛卡尔坐标 @@ -27,11 +27,22 @@ function cartesian2ToCartesian3(viewer: Viewer, windowPosition: Cartesian2) { function cartesian2ToWGS84(viewer: Viewer, windowPosition: Cartesian2) { const cartesian3 = cartesian2ToCartesian3(viewer, windowPosition) if (cartesian3 != undefined) { - const cartographic = Cartographic.fromCartesian(cartesian3) + return cartesian3ToWGS84(cartesian3) + } else return [] +} +/** + * 笛卡尔坐标转WGS84坐标 + * @param pos 笛卡尔坐标 + * @returns 经纬度坐标 + */ +function cartesian3ToWGS84(pos: Cartesian3) { + if (pos) { + const cartographic = Cartographic.fromCartesian(pos) const lon = Math.toDegrees(cartographic.longitude) // 经度 const lat = Math.toDegrees(cartographic.latitude) // 纬度 const alt = cartographic.height // 高度 return [lon, lat, alt] - } else return [] + } + return [] } -export { cartesian2ToCartesian3, cartesian2ToWGS84 } +export { cartesian2ToCartesian3, cartesian2ToWGS84, cartesian3ToWGS84 } diff --git a/src/utils/map/draw/drawPoint.ts b/src/utils/map/draw/drawPoint.ts new file mode 100644 index 0000000..4d7b7b6 --- /dev/null +++ b/src/utils/map/draw/drawPoint.ts @@ -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: 绘制点类 + */ diff --git a/src/utils/map/draw/drawPolyline.ts b/src/utils/map/draw/drawPolyline.ts new file mode 100644 index 0000000..743522a --- /dev/null +++ b/src/utils/map/draw/drawPolyline.ts @@ -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, + }, + }) + } +} diff --git a/src/utils/map/draw/editGeometry.ts b/src/utils/map/draw/editGeometry.ts new file mode 100644 index 0000000..1467e63 --- /dev/null +++ b/src/utils/map/draw/editGeometry.ts @@ -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) + // } + } +} diff --git a/src/utils/map/draw/geometry.ts b/src/utils/map/draw/geometry.ts new file mode 100644 index 0000000..97fd0fc --- /dev/null +++ b/src/utils/map/draw/geometry.ts @@ -0,0 +1,231 @@ +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-28 09:14:45 + * @LastEditors: cbwu + * @LastEditTime: 2024-03-28 17:40:14 + * @Description: 封装的几何类型类 + */ +import { + Entity, + EntityCollection, + Cartesian3, + Color, + PrimitiveCollection, + PointPrimitiveCollection, + PolylineGeometry, + PointGraphics, + Property, + PositionProperty, + LabelGraphics, + PolylineGraphics, + PolygonGraphics, + Cartesian2, + ConstantPositionProperty, + CallbackProperty, +} 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: PositionProperty | 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++ + } +} +// 线 +class PolylineEntity extends EntityCollection { + static ID: number = 0 + positions: Cartesian3[] = [] + controlPointsID: string[] = [] + options: EntityOptions = { + id: 'Polyline' + String(PolylineEntity.ID), + name: 'Polyline' + String(PolylineEntity.ID + 1), + show: true, + width: 2, + color: Color.GREEN, + } + constructor(ptArr: Cartesian3[], options?: EntityOptions) { + super() + this.options = { ...this.options, ...options } + this.positions = ptArr + const polyline = 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.add(polyline) + ptArr.forEach((pt, index) => { + this.createPoint(pt, index) + }) + + PolylineEntity.ID++ + } + /** + * 新增一个节点,默认插入在尾部, + * @param pos 点坐标 + * @param index 插入的位置,0起步 + */ + public addPoint(pos: Cartesian3, index: number = -1) { + if (index === -1) { + //插入尾部 + this.positions.push(pos) + this.createPoint(pos, this.positions.length - 1) + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 0, pos) + this.createPoint(pos, index) + } else { + return + } + } + /** + * 移除点 + * @param index 移除点的位置 + * @returns + */ + public removePoint(index: number = -1) { + if (index === -1 || index === this.positions.length - 1) { + //移除尾部元素 + this.positions.pop() + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1) + this.removeById(this.controlPointsID[index]) + this.controlPointsID.splice(index, 1) + } else { + return + } + } + /** + * 修改某点的坐标 + * @param pos 修改点的坐标 + * @param index 修改点的位置 + */ + public modifyPoint(pos: Cartesian3, index: number) { + if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1, pos) + //修改控制点坐标 + const point = this.getById(this.controlPointsID[index]) + if (point) { + point.position = new ConstantPositionProperty(pos) + } + } + } + /** + * 新加一个点 + * @param pos 点的坐标 + * @param index 插入的位置,0起步 + */ + createPoint(pos: Cartesian3, index: number) { + const point = new PointEntity(pos) + point.subId = index + 1 + this.add(point) + this.controlPointsID.splice(index, 0, point.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 } diff --git a/src/utils/map/drawer.ts b/src/utils/map/drawer.ts new file mode 100644 index 0000000..8015732 --- /dev/null +++ b/src/utils/map/drawer.ts @@ -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 } diff --git a/src/utils/map/geocomputation.ts b/src/utils/map/geocomputation.ts index d336bb7..1569ba6 100644 --- a/src/utils/map/geocomputation.ts +++ b/src/utils/map/geocomputation.ts @@ -2,6 +2,87 @@ * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-22 15:42:49 * @LastEditors: cbwu - * @LastEditTime: 2024-03-22 15:43:23 + * @LastEditTime: 2024-04-01 14:05:43 * @Description: 地理计算 */ +import { Cartesian3, Math as Cesium_Math } from 'cesium' +/** + * 计算空间中一点到一条直线的最短距离的交点(在不考虑地球曲率的情况下) + * @param lineStart 直线的起点:[longitude1, latitude1, height1] + * @param lineEnd 直线的终点:[longitude2, latitude2, height2] + * @param point 空间中的点:[[longitude3, latitude3, height3]] + * @returns 最近的交点 + */ +function getClosestPoint( + lineStart: Cartesian3, + lineEnd: Cartesian3, + point: Cartesian3, +): Cartesian3 { + // 计算直线方向向量 + const lineDirection = new Cartesian3() + Cartesian3.subtract(lineEnd, lineStart, lineDirection) + Cartesian3.normalize(lineDirection, lineDirection) + + // 计算点到直线起点的向量 + const pointToStart = new Cartesian3() + Cartesian3.subtract(point, lineStart, pointToStart) + + // 计算投影长度,即点到直线的向量在直线方向向量上的分量长度 + const projectionLength = Cartesian3.dot(pointToStart, lineDirection) + + // 使用标量乘法和向量加法确定交点 + const closestPoint = new Cartesian3() + Cartesian3.multiplyByScalar(lineDirection, projectionLength, closestPoint) + Cartesian3.add(lineStart, closestPoint, closestPoint) + return closestPoint +} + +/** + * 判断一个点是否在直线上(在不考虑地球曲率的情况下) + * @param lineStart 直线的起点:[longitude1, latitude1, height1] + * @param lineEnd 直线的起点:[longitude2, latitude2, height2] + * @param pointToCheck 直线的起点:[longitude3, latitude3, height3] + * @param tolerance 容差 + * @returns 是否在线段上 + */ +function isOnLineSegment( + lineStart: Cartesian3, + lineEnd: Cartesian3, + pointToCheck: Cartesian3, + tolerance: number = Cesium_Math.EPSILON1, +): boolean { + const dist_AP = Cartesian3.distance(lineStart, pointToCheck) + const dist_BP = Cartesian3.distance(lineEnd, pointToCheck) + const dist_AB = Cartesian3.distance(lineStart, lineEnd) + + const isCollinear = Math.abs(dist_AP + dist_BP - dist_AB) < tolerance + return isCollinear + /* + const startToEnd = new Cartesian3() + const startToPoint = new Cartesian3() + const endToPoint = new Cartesian3() + + // 计算向量 + Cartesian3.subtract(lineEnd, lineStart, startToEnd) + Cartesian3.subtract(pointToCheck, lineStart, startToPoint) + Cartesian3.subtract(pointToCheck, lineEnd, endToPoint) + + // 判断共线 + const cross = Cartesian3.cross(startToEnd, startToPoint, new Cartesian3()) + console.log('cross:' + Cartesian3.magnitude(cross).toString()) + // Math.EPSILON6 是一个非常小的值,用来防止浮点数计算的误差 + const isCollinear = Cartesian3.magnitude(cross) < tolerance + + // 判断点是否在线段之间 + let isBetween = false + if (isCollinear) { + const dotProduct1 = Cartesian3.dot(startToEnd, startToPoint) + const dotProduct2 = Cartesian3.dot(startToEnd, endToPoint) + isBetween = dotProduct1 >= 0 && dotProduct2 <= 0 + } + return isBetween + */ +} + + +export { getClosestPoint, isOnLineSegment } diff --git a/src/utils/map/geometry.ts b/src/utils/map/geometry.ts deleted file mode 100644 index 5199560..0000000 --- a/src/utils/map/geometry.ts +++ /dev/null @@ -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 } diff --git a/src/utils/map/geometry/baseGeometry.ts b/src/utils/map/geometry/baseGeometry.ts new file mode 100644 index 0000000..3a1804b --- /dev/null +++ b/src/utils/map/geometry/baseGeometry.ts @@ -0,0 +1,109 @@ +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-03-28 16:22:58 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-02 14:09:15 + * @Description: 几何类抽象基类 + */ +import { + // EntityCollection, + Entity, + Cartesian3, + Color, + ConstantPositionProperty, + CustomDataSource, +} from 'cesium' +import { PointEntity, EntityOptions } from './pointEntity' +export abstract class BaseGeometry extends CustomDataSource { + static ID: number + // abstract subId: number + geometry: Entity | null = null + positions: Cartesian3[] = [] + controlPointsID: string[] = [] //存储 + options: EntityOptions = { + // id: 'Point' + String(PointEntity.ID), + // name: 'Point' + String(PointEntity.ID + 1), + show: true, + // pixelSize: 10, + width: 2, + color: Color.GREEN, + outlineWidth: 0, + } + + constructor() { + super() + } + /** + * 新增一个节点,默认插入在尾部, + * @param pos 点坐标 + * @param index 插入的位置,0起步 + */ + public addPoint(pos: Cartesian3, index: number = -1) { + if (index === -1) { + //插入尾部 + this.positions.push(pos) + // console.log(this.positions.length) + this.createPoint(pos, this.positions.length - 1) + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 0, pos) + this.createPoint(pos, index) + } else { + return + } + } + /** + * 移除点 + * @param index 移除点的位置 + * @returns + */ + public removePoint(index: number = -1) { + if (index === -1 || index === this.positions.length - 1) { + //移除尾部元素 + this.positions.pop() + } else if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1) + this.entities.removeById(this.controlPointsID[index]) + this.controlPointsID.splice(index, 1) + } else { + return + } + } + /** + * 修改某点的坐标 + * @param pos 修改点的坐标 + * @param index 修改点的位置 + */ + public modifyPoint(pos: Cartesian3, index: number) { + if (index >= 0 && index < this.positions.length) { + this.positions.splice(index, 1, pos) + //修改控制点坐标 + const point = this.entities.getById(this.controlPointsID[index]) + if (point) { + point.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.entities.add(point) + this.controlPointsID.splice(index, 0, point.id) + // } + } + /** + * 清空所有控制点 + */ + removeControlPoints() { + this.controlPointsID.forEach((value) => { + this.entities.removeById(value) + }) + this.controlPointsID = [] + } +} diff --git a/src/utils/map/geometry/pointEntity.ts b/src/utils/map/geometry/pointEntity.ts new file mode 100644 index 0000000..ec8878b --- /dev/null +++ b/src/utils/map/geometry/pointEntity.ts @@ -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 } diff --git a/src/utils/map/geometry/polylineEntity.ts b/src/utils/map/geometry/polylineEntity.ts new file mode 100644 index 0000000..026ea28 --- /dev/null +++ b/src/utils/map/geometry/polylineEntity.ts @@ -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++ + } +} diff --git a/src/utils/map/sceneViewer.ts b/src/utils/map/sceneViewer.ts index 3144858..2a4f530 100644 --- a/src/utils/map/sceneViewer.ts +++ b/src/utils/map/sceneViewer.ts @@ -2,7 +2,7 @@ * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-13 09:32:21 * @LastEditors: cbwu - * @LastEditTime: 2024-03-26 13:27:27 + * @LastEditTime: 2024-04-02 13:49:26 * @Description: */ // Viewer初始化 @@ -13,6 +13,7 @@ import { RequestScheduler, SceneMode, buildModuleUrl, + ScreenSpaceEventType, } from 'cesium' //离线地球底图 @@ -49,6 +50,8 @@ function initViewer(container: string | Element): Viewer { //去除cesium logo,隐藏版本信息 const creditContainer = viewer.cesiumWidget.creditContainer as HTMLDivElement creditContainer.style.display = 'none' + // 开启深度检测 + viewer.scene.globe.depthTestAgainstTerrain = true // 水雾特效 viewer.scene.globe.showGroundAtmosphere = true // 设置更高的缩放惯性以使缩放操作更平滑 @@ -58,10 +61,10 @@ function initViewer(container: string | Element): Viewer { viewer.scene.screenSpaceCameraController.maximumZoomDistance = 20000000 //相机高度的最大值 // 去掉entity的点击事件(双击、单击) viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, + ScreenSpaceEventType.LEFT_DOUBLE_CLICK, ) viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( - Cesium.ScreenSpaceEventType.LEFT_CLICK, + ScreenSpaceEventType.LEFT_CLICK, ) return viewer }