import * as Cesium from 'cesium'
import { useCesiumStore } from '@/stores/useCesiumStore.js'
import { toRaw } from 'vue'
export function drawShape(type) {
const viewer = toRaw(useCesiumStore().viewer) // 获取viewer对象
let activeShapePoints = [] // 存放当前绘制的多边形的点坐标
let activeShape = null // 存放当前绘制的多边形对象
let floatingPoint = null //存储第一个点并判断是否开始获取鼠标移动结束位置
let drawingMode = null
const hander = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
switch (type) {
case 'drawPoint':
drawingMode = 'point'
break
case 'drawLine':
drawingMode = 'line'
// console.log(viewer.entities.values);
break
case 'drawPolygon':
drawingMode = 'polygon'
break
case 'drawCircle':
drawingMode = 'circle'
break
case 'drawRectangle':
drawingMode = 'rectangle'
break
case 'clearDraw':
console.log(viewer.entities.values.length);
// viewer.entities.removeAll() //清除所有图形
clearDraw()
viewer.scene.canvas.style.cursor = 'default' //恢复鼠标形状
break
default:
break
}
//清除图形
function clearDraw () {
for (let i = 0; i < viewer.entities.values.length; i++) {
if (viewer.entities.values[i].name === 'Point' || viewer.entities.values[i].name === 'Line' || viewer.entities.values[i].name === 'Polygon' || viewer.entities.values[i].name === 'Rectangle' || viewer.entities.values[i].name === 'Ellipse') {
viewer.entities.remove(viewer.entities.values[i])
i-- //删除后索引减一,数组塌陷
}
}
}
viewer.scene.canvas.style.cursor = 'crosshair'
//绘制点
const drawPoint = (position) => {
const pointGeometry = viewer.entities.add({
name: 'Point',
position: position,
point: {
color: Cesium.Color.BLUE,
pixelSize: 8,
outlineColor: Cesium.Color.YELLOW,
outlineWidth: 2
}
})
return pointGeometry
}
//绘制形状功能
const drawShape = (positionData) => {
let shape = null
//如果为线时
if (drawingMode === 'line') {
shape = viewer.entities.add({
name: 'Line',
polyline: {
positions: positionData,
width: 5,
material: new Cesium.PolylineOutlineMaterialProperty({
color: Cesium.Color.GOLD
}),
clampToGround: true //贴地
}
})
}
else if (drawingMode === 'polygon') { //如果模式选择绘制多边形,调用绘制多边形
shape = viewer.entities.add({
name: 'Polygon',
polygon: {
hierarchy: positionData,
material: new Cesium.ColorMaterialProperty(Cesium.Color.BLUE.withAlpha(0.7)),
}
})
}
else if (drawingMode === 'circle') { //如果模式选择绘制圆,调用绘制圆
let value = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData //当传入的positionData为SampledPositionProperty时,取第一个值
shape = viewer.entities.add({
name: 'Ellipse',
position : activeShapePoints[0], //圆心
ellipse : { //椭圆
semiMinorAxis:new Cesium.CallbackProperty(function(){
//半径,两点之间的距离
let r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x,2) + Math.pow(value[0].y - value[value.length - 1].y,2)) //半径
return r ? r : r + 1
}, false),
semiMajorAxis:new Cesium.CallbackProperty(function(){
//半径,两点之间的距离
let r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x,2) + Math.pow(value[0].y - value[value.length - 1].y,2)) //半径
return r ? r : r + 1
}, false),
material: Cesium.Color.BLUE.withAlpha(0.5), //颜色
outline: true
}
})
}
else if (drawingMode === 'rectangle') { //如果模式选择绘制矩形,调用绘制矩形
let arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData //当传入的positionData为SampledPositionProperty时,取第一个值
shape = viewer.entities.add({
name: 'Rectangle',
rectangle: {
coordinates: new Cesium.CallbackProperty(function(){
let obj = Cesium.Rectangle.fromCartesianArray(arr)
return obj
}, false),
material:Cesium.Color.RED.withAlpha(0.5)
}
})
}
return shape
}
//注册鼠标左键单击事件
hander.setInputAction( (event) => {
let earthPosition = viewer.scene.pickPosition(event.position)
if (drawingMode === 'point') { //如果模式选择绘制点,调用绘制点
drawPoint(earthPosition)
}else if (drawingMode === 'polygon' || drawingMode === 'line' || drawingMode === 'circle' || drawingMode ==='rectangle') {
if (Cesium.defined(earthPosition)) {
if (activeShapePoints.length === 0) { //如果是第一次点击,则记录第一个点
floatingPoint = drawPoint(earthPosition)
activeShapePoints.push(earthPosition)
//动态点通过CallbackProperty更新位置
const dynamicPositions = new Cesium.CallbackProperty(function(){
if(drawingMode === 'polygon') {
return new Cesium.PolygonHierarchy(activeShapePoints)
}
return activeShapePoints
},false)
activeShape = drawShape(dynamicPositions)
}
activeShapePoints.push(earthPosition) //记录当前点
// drawPoint(earthPosition) //绘制动态点
if((drawingMode === 'rectangle' && activeShapePoints.length === 3) || (drawingMode === 'circle' && activeShapePoints.length === 3)){ //绘制矩形时,判断是否绘制完成
hander.destroy() //销毁事件处理器
viewer.scene.canvas.style.cursor = 'default' //恢复鼠标形状
viewer.entities.remove(floatingPoint) //删除重复的第一个点
floatingPoint = undefined //清空变量
activeShape = undefined //清空变量
activeShapePoints = [] //清空数组
}
}
}
},Cesium.ScreenSpaceEventType.LEFT_CLICK)
//注册鼠标移动事件
hander.setInputAction( (event) => {
if (Cesium.defined(floatingPoint)) {
//获取鼠标移动到的最终位置
const newPosition = viewer.scene.pickPosition(event.endPosition)
// console.log(newPosition);
if (Cesium.defined(newPosition)) {
//动态去除数组中最后一个点,并添加一个新的点,保证只保留鼠标位置点
activeShapePoints.pop()
activeShapePoints.push(newPosition)
}
}
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)
//注册鼠标右键单击事件
hander.setInputAction( () => {
hander.destroy() //销毁事件处理器
viewer.scene.canvas.style.cursor = 'default' //恢复鼠标形状
activeShapePoints.pop() //删除最后一个点
if(activeShapePoints.length){
drawShape(activeShapePoints) //绘制多边形或线
}
viewer.entities.remove(floatingPoint) //删除重复的第一个点
viewer.entities.remove(activeShape) //删除动态图形
floatingPoint = undefined //清空变量
activeShape = undefined //清空变量
activeShapePoints = [] //清空数组
},Cesium.ScreenSpaceEventType.RIGHT_CLICK)
//清除图形
}
(六)Cesium使用CallbackProperty交互绘制图形,点线面圆
最新推荐文章于 2024-08-05 20:40:17 发布