You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GCSGUI/src/utils/map/draw/editGeometry.ts

250 lines
7.8 KiB
TypeScript

/*
* @Author: cbwu 504-wuchengbo@htsdfp.com
* @Date: 2024-03-27 11:06:45
* @LastEditors: cbwu
* @LastEditTime: 2024-04-13 10:47:09
* @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)
// }
}
}