1.修改平面距离、面积测量功能的实现逻辑和显示效果;2.优化相关代码,修复bug;

This commit is contained in:
zhangquan 2025-08-02 11:59:35 +08:00
parent eef0209e58
commit 0f43d4d08a
6 changed files with 534 additions and 225 deletions

View File

@ -54,8 +54,13 @@ export const useDrawTool = (viewer) => {
) )
if (!assistLayer) { if (!assistLayer) {
assistLayer = new CustomDataSource('__assist_edit') const layers = viewer.dataSources.getByName('__assist_edit')
viewer.dataSources.add(assistLayer) if(layers.length && layers.length > 0) {
assistLayer = layers[0]
} else {
assistLayer = new CustomDataSource('__assist_edit')
viewer.dataSources.add(assistLayer)
}
} }
// 辅助点,用于显示获取的实际位置 // 辅助点,用于显示获取的实际位置

View File

@ -1,223 +0,0 @@
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
import { useDrawTool } from './useDrawTool'
// 存储测量内容的辅助图层
let measureLayer = null
/**
* 计算折线长度
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 折线长度单位米
*/
const getDistance = (positions) => {
const line = turf.lineString(positions.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
}))
return turf.length(line, { units: 'kilometers' }) * 1000 // 返回米
}
/**
* 计算多边形面积
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 多边形面积单位平方米
*/
const getArea = (positions) => {
const pts = [...positions, positions[0]] // 闭合多边形
const polygon = turf.polygon([pts.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
})])
return turf.area(polygon) // 返回平方米
}
/**
* 获取多个点的中心位置根据边界范围确定
* @param {Cesium.Cartesian3[]} positions 位置列表
* @param {number} height 返回位置的高度默认为0
* @returns 根据边界范围确定的中心点位置
*/
const getBoundingCenter = (positions, height = 0) => {
const coord = getBoundingCenterCoordinate(positions)
return Cesium.Cartesian3.fromDegrees(coord[0], coord[1], height)
}
/**
* 获取多个点的中心位置坐标根据边界范围确定
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 根据边界范围确定的中心点位置坐标格式为 [经度, 纬度]
*/
const getBoundingCenterCoordinate = (positions) => {
const polygon = turf.lineString(positions.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
}))
const centerFeature = turf.center(polygon)
return centerFeature.geometry.coordinates
}
export const useMeasureTool = (viewer) => {
if (!viewer) {
throw new Error('获取 Viewer 实例失败,请确保在 Viewer 初始化后调用 useMeasureTool 方法!')
}
const editTool = useDrawTool(viewer)
if (!measureLayer) {
measureLayer = new Cesium.CustomDataSource('__assist_measure')
viewer.dataSources.add(measureLayer)
}
// 距离测量
const measureDistance = () => {
return editTool.drawPolyline().then((positions) => {
const style = {
width: 5,
material: Cesium.Color.fromCssColorString('#57e0e0'),
}
let arr = []
for (let i = 0; i < positions.length; i++) {
if (i + 1 < positions.length) {
if (!positions[i] || !positions[i + 1]) continue
arr.push([positions[i], positions[i + 1]])
}
}
console.log(arr)
let result = 0
arr.forEach((item) => {
let start = Cesium.Cartographic.fromCartesian(item[0])
let end = Cesium.Cartographic.fromCartesian(item[1])
let startObj = { longitude: '', latitude: '' }
let endObj = { longitude: '', latitude: '' }
startObj.longitude = Cesium.Math.toDegrees(start.longitude)
startObj.latitude = Cesium.Math.toDegrees(start.latitude)
endObj.longitude = Cesium.Math.toDegrees(end.longitude)
endObj.latitude = Cesium.Math.toDegrees(end.latitude)
console.log(startObj)
console.log(endObj)
let from = turf.point([startObj.longitude, startObj.latitude])
let to = turf.point([endObj.longitude, endObj.latitude])
let distance = turf.distance(from, to, { units: 'kilometers' }) * 1000
result += distance
const tempPolyline = new Cesium.Entity({
name: '__measure_distance',
// position: [ {x: (item[0].x + item[1].x) / 2, y: (item[0].y + item[1].y) / 2, z: (item[0].z + item[1].z) / 2} ],
position: new Cesium.Cartesian3(
(item[0].x + item[1].x) / 2,
(item[0].y + item[1].y) / 2,
(item[0].z + item[1].z) / 2,
),
polyline: {
positions: [...item],
width: style.width,
material: style.material,
clampToGround: true,
},
label: new Cesium.LabelGraphics({
text: distance.toFixed(2) + '米',
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
pixelOffset: new Cesium.Cartesian2(10, 10),
disableDepthTestDistance: Number.POSITIVE_INFINITY,
}),
})
measureLayer.entities.add(tempPolyline)
return positions
})
let len = positions.length - 1
if (len > 1) {
let resultLabel = new Cesium.Entity({
name: 'measure_distance_length',
position: new Cesium.Cartesian3(
(positions[0].x + positions[len].x) / 2,
(positions[0].y + positions[len].y) / 2,
(positions[0].z + positions[len].z) / 2,
),
label: new Cesium.LabelGraphics({
text: '总距离:' + result.toFixed(2) + '米',
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
fillColor: Cesium.Color.AQUAMARINE,
}),
})
measureLayer.entities.add(resultLabel)
}
return positions
})
}
// 面积测量
const measureArea = () => {
return editTool.drawPolygon().then((positions) => {
let polygon = []
positions.forEach((item) => {
let obj = Cesium.Cartographic.fromCartesian(item)
polygon.push([Cesium.Math.toDegrees(obj.longitude), Cesium.Math.toDegrees(obj.latitude)])
})
let features = turf.points(polygon)
let center = turf.center(features)
console.log(center)
let points0 = Cesium.Cartographic.fromCartesian(positions[0])
polygon.push([
Cesium.Math.toDegrees(points0.longitude),
Cesium.Math.toDegrees(points0.latitude),
])
let areaPolygon = turf.polygon([polygon])
let area = turf.area(areaPolygon)
const tempPolygon = new Cesium.Entity({
name: '__measure_area',
position: Cesium.Cartesian3.fromDegrees(
center.geometry.coordinates[0],
center.geometry.coordinates[1],
),
polygon: {
hierarchy: new Cesium.PolygonHierarchy(positions),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
material: Cesium.Color.fromCssColorString('#ffff00').withAlpha(0.3),
},
polyline: {
positions: [...positions, positions[0]],
clampToGround: true,
width: 2,
material: Cesium.Color.fromCssColorString('#ffff00'),
},
label: new Cesium.LabelGraphics({
text: area.toFixed(2) + '平方米',
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
}),
})
measureLayer.entities.add(tempPolygon)
return positions
})
}
// 取消当前测量
const abort = () => {
editTool.abort() // 调用编辑工具的取消方法
}
// 清除所有测量结果
const clear = () => {
measureLayer.entities.removeAll()
}
return {
distance: measureDistance,
area: measureArea,
abort,
clear,
}
}
export { getDistance, getArea, getBoundingCenter, getBoundingCenterCoordinate }

View File

@ -0,0 +1,124 @@
import * as Cesium from 'cesium'
import { useEventBus, ScreenMode } from '../useEventBus'
import { useHoverPosition } from '../useHoverPosition'
import { getDistance, getArea, getBoundingCenter, getBoundingCenterCoordinate } from './utils'
import { measureDistance as _measureDistance } from './measureDistance'
import { measureArea as _measureArea } from './measureArea'
// 存储测量内容的辅助图层
let measureLayer = null
// 存储编辑内容的辅助图层
// let assistLayer = null
// 所有useMeasureTool实例共用一个绘制状态和取消回调
let abortCallback = null
export const useMeasureTool = (viewer) => {
if (!viewer) {
throw new Error('获取 Viewer 实例失败,请确保在 Viewer 初始化后调用 useMeasureTool 方法!')
}
// 获取实时位置
const { isHover, position } = useHoverPosition(viewer)
// 获取事件总线
const bus = useEventBus(viewer)
// 判断辅助点是否显示
watch(
() => [bus.mode.value, isHover.value],
([nowStatus, hover]) => {
if (hover && nowStatus === ScreenMode.DRAW) {
assistPoint.show = true
} else {
assistPoint.show = false
}
},
)
if (!measureLayer) {
const layers = viewer.dataSources.getByName('__assist_measure')
if(layers.length && layers.length > 0) {
measureLayer = layers[0]
} else {
measureLayer = new Cesium.CustomDataSource('__assist_measure')
viewer.dataSources.add(measureLayer)
}
}
// if (!assistLayer) {
// const layers = viewer.dataSources.getByName('__assist_edit')
// if(layers.length && layers.length > 0) {
// assistLayer = layers[0]
// } else {
// assistLayer = new Cesium.CustomDataSource('__assist_edit')
// viewer.dataSources.add(assistLayer)
// }
// }
// 辅助点,用于显示获取的实际位置
const assistPoint = new Cesium.Entity({
name: '__draw_icon',
show: false,
position: new Cesium.CallbackPositionProperty(() => {
return position.value || undefined
}, false),
point: {
pixelSize: 7,
color: Cesium.Color.BLUE,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
})
viewer.entities.add(assistPoint)
// 全局取消当前绘制操作的函数
const abort = () => {
if (abortCallback) {
abortCallback() // 调用当前注册的取消回调
abortCallback = null // 清空回调
}
}
// 注册当前绘制操作的取消回调函数
const registerAbort = (cb) => {
abortCallback = cb
}
// 准备传递给绘制函数的依赖对象
const drawDependencies = {
viewer,
bus,
ScreenMode,
position,
measureLayer,
registerAbort,
globalAbort: abort, // 将全局 abort 函数也传递进去,方便内部调用
}
// 调用拆分后的测量函数,并传递依赖
const distance = () => _measureDistance(drawDependencies)
const area = () => _measureArea(drawDependencies)
// 取消当前测量
// const abort = () => {
// editTool.abort() // 调用编辑工具的取消方法
// }
// 清除所有测量结果
const clear = () => {
measureLayer.entities.removeAll()
}
return {
distance,
area,
abort,
clear,
}
}
export { getDistance, getArea, getBoundingCenter, getBoundingCenterCoordinate }

View File

@ -0,0 +1,166 @@
import * as Cesium from 'cesium'
import { getBoundingCenter, getArea } from './utils'
// 面积测量
export const measureArea = (deps) => {
const { viewer, bus, ScreenMode, position, measureLayer, registerAbort, globalAbort } = deps
// 如果在执行其它操作,则取消
globalAbort()
bus.mode.value = ScreenMode.DRAW
const featurePositions = []
// 临时多边形实体 (包含填充和边界线)
const tempPolygon = new Cesium.Entity({
name: '__draw_temp_polygon',
position: new Cesium.CallbackProperty(() => {
if (featurePositions.length < 2) return null
return getBoundingCenter([...featurePositions, position.value])
}, false),
label: {
text: new Cesium.CallbackProperty(() => {
if (featurePositions.length < 2) return null
return `${getArea([...featurePositions, position.value]).toFixed(2)}平方米`
}, false),
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(8, 4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
polygon: {
hierarchy: new Cesium.CallbackProperty(() => {
const positions = [...featurePositions]
// 添加当前鼠标位置作为最后一个点,形成动态效果
if (
position.value &&
!position.value.equals(featurePositions[featurePositions.length - 1]) // 避免重复添加同一个点
) {
positions.push(position.value)
}
// 多边形需要至少3个点才能形成
if (positions.length < 3) {
return null
}
return new Cesium.PolygonHierarchy(positions)
}, false),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
material: Cesium.Color.fromCssColorString('#ff0000').withAlpha(0.3),
},
// 绘制边界线,连接所有点和第一个点,形成闭合效果
polyline: {
positions: new Cesium.CallbackProperty(() => {
const positions = [...featurePositions]
// 添加当前鼠标位置作为最后一个点
if (
position.value &&
!position.value.equals(featurePositions[featurePositions.length - 1])
) {
positions.push(position.value)
}
// 如果有至少一个点,则连接到第一个点形成闭合线
if (featurePositions.length > 0 && featurePositions[0]) {
positions.push(featurePositions[0])
}
return positions
}, false),
// clampToGround: true, // 多边形边界线通常不需要 clampToGround因为多边形本身已经处理了高度
width: 2,
material: Cesium.Color.fromCssColorString('#ff0000'),
clampToGround: true,
},
})
viewer.entities.add(tempPolygon)
return new Promise((resolve, reject) => {
// 清理资源
const dispose = () => {
registerAbort(null) // 取消注册当前的 abort 回调
viewer.entities.remove(tempPolygon)
bus.offScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, handleAddPoint)
bus.offScreen(Cesium.ScreenSpaceEventType.RIGHT_CLICK, handleCancelDraw)
bus.offScreen(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, handleEndDraw)
bus.mode.value = ScreenMode.VIEW
}
// 取消绘制
const abort = (info) => {
dispose()
reject(info || '取消多边形绘制!')
}
// 左键加点
const handleAddPoint = () => {
if (position.value && !position.value.equals(featurePositions[featurePositions.length - 1])) {
featurePositions.push(position.value)
}
}
// 左键双击完成绘制
const handleEndDraw = () => {
// 双击时,如果鼠标位置与最后一个点不同,先添加当前点
handleAddPoint()
if (featurePositions.length < 3) {
// TODO: 替换为实际的错误提示方式
console.error('请保多边形至少有三个点!')
return
}
// 绘制完成的面积测量实体
measureLayer.entities.add({
position: getBoundingCenter(featurePositions),
label: {
text: `${getArea(featurePositions).toFixed(2)}平方米`,
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(8, 4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
polygon: {
hierarchy: [...featurePositions],
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
material: Cesium.Color.fromCssColorString('#ff0000').withAlpha(0.3),
},
// 绘制边界线,连接所有点和第一个点,形成闭合效果
polyline: {
positions: [...featurePositions, featurePositions[0]],
width: 2,
material: Cesium.Color.fromCssColorString('#ff0000'),
clampToGround: true,
},
})
dispose()
// 使用 setTimeout 避免立即 resolve 可能导致的事件冲突或其他问题
setTimeout(() => {
resolve(featurePositions)
}, 0)
}
// 右键取消绘制或删除最后一个点
const handleCancelDraw = () => {
if (featurePositions.length > 0) {
// 取消最后绘制的点
featurePositions.pop()
} else {
// 如果没有点,则取消整个绘制
abort()
}
}
// 注册当前的取消回调
registerAbort(abort)
// 绑定绘制相关事件
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, handleAddPoint)
bus.onScreen(Cesium.ScreenSpaceEventType.RIGHT_CLICK, handleCancelDraw)
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, handleEndDraw)
})
}

View File

@ -0,0 +1,183 @@
import * as Cesium from 'cesium'
import { getBoundingCenter, getDistance } from './utils'
// 距离测量
export const measureDistance = (deps) => {
const { viewer, bus, ScreenMode, position, measureLayer, registerAbort, globalAbort } = deps
// 如果在执行其它操作,则取消
globalAbort();
bus.mode.value = ScreenMode.DRAW;
const featurePositions = [];
/**
* 测距分段折线存储结构按绘制顺序排序
* {
* entity: 绘制完成对应折线部分的实体,
* distance: 绘制距离用于计算总距离
* }
*/
const subDistance = []
// 临时折线实体
const tempPolyline = new Cesium.Entity({
name: "__draw_temp_polyline",
position: new Cesium.CallbackProperty(() => {
if (featurePositions.length === 0) return null
// 获取最后一个位置和当前鼠标位置的中点,作为标签显示位置
// return getBoundingCenter([featurePositions[featurePositions.length - 1], position.value])
return position.value
}, false),
label: {
text: new Cesium.CallbackProperty(() => {
if (featurePositions.length === 0) return null
// 获取两个点之间的距离
const distance = getDistance([featurePositions[featurePositions.length - 1], position.value])
return `${distance.toFixed(2)}\n总距离:${(subDistance.reduce((total, d) => total + d.distance, 0) + distance).toFixed(2)}`;
}, false),
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(8, 4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
polyline: {
positions: new Cesium.CallbackProperty(() => {
if(featurePositions.length === 0) return null
const positions = [featurePositions[featurePositions.length - 1]]
// 添加当前鼠标位置作为最后一个点,形成动态效果
if (
position.value &&
!position.value.equals(
featurePositions[featurePositions.length - 1]
) // 避免重复添加同一个点
) {
positions.push(position.value);
}
if (positions.length < 2) return null
return positions;
}, false),
width: 2,
material: Cesium.Color.fromCssColorString("#FF0000"),
clampToGround: true,
},
});
viewer.entities.add(tempPolyline);
return new Promise((resolve, reject) => {
// 清理资源
const dispose = () => {
subDistance.length = 0
registerAbort(null); // 取消注册当前的 abort 回调
viewer.entities.remove(tempPolyline);
bus.offScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, handleAddPoint);
bus.offScreen(Cesium.ScreenSpaceEventType.RIGHT_CLICK, handleCancelDraw);
bus.offScreen(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, handleEndDraw);
bus.mode.value = ScreenMode.VIEW;
};
// 取消绘制
const abort = (info) => {
dispose();
reject(info || "取消折线绘制!");
};
// 左键加点
const handleAddPoint = () => {
if (
position.value &&
!position.value.equals(featurePositions[featurePositions.length - 1])
) {
featurePositions.push(position.value);
if(featurePositions.length > 1) {
const positions = [
featurePositions[featurePositions.length - 2],
featurePositions[featurePositions.length - 1],
];
// 当至少有2个点时添加最后2个点的折线
subDistance.push({
entity: measureLayer.entities.add(new Cesium.Entity({
position: getBoundingCenter(positions),
label: {
text: `${getDistance(positions).toFixed(2)}`,
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(8, 4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
polyline: {
positions,
width: 2,
material: Cesium.Color.fromCssColorString('#ff0000'),
clampToGround: true,
}
})),
distance: getDistance(positions),
})
}
}
};
// 左键双击完成绘制
const handleEndDraw = () => {
// 双击时,如果鼠标位置与最后一个点不同,先添加当前点
handleAddPoint();
if (featurePositions.length < 2) {
// TODO: 替换为实际的错误提示方式
console.error("请保证折线至少有两个点!");
return;
}
// 绘制总长标签
measureLayer.entities.add(new Cesium.Entity({
position: featurePositions[featurePositions.length - 1],
label: {
text: `总距离:${subDistance.reduce((total, d) => total + d.distance, 0).toFixed(2)}`,
font: '14px sans-serif',
pixelOffset: new Cesium.Cartesian2(0, -6),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
showBackground: true,
backgroundPadding: new Cesium.Cartesian2(8, 4),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
}
}))
dispose();
// 使用 setTimeout 避免立即 resolve 可能导致的事件冲突或其他问题
setTimeout(() => {
resolve(featurePositions);
}, 0);
};
// 右键取消绘制或删除最后一个点
const handleCancelDraw = () => {
if (featurePositions.length > 0) {
// 取消最后绘制的点
featurePositions.pop();
// 如果有已经绘制的测量线段,删除最后绘制的
if (subDistance.length > 0) {
measureLayer.entities.remove(subDistance.pop().entity);
}
} else {
// 如果没有点,则取消整个绘制
abort();
}
};
// 注册当前的取消回调
registerAbort(abort);
// 绑定绘制相关事件
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_CLICK, handleAddPoint);
bus.onScreen(Cesium.ScreenSpaceEventType.RIGHT_CLICK, handleCancelDraw);
bus.onScreen(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK, handleEndDraw);
});
};

View File

@ -0,0 +1,54 @@
import * as Cesium from 'cesium'
import * as turf from '@turf/turf'
/**
* 计算折线长度
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 折线长度单位米
*/
export const getDistance = (positions) => {
const line = turf.lineString(positions.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
}))
return turf.length(line, { units: 'kilometers' }) * 1000 // 返回米
}
/**
* 计算多边形面积
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 多边形面积单位平方米
*/
export const getArea = (positions) => {
const pts = [...positions, positions[0]] // 闭合多边形
const polygon = turf.polygon([pts.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
})])
return turf.area(polygon) // 返回平方米
}
/**
* 获取多个点的中心位置根据边界范围确定
* @param {Cesium.Cartesian3[]} positions 位置列表
* @param {number} height 返回位置的高度默认为0
* @returns 根据边界范围确定的中心点位置
*/
export const getBoundingCenter = (positions, height = 0) => {
const coord = getBoundingCenterCoordinate(positions)
return Cesium.Cartesian3.fromDegrees(coord[0], coord[1], height)
}
/**
* 获取多个点的中心位置坐标根据边界范围确定
* @param {Cesium.Cartesian3[]} positions 位置列表
* @returns 根据边界范围确定的中心点位置坐标格式为 [经度, 纬度]
*/
export const getBoundingCenterCoordinate = (positions) => {
const polygon = turf.lineString(positions.map((pos) => {
const cartographic = Cesium.Cartographic.fromCartesian(pos)
return [Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)]
}))
const centerFeature = turf.center(polygon)
return centerFeature.geometry.coordinates
}