最近接到一个需求,需要在Cesium中基于实时地形开启等高线效果,让用户可以看到真实效果。在网上看了一些资料,许多都是需要付费的或者不提供源码,于是在cesium官网找到了示例代码,以下将具体介绍如何在cesium中进行集成。
第一步:设置viewer开启光照
viewer.scene.globe.enableLighting = true;
第二步:定义等高线初始值
var minHeight = -414.0; // approximate dead sea elevation
var maxHeight = 8777.0; // approximate everest elevation
var contourColor = Cesium.Color.RED.clone();
var contourUniforms = {};
var shadingUniforms = {};
第三步:定义相关处理函数
function getElevationContourMaterial() {
// Creates a composite material with both elevation shading and contour lines
return new Cesium.Material({
fabric: {
type: "ElevationColorContour",
materials: {
contourMaterial: {
type: "ElevationContour",
},
elevationRampMaterial: {
type: "ElevationRamp",
},
},
components: {
diffuse:
"contourMaterial.alpha == 0.0 ? elevationRampMaterial.diffuse : contourMaterial.diffuse",
alpha:
"max(contourMaterial.alpha, elevationRampMaterial.alpha)",
},
},
translucent: false,
});
}
var elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0];
var slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2) / 2, 0.87, 0.91, 1.0];
var aspectRamp = [0.0, 0.2, 0.4, 0.6, 0.8, 0.9, 1.0];
function getColorRamp(selectedShading) {
var ramp = document.createElement("canvas");
ramp.width = 100;
ramp.height = 1;
var ctx = ramp.getContext("2d");
var values;
if (selectedShading === "elevation") {
values = elevationRamp;
} else if (selectedShading === "slope") {
values = slopeRamp;
} else if (selectedShading === "aspect") {
values = aspectRamp;
}
var grd = ctx.createLinearGradient(0, 0, 100, 0);
grd.addColorStop(values[0], "#000000"); //black
grd.addColorStop(values[1], "#2747E0"); //blue
grd.addColorStop(values[2], "#D33B7D"); //pink
grd.addColorStop(values[3], "#D33038"); //red
grd.addColorStop(values[4], "#FF9742"); //orange
grd.addColorStop(values[5], "#ffd700"); //yellow
grd.addColorStop(values[6], "#ffffff"); //white
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 100, 1);
return ramp;
}
// The viewModel tracks the state of our mini application.
var viewModel = {
enableContour: false,
contourSpacing: 50.0,
contourWidth: 2.0,
selectedShading: "none",
changeColor: function () {
contourUniforms.color = Cesium.Color.fromRandom(
{ alpha: 1.0 },
contourColor
);
},
};
// Convert the viewModel members into knockout observables.
Cesium.knockout.track(viewModel);
// Bind the viewModel to the DOM elements of the UI that call for it.
var toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);
function updateMaterial() {
var hasContour = viewModel.enableContour;
var selectedShading = viewModel.selectedShading;
var globe = viewer.scene.globe;
var material;
if (hasContour) {
if (selectedShading === "elevation") {
material = getElevationContourMaterial();
shadingUniforms = material.materials.elevationRampMaterial.uniforms;
shadingUniforms.minimumHeight = minHeight;
shadingUniforms.maximumHeight = maxHeight;
contourUniforms = material.materials.contourMaterial.uniforms;
}else {
material = Cesium.Material.fromType("ElevationContour");
contourUniforms = material.uniforms;
}
contourUniforms.width = viewModel.contourWidth;
contourUniforms.spacing = viewModel.contourSpacing;
contourUniforms.color = contourColor;
} else if (selectedShading === "elevation") {
material = Cesium.Material.fromType("ElevationRamp");
shadingUniforms = material.uniforms;
shadingUniforms.minimumHeight = minHeight;
shadingUniforms.maximumHeight = maxHeight;
}
if (selectedShading !== "none") {
shadingUniforms.image = getColorRamp(selectedShading);
}
globe.material = material;
}
updateMaterial();
Cesium.knockout.getObservable(viewModel, "enableContour").subscribe(function (newValue) {
updateMaterial();
});
Cesium.knockout.getObservable(viewModel, "contourWidth").subscribe(function (newValue) {
contourUniforms.width = parseFloat(newValue);
});
Cesium.knockout.getObservable(viewModel, "contourSpacing").subscribe(function (newValue) {
contourUniforms.spacing = parseFloat(newValue);
});
Cesium.knockout.getObservable(viewModel, "selectedShading").subscribe(function (value) {
updateMaterial();
});
第四步:绑定页面控件
<div class="demo-container">
<label><input type="radio" name="shadingMaterials"
value="none" data-bind="checked: selectedShading">无渲染</label> <label><input
type="radio" name="shadingMaterials" value="elevation"
data-bind="checked: selectedShading">高程渲染</label>
</div>
<div class="demo-container">
<div>
<label><input type="checkbox"
data-bind="checked: enableContour">等高线</label>
</div>
<div>
高程 <input
type="range" min="1.0" max="500.0" step="1.0"
data-bind="value: contourSpacing, valueUpdate: 'input', enable: enableContour">
<span data-bind="text: contourSpacing"></span>m
</div>
<div>
线宽 <input
type="range" min="1.0" max="10.0" step="1.0"
data-bind="value: contourWidth, valueUpdate: 'input', enable: enableContour">
<span data-bind="text: contourWidth"></span>px
</div>
<div>
<button type="button"
data-bind="click: changeColor, enable: enableContour">颜色</button>
</div>
</div>
完成上述代码后,运行页面即可看到如下效果:
点击等高线,即可看到效果
还可以开启高程渲染效果: