feat: 完善三维航线编辑功能。

dev-cbwu
cbwu 11 months ago
parent 32f4457012
commit 894d54145a

@ -67,9 +67,9 @@ onMounted(() => {
// window // window
window.viewer = viewer window.viewer = viewer
inputGeoJson(viewer) // inputGeoJson(viewer)
// //
const drawPolyline = new CreatePolyline(viewer,true,true,{}) const drawPolyline = new CreatePolyline(viewer)
drawPolyline.start() drawPolyline.start()
// const drawPolygon = new DrawPolygon(viewer,true) // const drawPolygon = new DrawPolygon(viewer,true)
// drawPolygon.start() // drawPolygon.start()

@ -3,7 +3,7 @@
* @Date: 2024-03-07 16:04:55 * @Date: 2024-03-07 16:04:55
* @LastEditors: cbwu * @LastEditors: cbwu
* @LastEditTime: 2024-04-15 16:06:06 * @LastEditTime: 2024-04-15 16:06:06
* @Description: * @Description:
*/ */
// 天地图影像服务 // 天地图影像服务
import { import {

@ -2,7 +2,7 @@
* @Author: cbwu 504-wuchengbo@htsdfp.com * @Author: cbwu 504-wuchengbo@htsdfp.com
* @Date: 2024-03-27 08:43:44 * @Date: 2024-03-27 08:43:44
* @LastEditors: cbwu * @LastEditors: cbwu
* @LastEditTime: 2024-04-22 16:19:27 * @LastEditTime: 2024-04-23 10:56:54
* @Description: Polyline * @Description: Polyline
*/ */
import { import {
@ -28,7 +28,7 @@ import { getDistance } from '@/utils/map/geocomputation.ts'
import { Angle } from '@/utils/map/angle.ts' import { Angle } from '@/utils/map/angle.ts'
import { TextLabel } from '@/utils/map/geometry/textLabel.ts' import { TextLabel } from '@/utils/map/geometry/textLabel.ts'
import { EntityOptions } from '@/types/entityoptions.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 { export default class CreatePolyline {
viewer: Viewer viewer: Viewer
@ -43,8 +43,8 @@ export default class CreatePolyline {
moveSelectedPoint: PointEntity | null = null moveSelectedPoint: PointEntity | null = null
positions: Cartesian3[] = [] positions: Cartesian3[] = []
bMove: boolean = false bMove: boolean = false
bMeasure: boolean | undefined = false //是否处于测距模式 bMeasure: boolean | undefined = false //是否处于测距模式
bProfile: boolean | undefined = false //是否处于测距模式 bProfile: boolean | undefined = false //是否处于测距模式
totalDistance: number = 0 totalDistance: number = 0
bLongClick: boolean = false bLongClick: boolean = false
clickTimeout: any clickTimeout: any
@ -53,6 +53,9 @@ export default class CreatePolyline {
// 存储第一次点击的信息 // 存储第一次点击的信息
firstClickPosition: Cartesian2 | null = null firstClickPosition: Cartesian2 | null = null
firstClickTime: number | null = null firstClickTime: number | null = null
//存储辅助对象ID
vDashLinesID: string[] = []
groundPointsID: string[] = []
// layer: CustomDataSource // layer: CustomDataSource
defaultStyle: EntityOptions = { defaultStyle: EntityOptions = {
// id: 'Polyline' + String(PolylineEntity.id), // id: 'Polyline' + String(PolylineEntity.id),
@ -62,7 +65,12 @@ export default class CreatePolyline {
color: Color.GREEN, 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.viewer = viewer
this.bMeasure = bMeasure this.bMeasure = bMeasure
this.bProfile = bProfile this.bProfile = bProfile
@ -128,23 +136,39 @@ export default class CreatePolyline {
const n = this.positions.length - 1 const n = this.positions.length - 1
const ptArr = [oldPosition, cartesian3] const ptArr = [oldPosition, cartesian3]
this.vDashLinePosition[n] = ptArr 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]) const groundControlPoint = new PointEntity(this.vDashLinePosition[n][0])
this.groundPointsID.push(groundControlPoint.id)
this.viewer.entities.add(groundControlPoint) this.viewer.entities.add(groundControlPoint)
this.bMove = true this.bMove = true
this.viewer.scene.requestRender() //刷新 this.viewer.scene.requestRender() //刷新
// 计算2点距离 // 计算2点距离
if(this.positions.length>=2 && this.bMeasure){ if (this.positions.length >= 2 && this.bMeasure) {
let distance = getDistance(this.positions[this.positions.length-1],this.positions[this.positions.length-2]) let distance = getDistance(
this.positions[this.positions.length - 1],
this.positions[this.positions.length - 2],
)
this.totalDistance += distance this.totalDistance += distance
// 计算2点方位角 // 计算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点的中间点 // 计算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 // 添加label
let labelText = `距离: ${distance.toFixed(2)}km, 方位角: ${azimuth}°` 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 if (!this.polyline) return
this.bMove = false this.bMove = false
const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position) const cartesian3 = cartesian2ToCartesian3(this.viewer, event.position)
@ -183,14 +209,17 @@ export default class CreatePolyline {
} }
} }
if(this.bMeasure){ if (this.bMeasure) {
// 添加总距离label // 添加总距离label
new TextLabel(this.viewer,this.positions[this.positions.length-1], new TextLabel(
`总距离: ${this.totalDistance.toFixed(2)}km`) 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: 弹出地形剖面折线图 // TODO: 弹出地形剖面折线图
console.log(profile) console.log(profile)
} }
@ -198,10 +227,22 @@ export default class CreatePolyline {
console.log('end:' + this.positions.length.toString()) console.log('end:' + this.positions.length.toString())
console.log(this.positions) console.log(this.positions)
console.log(this.polyline.controlPointsID.length) console.log(this.polyline.controlPointsID.length)
//结束绘制进入编辑模式 //移除辅助实体
this.polyline.removeControlPoints() 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!) const editTool = new EditGeometry(this.viewer, this.polyline.geometry!)
editTool.start() editTool.start()
//刷新
this.viewer.scene.requestRender()
} }
// 右击回调事件 // 右击回调事件
private rightClickCallBack = () => { 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({ return new Entity({
polyline: { polyline: {
positions: new CallbackProperty(() => { positions: new CallbackProperty(() => {

@ -2,7 +2,7 @@
* @Author: cbwu 504-wuchengbo@htsdfp.com * @Author: cbwu 504-wuchengbo@htsdfp.com
* @Date: 2024-03-27 11:06:45 * @Date: 2024-03-27 11:06:45
* @LastEditors: cbwu * @LastEditors: cbwu
* @LastEditTime: 2024-04-22 16:49:15 * @LastEditTime: 2024-04-24 16:52:23
* @Description: * @Description:
*/ */
import { import {
@ -20,10 +20,17 @@ import {
PolylineDashMaterialProperty, PolylineDashMaterialProperty,
Color, Color,
Cartographic, Cartographic,
Cartesian2,
Ellipsoid,
} from 'cesium' } from 'cesium'
import { cartesian2ToCartesian3 } from '@/utils/map/coordinate' 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 { PointEntity } from '@/utils/map/geometry/pointEntity'
import { setMouseStyle, MouseType } from '@/utils/map/mouseStyle'
export default class EditGeometry { export default class EditGeometry {
viewer: Viewer viewer: Viewer
editHandler: ScreenSpaceEventHandler editHandler: ScreenSpaceEventHandler
@ -34,14 +41,21 @@ export default class EditGeometry {
groundPointsID: string[] = [] //地表控制点ID数组 groundPointsID: string[] = [] //地表控制点ID数组
groundDashLineID: string[] = [] //垂直辅助线ID数组 groundDashLineID: string[] = [] //垂直辅助线ID数组
groundDashLinesPosition: Cartesian3[][] = [] //垂直辅助线坐标数组 groundDashLinesPosition: Cartesian3[][] = [] //垂直辅助线坐标数组
heightPoint: PointEntity | null = null //高度控制点 controlPoint: PointEntity | null = null //控制点
groundPoint: PointEntity | null = null //地表控制点 // groundPoint: PointEntity | null = null //地表控制点
clickedGeometry: Entity | null = null clickedGeometry: Entity | null = null
clickDownPosition: Cartesian3 | 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 moveSelectedPoint: PointEntity | null = null
bDrag: boolean = false //拖动标识 bDrag: boolean = false //拖动标识
bLongClick: boolean = false //长按标识 bLongClick: boolean = false //长按标识
bDoubleClick: boolean = false //双击标识
nClick: number = 0 //单击次数
clickTimeout: any clickTimeout: any
doubleClickTimeout: any
constructor(viewer: Viewer, editGeometry: Entity) { constructor(viewer: Viewer, editGeometry: Entity) {
this.viewer = viewer this.viewer = viewer
@ -55,8 +69,8 @@ export default class EditGeometry {
this.positions.forEach((value, index) => { this.positions.forEach((value, index) => {
this.createPoint(value, index) this.createPoint(value, index)
//地表点 //地表点
const groundPosition = this.calculateGroundPosition(value) const groundPosition = this.modifyPositionZ(value)
this.createGroundPoint(value, index) this.createGroundPoint(groundPosition, index)
//垂直辅助线 //垂直辅助线
const ptArr = [value, groundPosition] const ptArr = [value, groundPosition]
this.groundDashLinesPosition[index] = ptArr this.groundDashLinesPosition[index] = ptArr
@ -76,25 +90,12 @@ export default class EditGeometry {
this.leftUpClickCallBack, this.leftUpClickCallBack,
ScreenSpaceEventType.LEFT_UP, 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 = ( private leftDownClickCallBack = (
event: ScreenSpaceEventHandler.PositionedEvent, event: ScreenSpaceEventHandler.PositionedEvent,
@ -111,29 +112,25 @@ export default class EditGeometry {
// 记录点击的几何对象及位置 // 记录点击的几何对象及位置
this.clickedGeometry = pickedObject.id this.clickedGeometry = pickedObject.id
this.clickDownPosition = this.viewer.scene.pickPosition(event.position) this.clickDownPosition = this.viewer.scene.pickPosition(event.position)
// // 判断是否同一实体 this.clickScreenPosition = 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) { if (pickedObject.id.point instanceof PointGraphics) {
console.log('You clicked a point entity.') // console.log('You clicked a point entity.')
if (pickedObject.id.point.type === 0) { this.controlPoint = pickedObject.id
console.log('You clicked a HeightPoint entity.') //记录初始坐标,用于高度调节
this.heightPoint = pickedObject.id this.startHeightPointPosition =
} else if (pickedObject.id.point.type === 1) { this.positions[pickedObject.id.subId].clone()
console.log('You clicked a GroundPoint entity.') //计算高度缩放比例
this.groundPoint = pickedObject.id this.heightScale = this.getHeightPerPixel(this.startHeightPointPosition)
} // console.log(this.controlPoint)
// console.log(this.heightPoint?.subId) // 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.bDrag = true
this.forbidDrawWorld(true) this.forbidDrawWorld(true)
} }
@ -142,43 +139,29 @@ export default class EditGeometry {
//移动回调 //移动回调
private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => { private moveCallBack = (event: ScreenSpaceEventHandler.MotionEvent) => {
const pickedObject = this.viewer.scene.pick(event.endPosition) const pickedObject = this.viewer.scene.pick(event.endPosition)
// 悬停控制点放大 // 出发不同编辑内容修改鼠标形状
if ( this.changeSelectedStyle(pickedObject)
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() //刷新
}
}
if (!this.heightPoint || !this.bDrag) return if (!this.controlPoint || !this.bDrag) return
console.log('************************left down') // console.log('************************left down')
const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition) const cartesian3 = cartesian2ToCartesian3(this.viewer, event.endPosition)
if (cartesian3) { if (cartesian3) {
// 修改节点坐标 //地表点
this.modifyPoint(cartesian3, this.heightPoint.subId) if (this.controlPoint.type === 1) {
// this.geometry?.modifyPoint(cartesian3, this.controlPoint.subId) // 修改节点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() //刷新 this.viewer.scene.requestRender() //刷新
} }
} }
@ -187,12 +170,26 @@ export default class EditGeometry {
event: ScreenSpaceEventHandler.PositionedEvent, event: ScreenSpaceEventHandler.PositionedEvent,
) => { ) => {
clearTimeout(this.clickTimeout) 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 ( if (
!this.bLongClick && !this.bLongClick &&
this.clickedGeometry?.polyline instanceof PolylineGraphics this.clickedGeometry?.polyline instanceof PolylineGraphics
) { ) {
console.log('点中线,加点') // console.log('点中线,加点')
this.addPoint() this.addPoint()
} }
this.bLongClick = false this.bLongClick = false
@ -203,7 +200,17 @@ export default class EditGeometry {
private leftDoubleClickCallBack = ( private leftDoubleClickCallBack = (
event: ScreenSpaceEventHandler.PositionedEvent, 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操作控制 // Viewer操作控制
forbidDrawWorld(isForbid: boolean) { forbidDrawWorld(isForbid: boolean) {
@ -229,37 +236,120 @@ export default class EditGeometry {
this.clickDownPosition!, this.clickDownPosition!,
) )
this.positions.splice(i + 1, 0, pt) this.positions.splice(i + 1, 0, pt)
// 新建控制点 // 新建节点控制点
this.createPoint(pt, i + 1) 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) { for (let index = i + 2; index < this.controlPointsID.length; ++index) {
//节点控制点
const point = this.geometry.entityCollection.getById( const point = this.geometry.entityCollection.getById(
this.controlPointsID[index], this.controlPointsID[index],
) as PointEntity ) as PointEntity
point!.subId = point!.subId + 1 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 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 pos
* @param index * @param index
*/ */
modifyPoint(pos: Cartesian3, index: number) { modifyPoint(pos: Cartesian3, index: number) {
//计算新坐标
const newHeightPos = this.calculateHeightPosition(
this.positions[index],
pos,
)
// 修改线坐标 // 修改线坐标
this.positions.splice(index, 1, pos) this.positions.splice(index, 1, newHeightPos)
// 修改控制点坐标 // 修改高度控制点坐标
this.heightPoint!.position = new ConstantPositionProperty(pos) 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 pos
* @param index ,0 * @param index ,0
*/ */
createPoint(pos: Cartesian3, index: number) { createPoint(pos: Cartesian3, index: number) {
// if (this.geometry) { // if (this.geometry) {
// 高度控制点
const point = new PointEntity(pos) const point = new PointEntity(pos)
point.parent = this.geometry point.parent = this.geometry
point.subId = index point.subId = index
@ -267,8 +357,9 @@ export default class EditGeometry {
this.controlPointsID.splice(index, 0, point.id) this.controlPointsID.splice(index, 0, point.id)
// } // }
} }
/** /**
* *
* @param pos * @param pos
* @param index ,0 * @param index ,0
*/ */
@ -301,14 +392,99 @@ export default class EditGeometry {
this.groundDashLineID.splice(index, 0, vDashLine.id) this.groundDashLineID.splice(index, 0, vDashLine.id)
this.geometry.entityCollection.add(vDashLine) this.geometry.entityCollection.add(vDashLine)
} }
//获取地表坐标 /**
calculateGroundPosition(pos: Cartesian3) { *
* @param pos
* @param increaseAltitude
* @returns
*/
modifyPositionZ(pos: Cartesian3, increaseAltitude?: number) {
// 输入的当前点的笛卡尔坐标 // 输入的当前点的笛卡尔坐标
const cartographic = Cartographic.fromCartesian(pos) 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对象转换为笛卡尔坐标 // 最后使用Cesium.Cartographic.toCartesian将刚才得到的Cartographic对象转换为笛卡尔坐标
return 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() //刷新
}
}
}
} }

@ -5,8 +5,16 @@
* @LastEditTime: 2024-04-01 14:05:43 * @LastEditTime: 2024-04-01 14:05:43
* @Description: * @Description:
*/ */
import {Cartesian3, Cartographic, EllipsoidGeodesic, Math as Cesium_Math, Matrix4, Transforms, Viewer} from 'cesium' import {
import {Angle} from "@/utils/map/angle.ts"; 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 p1
* @param p2 * @param p2
*/ */
function getDistance(p1:Cartesian3, p2: Cartesian3): number function getDistance(p1: Cartesian3, p2: Cartesian3): number {
{ let point1cartographic = Cartographic.fromCartesian(p1)
let point1cartographic = Cartographic.fromCartesian(p1); let point2cartographic = Cartographic.fromCartesian(p2)
let point2cartographic = Cartographic.fromCartesian(p2);
/**根据经纬度计算出距离**/ /**根据经纬度计算出距离**/
let geodesic = new EllipsoidGeodesic() let geodesic = new EllipsoidGeodesic()
geodesic.setEndPoints(point1cartographic, point2cartographic) 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 p2
* @param digits 1 * @param digits 1
*/ */
function getAzimuth(p1:Cartesian3, p2: Cartesian3, digits=1): string function getAzimuth(p1: Cartesian3, p2: Cartesian3, digits = 1): string {
{
// 建立局部坐标系北为y东为xp1为原点 // 建立局部坐标系北为y东为xp1为原点
const localMatrix = Transforms.eastNorthUpToFixedFrame(p1) const localMatrix = Transforms.eastNorthUpToFixedFrame(p1)
//求世界坐标到局部坐标的变换矩阵 //求世界坐标到局部坐标的变换矩阵
const worldToLocalMatrix = Matrix4.inverse(localMatrix, new Matrix4()) const worldToLocalMatrix = Matrix4.inverse(localMatrix, new Matrix4())
//p1在局部坐标系的位置即局部坐标原点 //p1在局部坐标系的位置即局部坐标原点
const localPosition1 = Matrix4.multiplyByPoint(worldToLocalMatrix, p1, new Cartesian3()) const localPosition1 = Matrix4.multiplyByPoint(
worldToLocalMatrix,
p1,
new Cartesian3(),
)
//p2在局部坐标系的位置 //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 theta = theta < 0 ? theta + 360 : theta
return theta.toFixed(digits) return theta.toFixed(digits)
} }
@ -146,20 +162,29 @@ function getPolygonArea(vertexs: Cartesian3[]) {
* @param viewer Viewer * @param viewer Viewer
* @param pos Cartographic|Cartesian3|[lon,lat] * @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 let cartographic = undefined
if(pos instanceof Array){ if (pos instanceof Array) {
cartographic = Cartographic.fromDegrees(Angle.degree2rad(pos[0]), Angle.degree2rad(pos[1])) cartographic = Cartographic.fromDegrees(
return viewer.scene.globe.getHeight(cartographic)??-99.2024 Angle.degree2rad(pos[0]),
} Angle.degree2rad(pos[1]),
else if(pos instanceof Cartesian3){ )
return viewer.scene.globe.getHeight(cartographic) ?? -999
} else if (pos instanceof Cartesian3) {
cartographic = Cartographic.fromCartesian(pos) cartographic = Cartographic.fromCartesian(pos)
return viewer.scene.globe.getHeight(cartographic)??-99.2024 return viewer.scene.globe.getHeight(cartographic) ?? -999
} } else {
else{ return viewer.scene.globe.getHeight(pos) ?? -999
return viewer.scene.globe.getHeight(pos)??-99.2024
} }
} }
export {
export { getClosestPoint, isOnLineSegment, getDistance, getAzimuth, getPolygonArea } getClosestPoint,
isOnLineSegment,
getDistance,
getAzimuth,
getPolygonArea,
}

@ -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 }
Loading…
Cancel
Save