话不多说,随便介绍一下,本来以为只能修改shader,后来发现turf有等高线,但区域坡度坡向估计还是要学习webgl,或者直接用超图或者火星。。。
核心
采用第三方库turf(turf文档)绘制等值线,控制点通过turf.pointGrid生成,再计算控制点高度,最后通过turf.isolines生成等值线geojson。
注意点:示例代码中通过示例区域展示,需要先将视角切换到对应区域,渲染出示例区域的地形才能计算高度,再生成等高线。
源码
addContour(extent) {
// 创建等值线区域
// let extent = [120, 30, 120.1, 30.1];
let heightArr = [];
// 等高线生成效果与控制点是否精细有关
let pointGrid = turf.pointGrid(extent, 0.001, {
units: "degrees",
});
console.log(pointGrid.features, "pointGrid.features");
for (let i = 0; i < pointGrid.features.length; i++) {
heightArr.push(
Cesium.Cartographic.fromDegrees(
pointGrid.features[i].geometry.coordinates[0],
pointGrid.features[i].geometry.coordinates[1]
)
);
}
Cesium.sampleTerrainMostDetailed(
viewer.scene.terrainProvider,
heightArr
).then((updatePositions) => {
console.log(updatePositions, "updatePositions");
let testArr = [];
let breaks = [];
for (let i = 0; i < pointGrid.features.length; i++) {
pointGrid.features[i].properties.height = updatePositions[i].height;
testArr.push(updatePositions[i].height);
}
// 取最大值和最小值
testArr.sort((a, b) => {
return a - b;
});
// 根据计算的高度集合最大最小值等分等高线等级
let testLength = (testArr[testArr.length - 1] - testArr[0]) / 10;
for (let i = 0; i < 10; i++) {
breaks.push(testArr[0] + i * testLength);
}
//等值线等级
// let breaks = [
// 0, 20, 30, 50, 60, 80, 90, 110, 120, 130, 150, 160, 170, 180, 200, 210,
// 230, 240, 250, 260, 280, 290, 300, 500, 600, 800, 900, 1000,
// ];
let lines = turf.isolines(pointGrid, breaks, {
zProperty: "height",
});
//平滑线
let lineFeatures = lines.features;
lineFeatures.forEach((feature) => {
let coords = feature.geometry.coordinates;
let lineCoords = [];
coords.forEach((coord) => {
let line = turf.lineString(coord);
let curve = turf.bezierSpline(line);
lineCoords.push(curve.geometry.coordinates);
});
feature.geometry.coordinates = lineCoords;
});
// cesium 加载geojson
let contourSource = Cesium.GeoJsonDataSource.load(lines, {
stroke: Cesium.Color.RED,
strokeWidth: 3,
fill: Cesium.Color.RED,
extruded: true,
// 贴地
clampToGround: true,
});
viewer.dataSources.add(contourSource);
});
}
改进
网上随便找个绘制区域的代码,再根据turf.bbox计算绘制多边形的包围矩形作为extent,就能实现画矩形生成等高线了。
加label和区分颜色直接操作contourSource里的entity应该就可以,具体我也没搞