Cesium中开启等高线渲染

最近接到一个需求,需要在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 style="width: 136px; float: left; width: 100px;"
        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 style="width: 125px; float: left; width: 100px;"
        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>

完成上述代码后,运行页面即可看到如下效果:

图片

点击等高线,即可看到效果

图片

还可以开启高程渲染效果:

图片

Guess you like

Origin blog.csdn.net/yelangkingwuzuhu/article/details/116420079