Cesium开发工具篇 | 05与第三方库的集成

集成Three.js

Three.js是基于原生WebGL封装运行的三维引擎库,在所有WebGL引擎中,Three.js是国内文资料最多、使用最广泛的三维引擎。Three.js可应用于Web 3D的可视化(如产品在线浏览、在线三维可视化等),H5/微信小程序游戏(如跳一跳),科教领域,机械领域,WebVR(VR看房、VR看车等)以及家装室内设计等方面,是一个比较轻量级的跨浏览器JavaScript库 ,适合在浏览器中创建和显示动画3D计算机图形。将Cesium的行星级渲染和GIS功能与Three.js广泛而易用的通用3D API相结合,为新的WebGL体验开启了许多可能性。两者的集成总体思路如下:

(1)创建两个容器,分别用于显示cesium和three的场景

(2)初始化cesium、three渲染器

(3)调整three和cesium的渲染频率保持一致

(4)调整three和cesium的相机位置角度保持一致

(5)加入要展示的图形
以下展示了部分核心代码。

    <div id="cesiumContainer"></div>
    <div id="ThreeContainer"></div>

     // 2-1.初始化cesium
     // cesium初始化时,要将它的自动渲染关掉(即useDefaultRenderLoop属性调整为false)
     cesium.viewer = new Cesium.Viewer("cesiumContainer", {
       useDefaultRenderLoop: false, // 关闭自动渲染
       ...
     });

      // 2-2.初始化three
      function initThree() {
        let fov = 45;
        let width = window.innerWidth;
        let height = window.innerHeight;
        let aspect = width / height;
        let near = 1;
        let far = 10 * 1000 * 1000; // needs to be far to support Cesium's world-scale rendering
        three.scene = new THREE.Scene();
        three.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
        three.renderer = new THREE.WebGLRenderer({ alpha: true });        ThreeContainer.appendChild(three.renderer.domElement);
      }

      // 3.调整three和cesium的渲染频率
      // 手动开启cesium和three的渲染,并放进一个渲染频率里。
      function loop() {
        requestAnimationFrame(loop);
        renderCesium();
        renderThreeObj();

      // 4.调整相机一致
      // 这里使用的cesium的相机为主相机,使three的相机与cesium保持一致即可。
        renderCamera();
      }

 // 5.加入要展示的图形
      // 这里加入一个cesium的图形polygon,再加入一个three的球体,以及一个three的12面体。
      function init3DObject() {
        let entity = {
          name: "Polygon",
          polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
              minWGS84[0],
              minWGS84[1],
              maxWGS84[0],
              minWGS84[1],
              maxWGS84[0],
              maxWGS84[1],
              minWGS84[0],
              maxWGS84[1],
            ]),
            material: Cesium.Color.RED.withAlpha(0.1),
          },
        };
        let Polypon = cesium.viewer.entities.add(entity);
        let doubleSideMaterial = new THREE.MeshNormalMaterial({
          side: THREE.DoubleSide,
        });

        geometry = new THREE.SphereGeometry(1, 32, 32);
        let sphere = new THREE.Mesh(
          geometry,
          new THREE.MeshPhongMaterial({
            color: 0xffffff,
            side: THREE.DoubleSide,
          })
        ); //12面体
        ...         

        }
      }

效果图如下:

集成Echarts

Echarts 是一个基于 JavaScript 的开源可视化图表库,具有丰富的图表类型,可用于地理数据可视化的地图、热力图、线图等。Cesium通过与Echarts的地理数据可视化能力相结合,大大增强Cesium整体的可视化效果。本文通过封装EchartsLayer来实现迁徙图的效果。需要注意的是,在图表的option配置项中不需要写geo,同时每个series数组中元素都必须加coordinateSystem:‘GLMap’。部分核心代码如下:

var EchartsLayer = function (map, options) {
  this._map = map;
  this._overlay = this._createChartOverlay();
  if (options) {
    this._registerMap();
  }
  this._overlay.setOption(options || {});
};

let _echartLayer = new EchartsLayer(viewer, option);

简单效果图如下所示:

集成heatmap

heatmap.js是一个轻量级的、最先进的用于表达热力图的可视化前端库,比如人群分布情况、污染物浓度变化情况、信号强度等。感兴趣的同学可以进入官网https://www.patrick-wied.at/static/heatmapjs/ 查看详情。
下面说一下cesium和heatmap集成的原理,其实也很简单,就是把使用heatmap.js生成的热力图,以贴图材质的方式赋给某个几何图形贴图属性。部分核心代码如下:

    // 根据热力图图片范围,生成随机热力点和强度值
    var dataRaw = [];
    for (var i = 0; i < len; i++) {
      var point = {
        lat: latMin + Math.random() * (latMax - latMin),
        lon: lonMin + Math.random() * (lonMax - lonMin),
        value: Math.floor(Math.random() * 100),
      };
      dataRaw.push(point);
    }
    // 生成数据
    for (var i = 0; i < len; i++) {
      var dataItem = dataRaw[i];
      var point = {
        x: Math.floor(((dataItem.lat - latMin) / (latMax - latMin)) * width),
        y: Math.floor(((dataItem.lon - lonMin) / (lonMax - lonMin)) * height),
        value: Math.floor(dataItem.value),
      };
      max = Math.max(max, dataItem.value);
      points.push(point);
    }

    // 创建热力图
    var heatmapInstance = h337.create({
      container: document.querySelector(".heatmap"),
    });

    var data = {
      max: max,
      data: points,
    };
    heatmapInstance.setData(data);

 // 将热力图添加到球体上(生成的热力图canvas元素类名为heatmap-canvas)
    var canvas = document.getElementsByClassName("heatmap-canvas");
    // console.log(canvas);
    viewer.entities.add({
      name: "heatmap",
      rectangle: {
        coordinates: Cesium.Rectangle.fromDegrees(
          lonMin,
          latMin,
          lonMax,
          latMax
        ),
        material: new Cesium.ImageMaterialProperty({
          image: canvas[0],
          transparent: true,
        }),
      },
    });

效果图如下:

集成Turf

Cesium本身更侧重于三维可视化,在空间分析方面会显得薄弱些,当然空间分析能力可以借助开源postGIS中的函数去实现,然后将结果通过Cesium去呈现。这里我们不对postGIS进行介绍,而是给大家介绍一个轻量级的用于空间分析的前端库,即Turf。Turf的定位是地理空间分析库,处理各种地图算法;特点是离线计算、模块化、快速。下面是一个简单的示例:计算两点之间的距离。

var point1 = turf.point([144.834823, -37.771257]);
var point2 = turf.point([145.14244, -37.830937]);
var midpoint = turf.midpoint(point1, point2);

而下面的截图是通过Turf、Cesium实现的点、线、面缓冲区分析结果,即借助了Turf的空间分析能力和Cesium的可视化能力。

部分核心代码如下:

 // 初始化点缓冲
    function initPointBuffer() {
      let point = [106.422638966289, 29.5698367125623];
      addPoint(point);

      let pointF = turf.point(point);
      let buffered = turf.buffer(pointF, 60, { units: "meters" });
      let coordinates = buffered.geometry.coordinates;
      let points = coordinates[0];
      let degreesArray = pointsToDegreesArray(points);
      addBufferPolyogn(Cesium.Cartesian3.fromDegreesArray(degreesArray));
    }

    // 添加点
    function addPoint(point) {
      viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(point[0], point[1], 0),
        point: {
          pixelSize: 10,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          color: Cesium.Color.YELLOW,
          outlineWidth: 3,
          outlineColor: Cesium.Color.YELLOW.withAlpha(0.4),
        },
      });
    }
 // 添加缓冲面
    function addBufferPolyogn(positions) {
      viewer.entities.add({
        polygon: {
          hierarchy: new Cesium.PolygonHierarchy(positions),
          material: Cesium.Color.RED.withAlpha(0.6),
          classificationType: Cesium.ClassificationType.BOTH,
        },
      });
    }

如果你觉得比较麻烦的话,网上也有大神基于cesium、turf、shpjs、proj4js等这些库文件封装好了CesiumVectorTile,GitHub地址为https://github.com/engineerhe/CesiumVectorTile,支持小数据量的geojson、shape文件矢量动态切片,并且还能实现贴地效果。

获取上述全部源代码可访问本人GitHub地址:https://github.com/ls870061011


微信扫描下方二维码,获取更多资讯。

微信公众号二维码

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

暮紫月升

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

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

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

打赏作者

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

抵扣说明:

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

余额充值