1. 程式人生 > 其它 >vue 中使用 cesium

vue 中使用 cesium

vue 中使用 cesium

我是在 vue 專案裡面使用的 cesium,但是呢,有點問題,就是有些語法在js轉vue的時候有些許的限制,比如說js中相對路徑引入檔案是一切OK的,vue 也能解決,但是呢,在引入的檔案中又引用了其他的檔案,vue 處理起來就不是特別的好用,所以說,我是直接在 vue 檔案裡面使用 iframe 標籤引入的 html 檔案來實現接入的,而vue和iframe之間的通訊採用的 postMessage 方式實現,下面就稍微介紹一下。

vue專案引入cesium

這個相對來說簡單,我也在之前的部落格有介紹過,主要是下載cesiumjs包,然後這個包下載比較分時費力,所以說我整理了一下百度雲盤存了起來。

百度雲盤:連結:https://pan.baidu.com/s/1lf75yPi8XPPo5Y9YTvrVig
提取碼:0c7s

如果有需要的可以在這裡下載。

下載下來之後選擇一個自己需要的版本,然後放進 public 資料夾下就可以。

編寫 cesium 程式碼

開始已經說了,我是寫了一個html檔案,所有有關3D的東西全部在這個html檔案裡面實現的,所以說,最後需要我們將寫的程式碼檔案通過iframe標籤引入到vue專案當中去,其中有幾個注意的點,我來稍微強調一下。

首先第一個,這個html檔案就是一個普通的html檔案,按照官網的官方文件寫響應的程式碼就可以了,但是呢,關鍵是怎麼使用iframe標籤嵌入進我們的vue專案,首先強調,我是用的是cli3建立的專案,其他方式建立可靠性不確定,且下面的程式碼都是在我發文之前編寫demo測試通過的,截止到發文為止完全可靠!

編寫iframe標籤

這個就很簡單了,無非就是在需要引入3D的地方不寫詳細的程式碼了, 然後就是單純的寫一個iframe標籤,把編寫具體3D程式碼的html檔案引入進來就可以了。

下面是主要程式碼:

<iframe ref="iframeModel" src="/static/cesium.html" width="100%" height="100%" style="background-color: #070707;" frameborder="0">
</iframe>

ok,就是上面這一行程式碼就完事了,然後src寫的就是我們具體詳細程式碼的html檔案,引入進來就行了。

注意!!!

cli3 建立的vue專案,這個引入的本地 html 檔案一定、是一定要放在 public/static 資料夾下面,放在其他的地方不可以!!!而且,使用iframe標籤引入的時候,直接 /static/檔名.html 就可以,不這樣整,可能引入會報錯,也就是顯示不出來!切記切記!

然後就是編寫HTML檔案了,這個沒啥可以說的,正常編寫就可以,沒啥注意的。

在這個 html 檔案中引入cesiumjs 包,檔案路徑寫自己的哈,別直接粘,我們不一定一樣。

  <link rel="stylesheet" href="../Cesium/Widgets/widgets.css">
  <script type="text/javascript" src="../Cesium/Cesium.js"></script>

然後就是很常規的操作,簡單寫一下關鍵程式碼哈,不全,根據實際需要得改一下哈。

	// 初始化3D地圖
    viewer = new Cesium.Viewer('map', {
      baseLayerPicker: false,  // 影像切換
      animation: false,  //是否顯示動畫控制元件
      timeline: false, //是否顯示時間線控制元件
      infoBox: false, //是否顯示點選要素之後顯示的資訊
      geocoder: false, //是否顯示地名查詢控制元件
      navigationHelpButton: false, //是否顯示幫助資訊控制元件
      terrainProvider: new Cesium.CesiumTerrainProvider({   // 載入地形資訊
        url: 'https://www.supermapol.com/realspace/services/3D-stk_terrain/rest/realspace/datas/info/data/path',
        requestVertexNormals: true
      }),
    })

自定義地圖例項

// 新增mapbox自定義地圖例項
var layer = new Cesium.MapboxStyleImageryProvider({
  url: 'https://api.mapbox.com/styles/v1',
  username: 'username',
  styleId: '這裡是我的styleId',
  accessToken: '這個是我的accessToken',
  scaleFactor: true
});
viewer.imageryLayers.addImageryProvider(layer);

這個地方我稍微多說兩句哈,我們在做具體專案的時候吧,肯定不可能直接把預設的地圖樣式給渲染出來,因為設計不會這麼簡單就放過我們開發,對吧?所以說可能需要深色模式,或者是個性化的地圖底層,這個就很難整,不好搞,百度地圖和高德地圖甚至是天地圖,他們都可以設計個性化地圖,但是這些個性化地圖都只能在高德或者百度的產品裡面使用,在cesium中用不了,所以說,這個時候有一個相當牛逼的網站,可以提供在cesium中使用的個性化地圖,這個網站就是偉大的 —— mapbox。在這裡面可以建立、設計、釋出自己的個性化地圖給cesium使用,超級牛掰,就是國外的開啟可能有點慢,進去註冊,然後怎麼用,自己研究一下就可以了!


可以設定地圖的顏色,文字等很多東西。建立好自己的個性化地圖,就可以設定成公開的,然後就可以根據一些引數呼叫到這種設計好的個性化地圖,很淫性!自己慢慢研究,上面程式碼就是我引入的例子,但是關鍵地方我隱掉了,換成你的就OK了!

然後是載入模型,找模型太費勁了,開發一星期,有半星期都在找模型上,那麼沒錯,貼心的我也給各位準備了幾個測試的軍艦3D模型,均是gltf格式的,不需要轉化,貼心吧?

百度雲盤 連結:https://pan.baidu.com/s/1T1fYUBk-9J6VKmWA7r3Wag
提取碼:63y7

不想要軍艦?在推薦一個網址!操碎了心,稀碎啊!

sketchfab 進這個網站,模型收費很正常哈,不要抱怨,但是這裡面也有很多免費的,可能不是很好,但是測試完全夠用,註冊賬號,撒歡去吧!

    // 新增3D模型
    var scene = viewer.scene

    var hpr = new Cesium.HeadingPitchRoll(
      Cesium.Math.toRadians(45), // 設定這個屬性即可(順時針旋轉的角度值)
      Cesium.Math.toRadians(0),
      Cesium.Math.toRadians(0)
    );  // 設定方向角
    var origin = Cesium.Cartesian3.fromDegrees(117.70901, 38.781056, 0.0);   // 設定位置
    var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
      origin,
      hpr
    );
    var model = scene.primitives.add(new Cesium.Model.fromGltf({
      url: './models/rrv_rapid_response_vessel/scene.gltf', //gltf檔案的URL
      // url: './models/ces1/scene.gltf', //gltf檔案的URL
      modelMatrix: modelMatrix,
      color: new Cesium.Color(0, 0.9, 0.8, 0.5),  // 設定模型的顏色以及透明度
      scale: 1000.0     //放大倍數
    }))

設定相機飛入角度

    // 設定相機飛入視角
    viewer.camera.flyTo({
      destination: new Cesium.Cartesian3.fromDegrees(117.80901, 38.481056, 15000.0),     //相機飛入點
      orientation: {
        heading: 0,
        pitch: -0.5,
        roll: 0.0
      }
    })

設定相機視角,和上邊不要共用哈,不然衝突。

    // 設定相機角度
    // heading - 代表鏡頭左右方向, 正值為右, 負值為左, 360度和0度是一樣的
    // pitch - 代表鏡頭上下方向, 正值為上, 負值為下.
    // roll - 代表鏡頭左右傾斜.正值, 向右傾斜, 負值向左傾斜
    viewer.scene.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(117.80901, 38.481056, 15000.0),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-25),
        roll: Cesium.Math.toRadians(0)
      }
    });

完事!齊活!


當然了,我這是自己寫的測試Demo,有點簡陋有點醜,但是,只要你地圖設定的好,模型找的漂亮,你就真她孃的是個天才~

vue postMessage 通訊給 iframe

這個其實不是很難哈,直接百度就到手了,首先iframe向我最開始一樣寫,主要是有一個 ref

然後呢,直接上程式碼:

vue頁面

監聽接受

	mounted() {
      window.addEventListener('message', function (event) {
        //此處執行事件
        console.log('監聽到iframe資料--------> ', event.data)
      })
    },

傳送

	this.$nextTick(() => {
       this.$refs.iframeModel.contentWindow.postMessage({
         type: 'full'
       }, '*')
    })

iframe 頁面

window.addEventListener('message', function (e) {
    const da = e.data;
    console.log("接收到的資料---->> ", da )
 });

齊活了!

【版權宣告】本博文著作權歸作者所有,任何形式的轉載都請聯絡作者獲取授權並註明出處!
【重要說明】本文為本人的學習記錄,論點和觀點僅代表個人而不代表當時技術的真理,目的是自我學習和有幸成為可以向他人分享的經驗,因此有錯誤會虛心接受改正,但不代表此刻博文無誤!
【部落格園地址】JayveeWong: http://www.cnblogs.com/wjw1014
【CSDN地址】JayveeWong: https://blog.csdn.net/weixin_42776111
【Gitee地址】Jayvee:https://gitee.com/wjw1014
【GitHub地址】Jayvee:https://github.com/wjw1014