import * as Cesium from 'cesium'
|
import { MapTooltip } from './MapTooltip'
|
import { DrawPolygon } from './DrawPolygon'
|
/**
|
* 飞到中心点并且所有点在可视范围
|
* @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height]
|
* @param viewer Cesium.Viewer 实例
|
* @param multiple 缩放倍数-默认为4
|
* @param pitch 俯仰角-默认为-90
|
*/
|
function flyVisual({ positionsData, viewer, multiple = 4, pitch = -90 }) {
|
if (!Array.isArray(positionsData) || positionsData.length === 0) return
|
|
// 如果是一个点,加两个点方便后续生成外包围盒
|
if (positionsData.length === 1) {
|
const [lon, lat, height = 0] = positionsData[0]
|
positionsData = [
|
[lon + 0.001, lat + 0.001, height],
|
[lon - 0.001, lat - 0.001, height],
|
[lon, lat, height],
|
]
|
}
|
const positions = positionsData.map(([lon, lat, height = 0]) =>
|
Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat), Number(height || 0))
|
)
|
|
// 计算最高高度和中心点经纬度
|
let maxHeight = -Infinity
|
let sumLon = 0,
|
sumLat = 0
|
for (const [lon, lat, height] of positionsData) {
|
sumLon += Number(lon)
|
sumLat += Number(lat)
|
maxHeight = Math.max(maxHeight, Number(height || 0))
|
}
|
const centerLon = sumLon / positionsData.length
|
const centerLat = sumLat / positionsData.length
|
const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
|
// 暂时飞向 BoundingSphere
|
viewer.camera.flyToBoundingSphere(Cesium.BoundingSphere.fromPoints(positions), {
|
duration: 0,
|
offset: {
|
heading: Cesium.Math.toRadians(0),
|
pitch: Cesium.Math.toRadians(pitch),
|
range: boundingSphere.radius * multiple,
|
},
|
complete: () => {
|
// 飞行完成后检查相机高度是否小于最高点
|
const cameraHeight = Cesium.Cartographic.fromCartesian(viewer.camera.position).height
|
if (cameraHeight < maxHeight) {
|
viewer.camera.flyTo({
|
destination: Cesium.Cartesian3.fromDegrees(centerLon, centerLat, maxHeight + 100), // 加100米缓冲
|
duration: 1.5,
|
orientation: {
|
heading: viewer.camera.heading,
|
pitch: viewer.camera.pitch,
|
roll: viewer.camera.roll,
|
},
|
})
|
}
|
},
|
})
|
}
|
|
// 批量获取点数组经纬度对应高度信息
|
const getPointPositionsHeight = (data, viewer, droneHeight = null) => {
|
return new Promise((resolve, reject) => {
|
if (!data || !data.length) {
|
resolve([])
|
return
|
}
|
// 假设 viewer 已经初始化并且 terrainProvider 是有效的
|
const terrainProvider = viewer?.terrainProvider
|
// 创建 Cartographic 对象
|
const cartographics = data.map(item => {
|
const { lng, lat } = item
|
return Cesium.Cartographic.fromDegrees(Number(lng), Number(lat))
|
})
|
// 获取地形数据的Promise
|
const promise = Cesium.sampleTerrainMostDetailed(terrainProvider, cartographics)
|
// 使用 Cesium.when 处理 Promise
|
promise
|
.then(function (updatedPositions) {
|
// 是一个数组,包含更新后的 Cartographic 对象
|
const newPosition = updatedPositions.map((item, index) => {
|
const longitude = Cesium.Math.toDegrees(item.longitude)
|
const latitude = Cesium.Math.toDegrees(item.latitude)
|
let pointData = {
|
...data[index],
|
longitude,
|
latitude,
|
ASL: Number(item.height),
|
customHeight: Number(item.height),
|
}
|
if (droneHeight) pointData.TH = Number(item.height) + Number(droneHeight)
|
return pointData
|
})
|
resolve(newPosition)
|
})
|
.catch(function (error) {
|
console.log('获取高程时发生错误:', error)
|
resolve(data.map(item => ({ ...item, ASL: 0, customHeight: 0, longitude: item.lng, latitude: item.lat })))
|
})
|
})
|
}
|
|
export { MapTooltip, flyVisual, getPointPositionsHeight, DrawPolygon }
|