Cesium中开启等高线渲染

54 篇文章 34 订阅
4 篇文章 2 订阅

最近接到一个需求,需要在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>

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

图片

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

图片

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

图片

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
Cesium是一种用于创建虚拟3D地球模型的JavaScript库。它可以用来指定区域等高线,即根据地形数据生成高程线来呈现地球上不同地区的高度差异。 在Cesium,制作区域等高线的第一步是获取高程数据。可以使用高程数据集,比如SRTM或DTM数据集,这些数据集提供了不同地区的高度信息。 一旦获取了高程数据,就可以使用Cesium的TerrainProvider来加载地形。TerrainProvider可以将高程数据转换为可视化的3D地形模型。通过指定区域等高线的经纬度范围,调用对应的TerrainProvider加载对应的地形数据。 在加载地形数据后,可以使用Cesium的Entity API来创建等高线。Entity API提供了创建和管理各种类型的图形实体的方法。可以使用Polyline等实体类型来创建等高线,设置对应的坐标、宽度、颜色等属性,以及连接不同高度的点,形成一条连续的等高线。 同时,Cesium还提供了丰富的样式和交互功能,可以通过修改实体的样式和交互事件来进一步定制等高线的外观和行为。比如可以修改实体的颜色、透明度,设置鼠标悬停时的交互效果等。 最后,通过将Cesium渲染到网页,可以在浏览器呈现出具有指定区域等高线的虚拟3D地球模型,用户可以通过鼠标和键盘与地球模型进行交互,查看不同地区的高度信息。这样,就实现了使用Cesium指定区域等高线的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜郎king

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值