vue2 使用 cesium 篇
今天好好寫一篇哈,之前寫的半死不活的,首先說明:這篇博文是我邊做邊寫的,小白也是,實作效果會同時發布截圖,如果沒有實作也會說明,僅僅作為技識訓累,選擇性分享,不做教學哈,不好別噴,
安裝 cesium
這個就很簡單,只需要一句簡簡單單的命令就可以實作在 vue 專案中安裝 cesium 了,
npm install cesium --save
然后等待安裝完成就可以了兄弟們!!

這個樣子嘞,就是安裝完成了,會開發 vue 的都曉得哈,

看一下依賴包里面,也成功下載了 cesium 的依賴,非常棒!!
接入專案 cesium
接下來就是使用,這個步驟很不好整,cesium 的官方檔案寫的很不友好,許多新手小白很難入門,甚至是理解都難,查檔案都不會,就比如我,但是!這里的步驟我都是自己測驗過可以的哈!首先呢,我是自己創建的 vue2 專案,使用的腳手架是 cli3 以上的,
首先第一步,從 node_modules 依賴包里面,找到我們剛剛安裝的 cesium ,在檔案夾里面有一個 Build 檔案夾,里面有一個 Cesium 檔案夾,把這個 Cesium 檔案夾復制一份,
然后呢,在專案的 public 檔案夾下,粘貼出來,

好的第一步完成!
然后第二步,在專案 index.html 檔案中,head 標簽里面,引入 cesium 的全域樣式,
<link rel="stylesheet" href="https://www.cnblogs.com/wjw1014/archive/2023/02/21/Cesium/Widgets/widgets.css">
還是在這個檔案中,在 body 最后,引入 cesium 原始碼,
<script type="text/javascript" src="https://www.cnblogs.com/wjw1014/archive/2023/02/21/Cesium/Cesium.js"></script>
就是下面這個樣子哈,

好的,完成之后我們重新啟動一下專案,記得哈,重啟一下專案!其實不重啟也可以,啊哈哈哈哈,
使用 cesium
接下來的作業就很簡單了嘛,我們寫一個頁面哈,用來顯示藍星,這個頁面就隨便寫了哈,沒有啥技術含量,咱就不啰嗦了,
<template>
<div id="my-map"></div>
</template>
<script>
export default {
name: "HomeView",
};
</script>
<style scoped>
#my-map {
width: 100%;
height: 100%;
background-color: black;
}
</style>
寫一個黑色的頁面,so 簡單哈!

非常好,效果出來了,到現在還沒有用到一點兒的 cesium 別急,下面開始哈,
我們寫一個 init() 方法,然后在 init() 方法里面呢,實作把這個 div 渲染成一個藍星,
init() {
this.viewer = new Cesium.Viewer('my-map', {
homeButton: false,
sceneModePicker: false,
baseLayerPicker: false, // 影像切換
animation: true, // 是否顯示影片控制元件
infoBox: false, // 是否顯示點擊要素之后顯示的資訊
selectionIndicator: false, // 要素選中框
geocoder: false, // 是否顯示地名查找控制元件
timeline: true, // 是否顯示時間線控制元件
fullscreenButton: false,
shouldAnimate: false,
navigationHelpButton: false, // 是否顯示幫助資訊控制元件
});
}
完成!藍星加載出來了!

這樣初始化藍星就差不多了是吧!好的下面說一些其他的事情,
cesium 相關資料
首先分享一些資料給各位,希望有用:
Cesium 官網:https://cesium.com/
Cesium 官網 API:https://cesium.com/learn/cesiumjs/ref-doc/
Cesium 中文API: http://cesium.xin/cesium/cn/Documentation1.62/
Cesium 官方案例:https://sandcastle.cesium.com/?
Cesium 技能樹:https://www.wenjiangs.com/doc/egyaeyav
Cesium 中文社區:http://cesium.xin/
3D 模型下載網站:https://sketchfab.com/feed
上邊這部分網站呢,也許對你有用,需要的話可以看一下,
優化上面代碼
為了保證代碼稍微稍微的整潔一點點,我們把 cesium 有關的代碼抽成一個 js 檔案哈,統一的放在一起,這樣的話呢,方便管理一下,嘿嘿!
首先在組件同級創建一個 js 檔案夾,里面放一個 TCesium.js 檔案,里面的代碼就是下面的樣子:
export class TCesium {
viewer = null;
scene = null;
/**
* 構造器函式:實體化cesium
* @param {*} dom 節點id
*/
constructor(dom) {
this.viewer = new Cesium.Viewer(dom, {
homeButton: false,
sceneModePicker: false,
baseLayerPicker: false, // 影像切換
animation: true, // 是否顯示影片控制元件
infoBox: false, // 是否顯示點擊要素之后顯示的資訊
selectionIndicator: false, // 要素選中框
geocoder: false, // 是否顯示地名查找控制元件
timeline: true, // 是否顯示時間線控制元件
fullscreenButton: false,
shouldAnimate: false,
navigationHelpButton: false, // 是否顯示幫助資訊控制元件
});
this.scene = this.viewer.scene
}
}
然后在組件中呢,引入一下這個檔案,
import { TCesium } from './js/TCesium'
然后嘞,init() 方法就可以直接實體化了,
init() {
this.mapObject = new TCesium('my-map') // 注意,這個my-map就是我們div的id
}
然后呢,效果是一樣的,

很棒!
cesium token 申請和設定
接下來我們說一下 cesium 的 token,使用cesium需要申請一個token值,這個地方就和百度地圖或者是高德地圖一樣,需要一個 token 秘鑰來進行操作,確保在使用 cesium 的程序中不會出現 token 過期造成地圖加載不出來的問題,當然了,現在看我們是一點問題沒有,藍星地球可以正常加載,但是隨著我們測驗撰寫的時間增長,呼叫 cesium 圖層次數過多,就會出現圖層加載不出來,就是超次數,這個是時候,我們地球可能就白了,因為沒有實時圖層回傳了,這個時候就需要 token,所以說我們現在就設定上 token,防止這種事情的發生,
首先我們需要去 cesium 官網去申請一個 token,方法很簡單:
cesium申請token請點擊 這里

然后嘞,輸入用戶名、密碼登錄一下子,沒有用戶名密碼的可以創建一個新的賬號來完成操作喲~!
然后就可以創建一個新的 token 來玩,

然后我們就成功的獲取到了一個 cesium 的秘鑰,太棒了親們!
然后我們在 TCesium.js 檔案中的構造器函式中,加載這個 token 就可以了,
Cesium.Ion.defaultAccessToken = '你申請的cesium的token'
就像下面這個樣子:

好的,這樣子的話, token 就申請使用完成了,
cesium 基礎配置
相關API
我們在上面的代碼配置了一些基本的設定項,稍微過一下子哈,
this.viewer = new Cesium.Viewer(dom, {
homeButton: false,
sceneModePicker: false,
baseLayerPicker: false, // 影像切換
animation: false, // 是否顯示影片控制元件
infoBox: false, // 是否顯示點擊要素之后顯示的資訊
selectionIndicator: false, // 要素選中框
geocoder: false, // 是否顯示地名查找控制元件
timeline: false, // 是否顯示時間線控制元件
fullscreenButton: false,
shouldAnimate: false,
navigationHelpButton: false, // 是否顯示幫助資訊控制元件
});
就是上面這一塊,我寫了幾個常用的,先全部設定為 false,就是不使用,我們稍微說幾個常用的看一下哈,
homeButton
我們先看 homeButton 引數,我們如果設定為 true,這個是主頁按鈕,啥意思呢,就是我們加載出藍星之后,我們可以滑鼠轉動嘛、放大縮小啥的,如果我們設定 homeButton 為 true 之后,在頁面的右上角就會出現一個主頁按鈕,當我們改變過藍星之后,點擊這個按鈕,會回到我們最開始的視角,

sceneModePicker
sceneModePicker 是地圖顯示的維度控制,他提供 二維平面 和 三維球體 兩種方式,當設定為 true 的時候,右上角會提供一個維度切換的按鈕,幫助我們進行藍星維度的展示切換功能,

baseLayerPicker
Cesium 為我們提供了一些底圖,這個 baseLayerPicker 設定為 true 的時候,右上角會有一個圖層切換的按鈕,但是我覺得沒用,不是沒用,不好用,一般都是自己寫,不用他默認提供的,

animation 和 timeline
這兩個是時間軸相關的,一般用不到,但是不保險,需要的時候沒有還真不行,這兩個要同時設定,true 的時候都 true,false 的時候都是 false,當然也不絕對哈,就是 timeline 的時候呢,就開始時間軸功能,animation 就是顯示時間軸的控制元件,可以直觀的控制時間軸的進度、速度之類的,

selectionIndicator
selectionIndicator 是要素選中框,啥意思呢,就比如說我的藍星上有模型,那么我點擊藍星上模型的時候呢,就會出現一個框框把模型給框住,我覺得沒必要,
fullscreenButton
這個是全屏按鈕,設定為 true 的時候呢,右下角就會出現一個全屏按鈕,點擊之后,cesium 就會進行全屏顯示,

infoBox
這個是要素資訊框,一般都是 false,啥呢,就是藍星上面有一個模型,點擊模型的時候會顯示這個模型的資訊之類的,一般不用他自帶的,一般是自己寫或者是自己改,一般設定 false 就可以,
geocoder
這個是地名查找組件,開啟后,右上角會出現一個查詢地址的組件,但是不好用,一般情況下,不顯示就行,

navigationHelpButton
這是一個幫助按鈕,如果設定為 true 的時候,右上角會有一個幫助的提示,這個關閉就可以,

好了,這就是常見的幾個設定,當然如果需要的話,可以根據官方檔案進行相應的設定,這個玩意兒很多設定,這只是其中幾個,
多余樣式隱藏
我們使用 cesium 的時候發現哈,左下角會有一些著作權資訊,我們想隱藏的話也很簡單,
只需要在 viewer 創建完成之后,把他的著作權 DOM 設定為 none 就可以了,
this.viewer._cesiumWidget._creditContainer.style.display = 'none'
這樣界面就干凈多了,除了藍星啥都沒有了,

地形資料
我們看到,我們加載的藍星是三維的,所以說嘞,和百度地圖、高德地圖不一樣,他能體現出一個地區的地形資料,比如說我們找一下四川山區那邊看一下子,

很明顯,看到了山地,我們在稍微放大一點兒,

盡管圖層顯示有山地,但是還想只是影像有山,但是實際上還是平面的!沒關系哈!我們可以向 cesium 中添加一下地形資料,這樣,他就是立體的了!
首先說明一下,我們添加的地形資料是公開的,不是私密的,也就是說,他可能不是很詳細很具體,但是是有的,比如有的單位需要做山東的 gis,那么人家會提供山東地形資料,這種資料肯定都是涉密的,這個資料相當具體,資料相當龐大,哪里高哪里底都很詳細,但是我們沒有,所以說呢,我們使用的,只能展示大概的地形,
怎么使用很簡單,我們在構造器函式中創建一個地形物件:
let terrain = new Cesium.createWorldTerrain({
requestWaterMask: true,
requestVertexNormals: true
})
創建完成,然后在 viewer 中把這個地形資料添加進去就可以了,
this.viewer.terrainProvider = terrain // 加入世界地形圖
好的,這個時候我們再來看一下山區能不能顯示出高度來,

誒!地形添加出來了! 厲害!
有兩個地方需要說一下,
this.viewer.scene.globe.depthTestAgainstTerrain = true // 地形遮擋
this.viewer.scene.postProcessStages.fxaa.enabled = true // 開啟抗鋸齒
首先第一個是地形遮擋,這是啥意思呢,就是說如果我們在藍星添加一個模型,如果這個模型被山體給擋住的話,那么這個模型就看不到了,不會透視的看到模型,在比如說,如果模型在地下,不在地表或者是地上,這個模型如果符合實際的話,應該不能被看到的,但是加載上發現我們能夠看到地底的模型,如果不想看到的話,開啟一下地形遮擋,這樣的話模型會被地形給擋起來,符合實際,
第二個是抗鋸齒,啥是抗鋸齒呢,做過 threejs 的應該接觸過,我解釋不好,意思就是渲染的更精致,當然性能消耗的也會大一些,
這兩個設定根據自己的實際情況選擇是否開啟哈,好了,不多說了,
添加第三方底圖
我們到現在使用的底圖都是 cesium 默認提供的,如果我們需要用自己的底圖也很簡單,無論是 geoserve 自己發布的還是 高德底圖 、百度底圖、天地圖底圖都是可以的,但是有一點需要說一下哈,就是這個高德、百度、google 底圖都是有偏移的,直接放進來可能會有偏差,所以說建議使用天地圖的,
我們先創建一個底圖物件,使用天地圖需要申請 tk 值,這個自己去申請,如果不會的話,看我關于天地圖的博文,里面有介紹和步驟,
// 矢量圖
TDT_SL = new Cesium.WebMapTileServiceImageryProvider({
url: 'http://{s}.tianditu.gov.cn/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=這是你申請的天地圖的tk值',
layer: 'vec',
style: 'default',
format: 'tiles',
tileMatrixSetID: 'w',
subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
maximumLevel: 18
})
然后創建完成添加到 cesium 就可以了,
// 添加天地圖矢量圖 (底圖物件,層級) 回傳圖層
this.TDL_YX_LAY = this.viewer.imageryLayers.addImageryProvider(this.TDL_SL, 1)
這樣就添加進來了,

放大看一下哈,當然,天地圖是中國的,所以說只有中國的詳細資訊,

都是可以的哈,移除的話也很簡單的啦,
this.viewer.imageryLayers.remove(this.TDL_YX_LAY) // 移除某個圖層(注意傳的引數)
或者
this.viewer.imageryLayers.removeAll(true) // 移除所有圖層并銷毀
相關檔案
好了,這就是關于添加第三方圖層相關操作了,
銷毀 cesium
創建說完了,現在說一下銷毀,銷毀的話就很簡單了,就是一句話:
this.viewer.destroy()
執行上面這句話就直接銷毀了,這個一般是組件注銷了,不展示 cesium 的時候使用,防止一直占用資源啥的,具體情況具體分析哈!
地圖放大縮小
其實 cesium 的放大縮小和百度地圖他們不一樣,cesium 的放大縮小其實就是相機高度,相機高度變小就是放大,相機高度變大就是縮小,理解吧?相機高了,視角大了,藍星上面東西就小了,
首先是放大:
/**
* 地圖放大
*/
zoomIn() {
// viewer 為 Viewer 物件
let position = this.viewer.camera.position;
let cameraHeight = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(position).height;
// 每次縮小 20 倍,引數可改
let moveRate = cameraHeight / 20.0;
this.viewer.camera.moveForward(moveRate);
}
然后是縮小:
/**
* 地圖縮小
*/
zoomOut() {
// viewer 為 Viewer 物件
let position = this.viewer.camera.position;
let cameraHeight = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(position).height;
// 每次縮小 20 倍,引數可改
let moveRate = cameraHeight / 20.0;
this.viewer.camera.moveBackward(moveRate);
}
道理都是一樣的!
可以寫兩個按鈕分別是“放大”和“縮小”,點擊按鈕的時候,執行這兩個方法就可以了!
獲取可視區域、高度、層級
獲取可視區域這個很簡單呀,一行代碼完事:
let rectangle = this.viewer.camera.computeViewRectangle();
我們可以看一下回傳的資料:

我們看到哈,列印出來的坐標不是地理坐標,轉換一下就可以了,
let rectangle = this.viewer.camera.computeViewRectangle();
let east = Cesium.Math.toDegrees(rectangle.east).toFixed(6); // 轉地理坐標
console.log(rectangle, east)

如果需要的話,挨個轉換一下也可以,
獲取相機高度的話更簡單了,
let height = Math.ceil(this.viewer.camera.positionCartographic.height).toFixed(0);
console.log("相機高度----->> ", height)
直接列印一下看結果:

這個單位是米哈,
然后是層級,就和百度高德一樣,層級顯示:
let zoom = this.heightToZoom(height).toFixed(0)
console.log("層級----->> ", zoom)
這是需要用到的一個方法,為啥里面是這樣,我也不知道,我也是從網上抄的這個方法:
heightToZoom(height) {
let A = 40487.57;
let B = 0.00007096758;
let C = 91610.74;
let D = -40467.74;
return Math.round(D + (A - D) / (1 + Math.pow(height / C, B)));
}
然后看一下結果:

真棒!
事件
接下來哈,說幾個常見的 cesium 事件,因為在展示藍星的時候,難免需要一些互動操作是吧!那么接下來,就是見證奇跡的時刻!!!!(其實也沒有那么神器)
----------- 未完待續 --------------
【著作權宣告】本博文著作權歸作者所有,任何形式的轉載都請聯系作者獲取授權并注明出處!【重要說明】博文僅作為本人的學習記錄,論點和觀點僅代表個人而不代表技術的真理,目的是自我學習和有幸成為可以向他人分享的經驗,因此有錯誤會虛心接受改正,但不代表此刻博文無誤!
【博客園地址】我是????. : http://www.cnblogs.com/wjw1014
【CSDN地址】我是????. : https://wjw1014.blog.csdn.net/
【Gitee地址】我是????. :https://gitee.com/wjw1014
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/544637.html
標籤:其他
上一篇:Map資料結構詳解
