Cesium通视分析
tip:利用两点间的插值计算,点A到点B之间,直线距离的高度是否大于地形高度为依据判断是否通视。
- 1、3Dtiles 的通视
const startPoint = car3ToLatLon(points[0]);
const endPoint = car3ToLatLon(points[1]);
// const h_asc = (startPoint.height >= endPoint.height) ? false : true; //两个点 哪个点高
const pointSum = this.pointsNum
let cartesians = new Array(pointSum), offset;
for (let i = 0; i < pointSum; ++i) {
offset = i / (pointSum - 1)
cartesians[i] = Cesium.Cartesian3.lerp(points[0], points[1], offset, new Cesium.Cartesian3())
}
const cartesians_clone = cartesians.map(d => d.clone())
//启动异步 Scene#clampToHeight查询3Dtitle下的位置信息高度等。
this.viewer.scene.clampToHeightMostDetailed(cartesians).then((clampedCartesians: Cesium.Cartesian3[])=> {
// 可视终点
let line_s_index = 0, position_updated:any,
p_update_degree, p_degree, heightArr = [], entityHeightArr = []
const length = clampedCartesians.length-1
for (let i = 1; i < length; i++) {
const position_updated = clampedCartesians[i];
p_update_degree = car3ToLatLon(position_updated)
p_degree = car3ToLatLon(cartesians_clone[i])
heightArr.push(p_degree.height)
entityHeightArr.push(p_update_degree.height)
}
this.heightArr = heightArr
this.entityHeightArr = entityHeightArr
for (let i = 1; i < length; i++) {
position_updated = clampedCartesians[i];
// 会有找不到的情况
if(!line_s_index && position_updated) {
p_update_degree = car3ToLatLon(position_updated)
p_degree = car3ToLatLon(cartesians_clone[i])
if (p_update_degree.height > p_degree.height) {
line_s_index = i;
break;
}
}
}
let line_e_index = line_s_index;
if (callback) {
this.isTrue = !!line_s_index
const labelText = `起点坐标:${startPoint.lon.toFixed(2)} | ${startPoint.lat.toFixed(2)}| ${startPoint.height.toFixed()}
\n终点坐标:${endPoint.lon.toFixed(2)} | ${endPoint.lat.toFixed(2)}| ${endPoint.height.toFixed()}
\n通视结果: ${line_s_index > 0 ? '否' : '是'}`
callback({
'line_s_end': cartesians_clone[line_s_index],
'line_e_start': cartesians_clone[line_e_index],
'labelResult': labelText
})
}
})
可以看到直线上每一个点的高度都比3D tiles上的高度高,顾能够看到。
2、基于DEM通视
tip:同理,比较地形上的高度,与线段上的高度。
// 获取经纬度
const startPoint = car3ToLatLon(points[0]);
const endPoint = car3ToLatLon(points[1]);
// const h_asc = (startPoint.height >= endPoint.height) ? false : true; //两个点 哪个点高
const pointSum = this.pointsNum
let pts:[number,number,number][] = []
let cartesians = new Array(pointSum);
let offset, x, y, height;
for (let i = 0; i< pointSum; ++i) {
offset = i / (pointSum - 1)
x = Cesium.Math.lerp(startPoint.lon, endPoint.lon, offset)
y = Cesium.Math.lerp(startPoint.lat, endPoint.lat, offset)
height = Cesium.Math.lerp(startPoint.height, endPoint.height, offset)
pts.push([x, y, height])
//使用提供的笛卡尔坐标计算t处的线性插值或外推(开始点,结束点,插值多少,存储在哪)
cartesians[i] = Cesium.Cartesian3.lerp(points[0], points[1], offset, new Cesium.Cartesian3())
}
const cartesians_clone = cartesians.map(d => d.clone())
const terrainProvider = Cesium.createWorldTerrain() //加载高程地址 可以是自定义的
const positions = pts.map(d=> Cesium.Cartographic.fromDegrees(...d))
//根据地形算某经纬点的高度
//查询完成后,可解析为提供的位置列表的承诺。这个 如果地形提供商的`availability`属性未定义,则promise将拒绝
const promise:any = Cesium.sampleTerrainMostDetailed(terrainProvider, positions);
(<any>Cesium).when(promise, (updatedPositions: any)=> {
//可视终点
let line_s_index = 0, position_updated = null, heightArr:number[] = [], entityHeightArr = [];
const length = updatedPositions.length-1
for (let i = 1; i < length; i++) {
const position_updated = updatedPositions[i]
entityHeightArr.push( position_updated.height)
heightArr.push(pts[i][2])
}
this.heightArr = heightArr
this.entityHeightArr = entityHeightArr
for (let i = 1; i < length; i++) {
position_updated = updatedPositions[i]
if(!line_s_index && position_updated && position_updated.height > pts[i][2]) {
line_s_index = i
break;
}
}
let line_e_index = line_s_index;
if (callback) {
this.isTrue = !!line_s_index
const labelText = `起点坐标:${startPoint.lon.toFixed(2)} | ${startPoint.lat.toFixed(2)}| ${startPoint.height.toFixed()}
\n终点坐标:${endPoint.lon.toFixed(2)} | ${endPoint.lat.toFixed(2)}| ${endPoint.height.toFixed()}
\n通视结果: ${line_s_index > 0 ? '否' : '是'}`
callback({
'line_s_end': cartesians_clone[line_s_index],
'line_e_start': cartesians_clone[line_e_index],
'labelResult': labelText
})
}
})
- 当然插值越多,计算出来的结果就越接近准确值。