| | |
| | | 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) { |
| | | // updatedPositions 是一个数组,包含更新后的 Cartographic 对象 |
| | | // 是一个数组,包含更新后的 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, |
| | |
| | | ASL: Number(item.height), |
| | | customHeight: Number(item.height), |
| | | } |
| | | |
| | | if (droneHeight) pointData.TH = Number(item.height) + Number(droneHeight) |
| | | |
| | | return pointData |
| | | }) |
| | | |
| | | resolve(newPosition) |
| | | // 在这里,你可以使用 height 值进行后续操作 |
| | | }) |
| | | .catch(function (error) { |
| | | // console.error('获取高程时发生错误:', error); |
| | | reject(error) |
| | | console.log('获取高程时发生错误:', error) |
| | | resolve(data.map(item => ({ ...item, ASL: 0, customHeight: 0, longitude: item.lng, latitude: item.lat }))) |
| | | }) |
| | | }) |
| | | } |
| | |
| | | //有相交 |
| | | return true |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 飞到中心点并且所有点在可视范围 |
| | | * @param positionsData 二维数组,每项为 [lon, lat] 或 三维数组 [lon, lat, height] |
| | | * @param viewer Cesium.Viewer 实例 |
| | | * @param multiple 缩放倍数-默认为4 |
| | | * @param pitch 俯仰角-默认为-90 |
| | | */ |
| | | export 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, |
| | | }, |
| | | }) |
| | | } |
| | | }, |
| | | }) |
| | | } |
| | | |
| | | // 获取视口地图中心点 |