Cesium開發(fā)工具篇 | 05與第三方庫(kù)的集成

集成Three.js

Three.js是基于原生WebGL封裝運(yùn)行的三維引擎庫(kù),在所有WebGL引擎中,Three.js是國(guó)內(nèi)文資料最多、使用最廣泛的三維引擎。Three.js可應(yīng)用于Web 3D的可視化(如產(chǎn)品在線瀏覽、在線三維可視化等),H5/微信小程序游戲(如跳一跳),科教領(lǐng)域,機(jī)械領(lǐng)域,WebVR(VR看房、VR看車等)以及家裝室內(nèi)設(shè)計(jì)等方面,是一個(gè)比較輕量級(jí)的跨瀏覽器JavaScript庫(kù) ,適合在瀏覽器中創(chuàng)建和顯示動(dòng)畫3D計(jì)算機(jī)圖形。將Cesium的行星級(jí)渲染和GIS功能與Three.js廣泛而易用的通用3D API相結(jié)合,為新的WebGL體驗(yàn)開啟了許多可能性。兩者的集成總體思路如下:
(1)創(chuàng)建兩個(gè)容器,分別用于顯示cesium和three的場(chǎng)景
(2)初始化cesium、three渲染器
(3)調(diào)整three和cesium的渲染頻率保持一致
(4)調(diào)整three和cesium的相機(jī)位置角度保持一致
(5)加入要展示的圖形
以下展示了部分核心代碼。

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

  // 2-1.初始化cesium
  // cesium初始化時(shí),要將它的自動(dòng)渲染關(guān)掉(即useDefaultRenderLoop屬性調(diào)整為false)
  cesium.viewer = new Cesium.Viewer("cesiumContainer", {
    useDefaultRenderLoop: false, // 關(guān)閉自動(dòng)渲染
    ...
  });

   // 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.調(diào)整three和cesium的渲染頻率
   // 手動(dòng)開啟cesium和three的渲染,并放進(jìn)一個(gè)渲染頻率里。
   function loop() {
     requestAnimationFrame(loop);
     renderCesium();
     renderThreeObj();

   // 4.調(diào)整相機(jī)一致
   // 這里使用的cesium的相機(jī)為主相機(jī),使three的相機(jī)與cesium保持一致即可。
     renderCamera();
   }

// 5.加入要展示的圖形
   // 這里加入一個(gè)cesium的圖形polygon,再加入一個(gè)three的球體,以及一個(gè)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 是一個(gè)基于 JavaScript 的開源可視化圖表庫(kù),具有豐富的圖表類型,可用于地理數(shù)據(jù)可視化的地圖、熱力圖、線圖等。Cesium通過與Echarts的地理數(shù)據(jù)可視化能力相結(jié)合,大大增強(qiáng)Cesium整體的可視化效果。本文通過封裝EchartsLayer來實(shí)現(xiàn)遷徙圖的效果。需要注意的是,在圖表的option配置項(xiàng)中不需要寫geo,同時(shí)每個(gè)series數(shù)組中元素都必須加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);

簡(jiǎn)單效果圖如下所示:


集成heatmap

heatmap.js是一個(gè)輕量級(jí)的、最先進(jìn)的用于表達(dá)熱力圖的可視化前端庫(kù),比如人群分布情況、污染物濃度變化情況、信號(hào)強(qiáng)度等。感興趣的同學(xué)可以進(jìn)入官網(wǎng)https://www.patrick-wied.at/static/heatmapjs/ 查看詳情。
下面說一下cesium和heatmap集成的原理,其實(shí)也很簡(jiǎn)單,就是把使用heatmap.js生成的熱力圖,以貼圖材質(zhì)的方式賦給某個(gè)幾何圖形貼圖屬性。部分核心代碼如下:


   // 根據(jù)熱力圖圖片范圍,生成隨機(jī)熱力點(diǎn)和強(qiáng)度值
   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);
   }
   // 生成數(shù)據(jù)
   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);
   }

   // 創(chuàng)建熱力圖
   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,
       }),
     },
   });

效果圖如下:


2.png

集成Turf

Cesium本身更側(cè)重于三維可視化,在空間分析方面會(huì)顯得薄弱些,當(dāng)然空間分析能力可以借助開源postGIS中的函數(shù)去實(shí)現(xiàn),然后將結(jié)果通過Cesium去呈現(xiàn)。這里我們不對(duì)postGIS進(jìn)行介紹,而是給大家介紹一個(gè)輕量級(jí)的用于空間分析的前端庫(kù),即Turf。Turf的定位是地理空間分析庫(kù),處理各種地圖算法;特點(diǎn)是離線計(jì)算、模塊化、快速。下面是一個(gè)簡(jiǎn)單的示例:計(jì)算兩點(diǎn)之間的距離。

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

而下面的截圖是通過Turf、Cesium實(shí)現(xiàn)的點(diǎn)、線、面緩沖區(qū)分析結(jié)果,即借助了Turf的空間分析能力和Cesium的可視化能力。


3.png

部分核心代碼如下:

 // 初始化點(diǎn)緩沖
 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));
 }

 // 添加點(diǎn)
 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,
     },
   });
 }

如果你覺得比較麻煩的話,網(wǎng)上也有大神基于cesium、turf、shpjs、proj4js等這些庫(kù)文件封裝好了CesiumVectorTile,GitHub地址為https://github.com/engineerhe/CesiumVectorTile,支持小數(shù)據(jù)量的geojson、shape文件矢量動(dòng)態(tài)切片,并且還能實(shí)現(xiàn)貼地效果。
獲取上述全部源代碼可訪問本人GitHub地址:https://github.com/ls870061011。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容