在三维开发中,绘制实体、添加模型等都需要经纬度、高程这三个值,但有时会遇到给的数据只有经纬度,如此,我们便可以使用以下方法通过经纬度获取到高程
turf
改方法接收一个经纬度数组,且数组第一项和最后一项需对应
getHigh(latLogList) {
const turfPolygon = turf.polygon([latLogList]);
const turfExtent = turf.bbox(turfPolygon);
// 在turfPolygon中按网格取样点,网格间距3米
const turfSamplePoints = turf.pointGrid(turfExtent, 0.003, {
units: 'kilometers',
mask: turfPolygon,
});
// 将 turf取样点转为 Cesium取样点
const cesiumSamplePoints = [];
for (let i = 0; i < turfSamplePoints.features.length; i++) {
const coord = turfSamplePoints.features[i].geometry.coordinates;
cesiumSamplePoints.push(Cesium.Cartographic.fromDegrees(coord[0], coord[1]));
}
this.toolTip = new Custom.ToolTip(this.Global.viewer);
this.toolTip.start();
const promise = new Promise(res => {
// 获取取样点的高程,使用 11级 地形,级别越高越精确,但越耗时
res(Cesium.sampleTerrain(this.Global.viewer.terrainProvider, 11, cesiumSamplePoints))
})
promise.then(res => {
let highest = 0 // 最大高度
let lowest = 8888 // 最小高度
res.forEach(point => {
if (point.height > highest) {
highest = point.height.toFixed(3);
}
if (point.height < lowest) {
lowest = point.height.toFixed(3);
}
})
})
}
sampleTerrainMostDetailed、 sampleHeightMostDetailed
场景中同时存在模型和地形时,先调用取模型的高度,如果高度为 undefined 获取是较大的负值时,再调用取地形高度的方法,可以使点位高度尽量精准。值得注意的是,这两个方法都为 promise,是耗时操作,当点位太多时,会造成卡顿
// 在模型上获取高度
var c3 = new Cesium.Cartographic(
Cesium.Math.toRadians(lon),
Cesium.Math.toRadians(lat)
)
const promise = viewer.scene.sampleHeightMostDetailed([c3]);
promise.then((data) => {
console.log(data);
});
// 在地形上获取高度
var c3 = Cesium.Cartesian3.fromDegrees(lon, lat);
var position = []
position.push(Cesium.Cartographic.fromCartesian(c3))
const promise = Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [position])
promise.then((data) => {
console.log(data);
});
封装
const GetPositionBylonlat = (viewer, posArr) => {
return new Promise(function (resolve) {
let lonlat = []
posArr.forEach(item => {
lonlat.push(new Cesium.Cartographic(Cesium.Math.toRadians(item.lon), Cesium.Math.toRadians(item.lat)))
})
let finalArr = []
//模型上取点
const promise = viewer.scene.sampleHeightMostDetailed(lonlat);//这里可以传多个点
promise.then((data) => {
data.forEach((obj, index) => {
if (obj && obj.height) {
finalArr[index] = Cesium.Cartesian3.fromDegrees(posArr[index].lon, posArr[index].lat, obj.height)
} else {
finalArr[index] = []
}
})
});
//地形上取点
const promise1 = Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, lonlat);
promise1.then((data) => {
data.forEach((obj, index) => {
if (finalArr[index] && finalArr[index].height) {
//这里就是判断是不是已经在模型上取点
} else {
finalArr[index] = Cesium.Cartesian3.fromDegrees(posArr[index].lon, posArr[index].lat, obj.height)
}
})
resolve(finalArr)
});
})
}
GetPositionBylonlat(this.viewer, [{ lon: lon, lat: lat }]).then((res) => {})