From 894d54145a403dc7a154c9313762beb1356d1d79 Mon Sep 17 00:00:00 2001 From: cbwu <504-wuchengbo@htsdfp.com> Date: Wed, 24 Apr 2024 16:53:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84=E4=B8=89=E7=BB=B4?= =?UTF-8?q?=E8=88=AA=E7=BA=BF=E7=BC=96=E8=BE=91=E5=8A=9F=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/map/SceneViewer.vue | 4 +- src/utils/map/TDTProvider.ts | 2 +- src/utils/map/draw/drawPolyline.ts | 79 +++++-- src/utils/map/draw/editGeometry.ts | 360 +++++++++++++++++++++-------- src/utils/map/geocomputation.ts | 77 +++--- src/utils/map/mouseStyle.ts | 23 ++ 6 files changed, 405 insertions(+), 140 deletions(-) create mode 100644 src/utils/map/mouseStyle.ts diff --git a/src/components/map/SceneViewer.vue b/src/components/map/SceneViewer.vue index b8b0259..fe0b21c 100644 --- a/src/components/map/SceneViewer.vue +++ b/src/components/map/SceneViewer.vue @@ -67,9 +67,9 @@ onMounted(() => { // 挂载在window,供全局组件共享 window.viewer = viewer - inputGeoJson(viewer) + // inputGeoJson(viewer) //绘制多边形 - const drawPolyline = new CreatePolyline(viewer,true,true,{}) + const drawPolyline = new CreatePolyline(viewer) drawPolyline.start() // const drawPolygon = new DrawPolygon(viewer,true) // drawPolygon.start() diff --git a/src/utils/map/TDTProvider.ts b/src/utils/map/TDTProvider.ts index b0514df..896ac36 100644 --- a/src/utils/map/TDTProvider.ts +++ b/src/utils/map/TDTProvider.ts @@ -3,7 +3,7 @@ * @Date: 2024-03-07 16:04:55 * @LastEditors: cbwu * @LastEditTime: 2024-04-15 16:06:06 - * @Description: + * @Description: 天地图服务 */ // 天地图影像服务 import { diff --git a/src/utils/map/draw/drawPolyline.ts b/src/utils/map/draw/drawPolyline.ts index 5691015..9bfb9a6 100644 --- a/src/utils/map/draw/drawPolyline.ts +++ b/src/utils/map/draw/drawPolyline.ts @@ -2,7 +2,7 @@ * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-27 08:43:44 * @LastEditors: cbwu - * @LastEditTime: 2024-04-22 16:19:27 + * @LastEditTime: 2024-04-23 10:56:54 * @Description: 绘制Polyline类 */ import { @@ -28,7 +28,7 @@ import { getDistance } from '@/utils/map/geocomputation.ts' import { Angle } from '@/utils/map/angle.ts' import { TextLabel } from '@/utils/map/geometry/textLabel.ts' import { EntityOptions } from '@/types/entityoptions.ts' -import {profileAnalyse} from "@/utils/map/SpatialAnalysis.ts"; +import { profileAnalyse } from '@/utils/map/SpatialAnalysis.ts' export default class CreatePolyline { viewer: Viewer @@ -43,8 +43,8 @@ export default class CreatePolyline { moveSelectedPoint: PointEntity | null = null positions: Cartesian3[] = [] bMove: boolean = false - bMeasure: boolean | undefined = false //是否处于测距模式 - bProfile: boolean | undefined = false //是否处于测距模式 + bMeasure: boolean | undefined = false //是否处于测距模式 + bProfile: boolean | undefined = false //是否处于测距模式 totalDistance: number = 0 bLongClick: boolean = false clickTimeout: any @@ -53,6 +53,9 @@ export default class CreatePolyline { // 存储第一次点击的信息 firstClickPosition: Cartesian2 | null = null firstClickTime: number | null = null + //存储辅助对象ID + vDashLinesID: string[] = [] + groundPointsID: string[] = [] // layer: CustomDataSource defaultStyle: EntityOptions = { // id: 'Polyline' + String(PolylineEntity.id), @@ -62,7 +65,12 @@ export default class CreatePolyline { color: Color.GREEN, } - constructor(viewer: Viewer, bMeasure: boolean=false,bProfile: boolean=false,options?: EntityOptions) { + constructor( + viewer: Viewer, + bMeasure: boolean = false, + bProfile: boolean = false, + options?: EntityOptions, + ) { this.viewer = viewer this.bMeasure = bMeasure this.bProfile = bProfile @@ -128,23 +136,39 @@ export default class CreatePolyline { const n = this.positions.length - 1 const ptArr = [oldPosition, cartesian3] this.vDashLinePosition[n] = ptArr - this.viewer.entities.add(this.createTrackingLine(this.vDashLinePosition[n], Color.WHITE)) + const vDashLine = this.createTrackingLine( + this.vDashLinePosition[n], + Color.WHITE, + ) + this.vDashLinesID.push(vDashLine.id) + this.viewer.entities.add(vDashLine) //添加地表控制点 const groundControlPoint = new PointEntity(this.vDashLinePosition[n][0]) + this.groundPointsID.push(groundControlPoint.id) this.viewer.entities.add(groundControlPoint) 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]) + 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]) + 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()) + 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) + new TextLabel(this.viewer, midPoint, labelText) } } } @@ -172,7 +196,9 @@ export default class CreatePolyline { } } // 左双击回调事件 - private leftDoubleClickCallBack = (event: ScreenSpaceEventHandler.PositionedEvent,) => { + private leftDoubleClickCallBack = ( + event: ScreenSpaceEventHandler.PositionedEvent, + ) => { if (!this.polyline) return this.bMove = false const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) @@ -183,14 +209,17 @@ export default class CreatePolyline { } } - if(this.bMeasure){ + if (this.bMeasure) { // 添加总距离label - new TextLabel(this.viewer,this.positions[this.positions.length-1], - `总距离: ${this.totalDistance.toFixed(2)}km`) + new TextLabel( + this.viewer, + this.positions[this.positions.length - 1], + `总距离: ${this.totalDistance.toFixed(2)}km`, + ) } - if(this.bProfile){ + if (this.bProfile) { // 计算剖面点高度 - let profile = profileAnalyse(this.viewer,this.positions,100) + let profile = profileAnalyse(this.viewer, this.positions, 100) // TODO: 弹出地形剖面折线图 console.log(profile) } @@ -198,10 +227,22 @@ export default class CreatePolyline { console.log('end:' + this.positions.length.toString()) console.log(this.positions) console.log(this.polyline.controlPointsID.length) - //结束绘制进入编辑模式 + //移除辅助实体 this.polyline.removeControlPoints() + this.groundPointsID.forEach((value) => { + this.viewer.entities.removeById(value) + }) + this.groundPointsID = [] + this.vDashLinesID.forEach((value) => { + this.viewer.entities.removeById(value) + }) + this.vDashLinesID = [] + + //结束绘制进入编辑模式 const editTool = new EditGeometry(this.viewer, this.polyline.geometry!) editTool.start() + //刷新 + this.viewer.scene.requestRender() } // 右击回调事件 private rightClickCallBack = () => { @@ -232,7 +273,7 @@ export default class CreatePolyline { ) } //创建追踪线 - createTrackingLine(positions: Cartesian3[],color: Color=Color.GREEN) { + createTrackingLine(positions: Cartesian3[], color: Color = Color.GREEN) { return new Entity({ polyline: { positions: new CallbackProperty(() => { diff --git a/src/utils/map/draw/editGeometry.ts b/src/utils/map/draw/editGeometry.ts index 2f8729c..087ed1e 100644 --- a/src/utils/map/draw/editGeometry.ts +++ b/src/utils/map/draw/editGeometry.ts @@ -2,7 +2,7 @@ * @Author: cbwu 504-wuchengbo@htsdfp.com * @Date: 2024-03-27 11:06:45 * @LastEditors: cbwu - * @LastEditTime: 2024-04-22 16:49:15 + * @LastEditTime: 2024-04-24 16:52:23 * @Description: 编辑几何体类。操作逻辑 */ import { @@ -20,10 +20,17 @@ import { PolylineDashMaterialProperty, Color, Cartographic, + Cartesian2, + Ellipsoid, } from 'cesium' import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' -import { getClosestPoint, isOnLineSegment } from '@/utils/map/geocomputation' +import { + getClosestPoint, + isOnLineSegment, + getElevation, +} from '@/utils/map/geocomputation' import { PointEntity } from '@/utils/map/geometry/pointEntity' +import { setMouseStyle, MouseType } from '@/utils/map/mouseStyle' export default class EditGeometry { viewer: Viewer editHandler: ScreenSpaceEventHandler @@ -34,14 +41,21 @@ export default class EditGeometry { groundPointsID: string[] = [] //地表控制点ID数组 groundDashLineID: string[] = [] //垂直辅助线ID数组 groundDashLinesPosition: Cartesian3[][] = [] //垂直辅助线坐标数组 - heightPoint: PointEntity | null = null //高度控制点 - groundPoint: PointEntity | null = null //地表控制点 + controlPoint: PointEntity | null = null //控制点 + // groundPoint: PointEntity | null = null //地表控制点 clickedGeometry: Entity | null = null clickDownPosition: Cartesian3 | null = null + clickScreenPosition: Cartesian2 | null = null + startHeightPointPosition: Cartesian3 | null = null //记录高度时的初始坐标值 + firstClickScreenPosition: Cartesian2 | null = null //记录第一次单击的位置 + heightScale: number = 1 //高度调节比例 moveSelectedPoint: PointEntity | null = null bDrag: boolean = false //拖动标识 bLongClick: boolean = false //长按标识 + bDoubleClick: boolean = false //双击标识 + nClick: number = 0 //单击次数 clickTimeout: any + doubleClickTimeout: any constructor(viewer: Viewer, editGeometry: Entity) { this.viewer = viewer @@ -55,8 +69,8 @@ export default class EditGeometry { this.positions.forEach((value, index) => { this.createPoint(value, index) //地表点 - const groundPosition = this.calculateGroundPosition(value) - this.createGroundPoint(value, index) + const groundPosition = this.modifyPositionZ(value) + this.createGroundPoint(groundPosition, index) //垂直辅助线 const ptArr = [value, groundPosition] this.groundDashLinesPosition[index] = ptArr @@ -76,25 +90,12 @@ export default class EditGeometry { this.leftUpClickCallBack, ScreenSpaceEventType.LEFT_UP, ) + this.editHandler.setInputAction( + this.leftDoubleClickCallBack, + ScreenSpaceEventType.LEFT_DOUBLE_CLICK, + ) } - //左键点击回调 - 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, @@ -111,29 +112,25 @@ export default class EditGeometry { // 记录点击的几何对象及位置 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, - // ) - // } - // } + this.clickScreenPosition = event.position + // 点中控制点 if (pickedObject.id.point instanceof PointGraphics) { - console.log('You clicked a point entity.') - if (pickedObject.id.point.type === 0) { - console.log('You clicked a HeightPoint entity.') - this.heightPoint = pickedObject.id - } else if (pickedObject.id.point.type === 1) { - console.log('You clicked a GroundPoint entity.') - this.groundPoint = pickedObject.id - } - // console.log(this.heightPoint?.subId) + // console.log('You clicked a point entity.') + this.controlPoint = pickedObject.id + //记录初始坐标,用于高度调节 + this.startHeightPointPosition = + this.positions[pickedObject.id.subId].clone() + //计算高度缩放比例 + this.heightScale = this.getHeightPerPixel(this.startHeightPointPosition) + // console.log(this.controlPoint) + // if (pickedObject.id.type === 0) { + // console.log('You clicked a HeightPoint entity.') + // // this.controlPoint = pickedObject.id + // } else if (pickedObject.id.type === 1) { + // console.log('You clicked a GroundPoint entity.') + // // this.groundPoint = pickedObject.id + // } this.bDrag = true this.forbidDrawWorld(true) } @@ -142,43 +139,29 @@ export default class EditGeometry { //移动回调 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! + 1, - ) - // console.log(this.moveSelectedPoint) - } - this.viewer.scene.requestRender() //刷新 - } - } else { - // 离开控制点恢复原始大小 - if (this.moveSelectedPoint) { - this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( - this.moveSelectedPoint!.options.pixelSize! - 1, - ) - this.moveSelectedPoint = null - this.viewer.scene.requestRender() //刷新 - } - } + // 出发不同编辑内容修改鼠标形状 + this.changeSelectedStyle(pickedObject) - if (!this.heightPoint || !this.bDrag) return - console.log('************************left down') + if (!this.controlPoint || !this.bDrag) return + // console.log('************************left down') const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) if (cartesian3) { - // 修改节点坐标 - this.modifyPoint(cartesian3, this.heightPoint.subId) - // this.geometry?.modifyPoint(cartesian3, this.controlPoint.subId) + //地表点 + if (this.controlPoint.type === 1) { + // 修改节点xy坐标 + this.modifyPoint(cartesian3, this.controlPoint.subId) + } else if (this.controlPoint.type === 0) { + //计算屏幕y坐标偏移量 + const altValue = this.clickScreenPosition!.y - event.endPosition.y + // console.log('************moveYValue:' + altValue.toString()) + //调节高度 + this.modifyAltitude( + this.startHeightPointPosition!, + altValue * this.heightScale, + this.controlPoint.subId, + ) + } + this.viewer.scene.requestRender() //刷新 } } @@ -187,12 +170,26 @@ export default class EditGeometry { event: ScreenSpaceEventHandler.PositionedEvent, ) => { clearTimeout(this.clickTimeout) + // 单击控制点结束 + if ( + !this.bLongClick && + this.clickedGeometry?.point instanceof PointGraphics + ) { + if (this.nClick === 0) this.firstClickScreenPosition = event.position + //记录单击次数 + this.nClick++ + //200ms内没有再次单击,次数清0 + this.doubleClickTimeout = setTimeout(() => { + this.nClick = 0 + }, 200) + } + // 单击添加点 if ( !this.bLongClick && this.clickedGeometry?.polyline instanceof PolylineGraphics ) { - console.log('点中线,加点') + // console.log('点中线,加点') this.addPoint() } this.bLongClick = false @@ -203,7 +200,17 @@ export default class EditGeometry { private leftDoubleClickCallBack = ( event: ScreenSpaceEventHandler.PositionedEvent, ) => { - // this.geometry. + // console.log('***********Double Clicked!') + //双击移除点 + if ( + this.nClick === 2 && + Cartesian2.distance(this.firstClickScreenPosition!, event.position) <= 3 + ) { + // console.log('***********双击移除点!') + //移除点 + this.removePoint(this.controlPoint!.subId) + this.viewer.scene.requestRender() //刷新 + } } // Viewer操作控制 forbidDrawWorld(isForbid: boolean) { @@ -229,37 +236,120 @@ export default class EditGeometry { this.clickDownPosition!, ) this.positions.splice(i + 1, 0, pt) - // 新建控制点 + // 新建节点控制点 this.createPoint(pt, i + 1) - // 修改控制点的subid + // 新建地表控制点 + const groundPos = this.modifyPositionZ(pt) //计算地表点坐标 + this.createGroundPoint(groundPos, 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 + //地表控制点 + const groundPoint = this.geometry.entityCollection.getById( + this.groundPointsID[index], + ) as PointEntity + groundPoint!.subId = groundPoint!.subId + 1 } + // 新建垂直辅助线 + const ptArr = [pt, groundPos] + this.groundDashLinesPosition.splice(i + 1, 0, ptArr) + this.createGroundDashLine(this.groundDashLinesPosition[i + 1], i + 1) + return } } } + + /** + * 删除一个节点 + * @param index 移除点号 + */ + removePoint(index: number) { + this.positions.splice(index, 1) + //移除辅助实体 + this.geometry.entityCollection.removeById(this.controlPointsID[index]) + this.geometry.entityCollection.removeById(this.groundPointsID[index]) + this.geometry.entityCollection.removeById(this.groundDashLineID[index]) + //删除实体ID记录 + this.controlPointsID.splice(index, 1) + this.groundPointsID.splice(index, 1) + this.groundDashLineID.splice(index, 1) + this.groundDashLinesPosition.splice(index, 1) + //修改控制点号 + for (let i = index; i < this.controlPointsID.length; ++i) { + //节点控制点 + const point = this.geometry.entityCollection.getById( + this.controlPointsID[i], + ) as PointEntity + point!.subId = point!.subId - 1 + //地表控制点 + const groundPoint = this.geometry.entityCollection.getById( + this.groundPointsID[i], + ) as PointEntity + groundPoint!.subId = groundPoint!.subId - 1 + } + } + /** * 修改某点的坐标 * @param pos 修改点的坐标 * @param index 修改点的位置 */ modifyPoint(pos: Cartesian3, index: number) { + //计算新坐标 + const newHeightPos = this.calculateHeightPosition( + this.positions[index], + pos, + ) // 修改线坐标 - this.positions.splice(index, 1, pos) - // 修改控制点坐标 - this.heightPoint!.position = new ConstantPositionProperty(pos) + this.positions.splice(index, 1, newHeightPos) + // 修改高度控制点坐标 + const heightPt = this.geometry.entityCollection.getById( + this.controlPointsID[index], + ) + heightPt!.position = new ConstantPositionProperty(newHeightPos) + // 修改地表控制点坐标 + const groundPt = this.geometry.entityCollection.getById( + this.groundPointsID[index], + ) + groundPt!.position = new ConstantPositionProperty(pos) + //修改垂直辅助线坐标 + this.groundDashLinesPosition[index][0] = newHeightPos + this.groundDashLinesPosition[index][1] = pos } + /** - * 新加一个节点 + * 调节航点高度 + * @param oldPosition 修改前的笛卡尔坐标 + * @param increaseAltitude 高度增量 + * @param index 要修改的点号 + */ + modifyAltitude( + oldPosition: Cartesian3, + increaseAltitude: number, + index: number, + ) { + const heightPos = this.modifyPositionZ(oldPosition, increaseAltitude) + this.positions.splice(index, 1, heightPos) + this.groundDashLinesPosition[index][0] = heightPos + const heightPt = this.geometry.entityCollection.getById( + this.controlPointsID[index], + ) + heightPt!.position = new ConstantPositionProperty(heightPos) + } + + /** + * 创建一个节点 * @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 @@ -267,8 +357,9 @@ export default class EditGeometry { this.controlPointsID.splice(index, 0, point.id) // } } + /** - * 新加一个地表控制点 + * 创建一个地表控制点 * @param pos 点的坐标 * @param index 插入的位置,0起步 */ @@ -301,14 +392,99 @@ export default class EditGeometry { this.groundDashLineID.splice(index, 0, vDashLine.id) this.geometry.entityCollection.add(vDashLine) } - //获取地表坐标 - calculateGroundPosition(pos: Cartesian3) { + /** + * 获取更改高度值的坐标 + * @param pos 要修改高度的笛卡尔坐标 + * @param increaseAltitude 可选高度增量值,未选择则默认地表 + * @returns 修改后的坐标 + */ + modifyPositionZ(pos: Cartesian3, increaseAltitude?: number) { // 输入的当前点的笛卡尔坐标 const cartographic = Cartographic.fromCartesian(pos) - // 经度、纬度不变,将地面高度加上需要上升的距离, 假设垂直升高1000米 - cartographic.height -= cartographic.height + // 经度、纬度不变,将地面高度加上需要上升的距离 + if (increaseAltitude != undefined) { + cartographic.height += increaseAltitude + } else { + const height = getElevation(this.viewer, pos) + cartographic.height = height + } // 最后使用Cesium.Cartographic.toCartesian将刚才得到的Cartographic对象转换为笛卡尔坐标 return Cartographic.toCartesian(cartographic) } + /** + * 获取移动后的高度坐标 + * @param heightPos 要修改xy的笛卡尔坐标 + * @param groundPos 目标位置的笛卡尔坐标 + * @returns 修改xy位置的新坐标 + */ + calculateHeightPosition(heightPos: Cartesian3, groundPos: Cartesian3) { + const groundCartographic = Cartographic.fromCartesian(groundPos) + const heightCartographic = Cartographic.fromCartesian(heightPos) + return Cartesian3.fromRadians( + groundCartographic.longitude, + groundCartographic.latitude, + heightCartographic.height, + ) + } + /** + * 修改高度 + * @param heightPos 要修改高度的坐标 + * @param addAltValue 高度增量值 + * @returns 返回修改高度后的坐标 + */ + calculateHeightPositionZ(heightPos: Cartesian3, addAltValue: number) { + const heightCartographic = Cartographic.fromCartesian(heightPos) + heightCartographic.height += addAltValue + return Cartographic.toCartesian(heightCartographic) + } + // 计算一像素对应的高度(有待优化) + getHeightPerPixel(pos: Cartesian3) { + const screenPos0 = this.viewer.scene.cartesianToCanvasCoordinates(pos) + const screenPos1 = this.viewer.scene.cartesianToCanvasCoordinates( + this.modifyPositionZ(pos, 1), + ) + const heightDifference = 1 / Math.abs(screenPos0.y - screenPos1.y) + // console.log('*****像素高度:' + heightDifference.toString()) + return heightDifference + } + + //设置移动靠近编辑实体对象的样式变化 + changeSelectedStyle(pickedObject: any) { + // console.log(pickedObject) + if (pickedObject && pickedObject.id) { + if (pickedObject.id.point instanceof PointGraphics) { + if ( + this.moveSelectedPoint == null || + this.moveSelectedPoint.id !== pickedObject.id.id + ) { + this.moveSelectedPoint = pickedObject.id as PointEntity + this.moveSelectedPoint!.point!.pixelSize = new ConstantProperty( + this.moveSelectedPoint!.options.pixelSize! + 1, + ) + // console.log('**************Selected Point') + //设置鼠标形状 + if (this.moveSelectedPoint.type === 0) { + setMouseStyle(this.viewer, MouseType.NSMove) + } else if (this.moveSelectedPoint.type === 1) { + setMouseStyle(this.viewer, MouseType.Move) + } + } + } else if (pickedObject.id.polyline instanceof PolylineGraphics) { + setMouseStyle(this.viewer, MouseType.AddPoint) + } + this.viewer.scene.requestRender() //刷新 + } else { + // 离开控制点恢复原始大小 + if (this.moveSelectedPoint) { + this.moveSelectedPoint.point!.pixelSize = new ConstantProperty( + this.moveSelectedPoint!.options.pixelSize! - 1, + ) + //设置鼠标形状 + setMouseStyle(this.viewer, MouseType.Default) + this.moveSelectedPoint = null + this.viewer.scene.requestRender() //刷新 + } + } + } } diff --git a/src/utils/map/geocomputation.ts b/src/utils/map/geocomputation.ts index 74efbdc..5a89a3b 100644 --- a/src/utils/map/geocomputation.ts +++ b/src/utils/map/geocomputation.ts @@ -5,8 +5,16 @@ * @LastEditTime: 2024-04-01 14:05:43 * @Description: 地理计算 */ -import {Cartesian3, Cartographic, EllipsoidGeodesic, Math as Cesium_Math, Matrix4, Transforms, Viewer} from 'cesium' -import {Angle} from "@/utils/map/angle.ts"; +import { + Cartesian3, + Cartographic, + EllipsoidGeodesic, + Math as Cesium_Math, + Matrix4, + Transforms, + Viewer, +} from 'cesium' +import { Angle } from '@/utils/map/angle.ts' /** * 计算空间中一点到一条直线的最短距离的交点(在不考虑地球曲率的情况下) @@ -86,20 +94,18 @@ function isOnLineSegment( */ } - /** * 计算距离,单位千米 * @param p1 起点 * @param p2 终点 */ -function getDistance(p1:Cartesian3, p2: Cartesian3): number -{ - let point1cartographic = Cartographic.fromCartesian(p1); - let point2cartographic = Cartographic.fromCartesian(p2); +function getDistance(p1: Cartesian3, p2: Cartesian3): number { + let point1cartographic = Cartographic.fromCartesian(p1) + let point2cartographic = Cartographic.fromCartesian(p2) /**根据经纬度计算出距离**/ let geodesic = new EllipsoidGeodesic() geodesic.setEndPoints(point1cartographic, point2cartographic) - return geodesic.surfaceDistance/1000 + return geodesic.surfaceDistance / 1000 } /** @@ -108,20 +114,30 @@ function getDistance(p1:Cartesian3, p2: Cartesian3): number * @param p2 终点 * @param digits 保留小数位数,默认保留1位小数 */ -function getAzimuth(p1:Cartesian3, p2: Cartesian3, digits=1): string -{ +function getAzimuth(p1: Cartesian3, p2: Cartesian3, digits = 1): string { // 建立局部坐标系:北为y,东为x,p1为原点 const localMatrix = Transforms.eastNorthUpToFixedFrame(p1) //求世界坐标到局部坐标的变换矩阵 const worldToLocalMatrix = Matrix4.inverse(localMatrix, new Matrix4()) //p1在局部坐标系的位置,即局部坐标原点 - const localPosition1 = Matrix4.multiplyByPoint(worldToLocalMatrix, p1, new Cartesian3()) + const localPosition1 = Matrix4.multiplyByPoint( + worldToLocalMatrix, + p1, + new Cartesian3(), + ) //p2在局部坐标系的位置 - const localPosition2 = Matrix4.multiplyByPoint(worldToLocalMatrix, p2, new Cartesian3()) + const localPosition2 = Matrix4.multiplyByPoint( + worldToLocalMatrix, + p2, + new Cartesian3(), + ) //弧度 - const angle = Math.atan2(localPosition2.x - localPosition1.x, localPosition2.y - localPosition1.y) + const angle = Math.atan2( + localPosition2.x - localPosition1.x, + localPosition2.y - localPosition1.y, + ) //转为角度 - let theta = angle * (180 / Math.PI); + let theta = angle * (180 / Math.PI) theta = theta < 0 ? theta + 360 : theta return theta.toFixed(digits) } @@ -146,20 +162,29 @@ function getPolygonArea(vertexs: Cartesian3[]) { * @param viewer 地图Viewer * @param pos 坐标点 Cartographic|Cartesian3|[lon,lat] */ -export function getElevation(viewer: Viewer, pos: Cartographic|Cartesian3|number[]){ +export function getElevation( + viewer: Viewer, + pos: Cartographic | Cartesian3 | number[], +) { let cartographic = undefined - if(pos instanceof Array){ - cartographic = Cartographic.fromDegrees(Angle.degree2rad(pos[0]), Angle.degree2rad(pos[1])) - return viewer.scene.globe.getHeight(cartographic)??-99.2024 - } - else if(pos instanceof Cartesian3){ + if (pos instanceof Array) { + cartographic = Cartographic.fromDegrees( + Angle.degree2rad(pos[0]), + Angle.degree2rad(pos[1]), + ) + return viewer.scene.globe.getHeight(cartographic) ?? -999 + } else if (pos instanceof Cartesian3) { cartographic = Cartographic.fromCartesian(pos) - return viewer.scene.globe.getHeight(cartographic)??-99.2024 - } - else{ - return viewer.scene.globe.getHeight(pos)??-99.2024 + return viewer.scene.globe.getHeight(cartographic) ?? -999 + } else { + return viewer.scene.globe.getHeight(pos) ?? -999 } } - -export { getClosestPoint, isOnLineSegment, getDistance, getAzimuth, getPolygonArea } +export { + getClosestPoint, + isOnLineSegment, + getDistance, + getAzimuth, + getPolygonArea, +} diff --git a/src/utils/map/mouseStyle.ts b/src/utils/map/mouseStyle.ts new file mode 100644 index 0000000..5d6542b --- /dev/null +++ b/src/utils/map/mouseStyle.ts @@ -0,0 +1,23 @@ +/* + * @Author: cbwu 504-wuchengbo@htsdfp.com + * @Date: 2024-04-24 15:06:54 + * @LastEditors: cbwu + * @LastEditTime: 2024-04-24 15:06:58 + * @Description: 鼠标形状 + */ +import { Viewer } from 'cesium' +enum MouseType { + Default = 'Default', //默认箭头 + Move = 'move', //移动 + NSMove = 'n-resize', //上下移动 + Pointer = 'Pointer', //手指 + AddPoint = 'copy', + Grab = 'grab', + Drag = 'grabbing', // +} +function setMouseStyle(viewer: Viewer, type: string = 'Default') { + const canvas = viewer.canvas + canvas.style.cursor = type +} + +export { setMouseStyle, MouseType }