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.
250 lines
7.8 KiB
TypeScript
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)
|
|
// }
|
|
}
|
|
}
|