/** 文件描述:空间分析方法 创建时间:2024/4/15 9:52 创建人:Zhaipeixiu */ import {getDistance, getElevation} from "@/utils/map/geocomputation.ts"; import {Cartesian3, Viewer} from "cesium"; type ProfileResult = { distanceArray:number[], elevationArray:number[], } /** * 两点间地形剖面分析数值计算 * @param viewer 地图Viewer * @param start 起点 * @param end 终点 * @param interval 线段采样间隔 m为单位 * @return 从起点至终点剖面线的海拔高度数组 */ export function elevationProfile(viewer: Viewer, start:Cartesian3, end:Cartesian3, interval: number) { let breakPointsHeight:number[] = [] //断点的高程m let distanceFromStart:number[] = [] //断点至起点的距离m // 计算首尾点距离 m let totalLen = getDistance(start, end) * 1000 // 获取起点高度 breakPointsHeight.push(getElevation(viewer, start)) distanceFromStart.push(0) //断点数量 let breakNum = Math.floor(totalLen/interval) // 如果采样间隔小于首尾点距离,则获取每个断点的坐标 并获取其高度 if(breakNum>=1){ for (let i = 1; i <= breakNum; i++) { let breakP = Cartesian3.lerp(start, end, i/breakNum, new Cartesian3()) breakPointsHeight.push(getElevation(viewer, breakP)) distanceFromStart.push(getDistance(start,breakP)*1000) } } // 获取终点高度 breakPointsHeight.push(getElevation(viewer, end)) distanceFromStart.push(totalLen) return { distanceArray:distanceFromStart, elevationArray:breakPointsHeight } } /** * 折线段地形剖面分析数值计算 * @param viewer 地图Viewer * @param polyline 折线点数组 * @param interval 线段采样间隔 m为单位 * @return 从折线起点至终点剖面线的海拔高度数组 */ export function profileAnalyse(viewer: Viewer, polyline:Cartesian3[],interval: number){ let result:ProfileResult = { distanceArray:[], elevationArray:[] } for (let i = 0; i < polyline.length - 2; i++) { let temp = elevationProfile(viewer,polyline[i],polyline[i+1],interval) result.elevationArray = result.elevationArray.concat(temp.elevationArray) result.distanceArray = result.distanceArray.concat(temp.distanceArray) } return result } /** * 两点间通视分析(基于最大斜率的算法)
* 返回值:通视为true,不通视为false,异常返回undefined * @param viewer 地图 * @param viewpoint 视点 * @param target 目标点 * @param h 视点地面抬高,默认为1m * @param breakNum 采样间隔,默认为100个断点 */ export function visibilityAnalyse(viewer: Viewer, viewpoint:Cartesian3, target:Cartesian3, h= 1, breakNum = 100) { // 获取视点高度和目标点高度 let viewpointH = getElevation(viewer, viewpoint) + h let targetH = getElevation(viewer, target) if (viewpointH === -9999.2024 + h ) { console.log("无法获取视点海拔高度!") return undefined } if (targetH === -9999.2024 ) { console.log("无法获取目标点海拔高度!") return undefined } // 计算首尾点距离 m let totalLen = getDistance(viewpoint, target) * 1000 // 计算首尾点斜率 let visibleK = (targetH - viewpointH)/totalLen // 逐个计算断点与视点的斜率 for (let i = 1; i <= breakNum; i++) { let breakP = Cartesian3.lerp(viewpoint, target, i/breakNum, new Cartesian3()) let breakPH = getElevation(viewer, breakP) //断点海拔 let breakPDis = getDistance(viewpoint,breakP)*1000 //断点与视点的距离 // 计算断点与视点的斜率 let breakPK = (breakPH-viewpointH)/breakPDis if(breakPK>visibleK){ return false } } return true }