專案裝好後
1.安裝Cesium.js
yarn add cesium
2.設定vue.config.js
因為Cesium會去讀取"/Assets"和"/Workers"資料夾的內容
而且CESIUM_BASE_URL這個全域變數一定要先定義
所以要先把node_modules裡面的檔案copy一份到public去
const webpack = require('webpack')
const path = require('path')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const cesiumSource = './node_modules/cesium/Source'
module.exports = {
configureWebpack: {
plugins: [
new CopyWebpackPlugin([{
from: path.join(cesiumSource, '../Build/Cesium/Workers'),
to: 'Workers'
}]),
new CopyWebpackPlugin([{
from: path.join(cesiumSource, 'Assets'),
to: 'Assets'
}]),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('./')
})
]
}
}
3.把HelloWorld.vue改成這樣
<template>
<div class="hello">
<div id="cesiumContainer"></div>
</div>
</template>
<script>
const Cesium = require('cesium') //無法使用import方法
import 'cesium/Build/Cesium/Widgets/widgets.css'
export default {
mounted() {
this.initCesium()
},
methods: {
initCesium() {
let viewer = new Cesium.Viewer("cesiumContainer");
}
}
}
</script>
<style scoped>
#cesiumContainer{
width: 60vw;
height: 60vh;
}
</style>
4.yarn run serve後,地球出現啦
至此步驟的github
5.設定相機飛向台灣
至此步驟的github
export default {
data() {
return {
viewer: {},
taiwanPosition: {
latitude: 23.6978,
longitude: 120.9605
}
}
},
mounted() {
this.initCesium()
this.flyToTaiwan()
},
methods: {
initCesium() {
this.viewer = new Cesium.Viewer("cesiumContainer");
},
flyToTaiwan() {
let { latitude, longitude } = this.taiwanPosition
let height = 1000000
this.viewer.camera.flyTo({ destination: new Cesium.Cartesian3.fromDegrees(longitude, latitude, height) })
}
}
}
6.放一隻龍到地圖上
至官方範例下載tileset
https://github.com/CesiumGS/3d-tiles-samples
把tileset.json與b3dm檔放到public資料夾
(正常都會再起一個tile server,但本文為了示範,故先放在前端,用web server起)
mounted() {
this.initCesium()
this.addDragon()
},
methods: {
initCesium() {
this.viewer = new Cesium.Viewer("cesiumContainer");
},
addDragon() {
let myTileset = new Cesium.Cesium3DTileset({
url : '/my-dragon/tileset.json'
})
let tileset = this.viewer.scene.primitives.add(myTileset);
this.viewer.zoomTo(tileset);
},
這樣龍就出現啦
另外,還有一些靜態資源需要被放入public資料夾,故再修改一下vue.config.js
configureWebpack: {
plugins: [
new CopyWebpackPlugin([{
from: path.join(cesiumSource, '../Build/Cesium/Workers'),
to: 'Workers'
}]),
new CopyWebpackPlugin([{
from: path.join(cesiumSource, 'ThirdParty/Workers'),
to: 'ThirdParty/Workers'
}]),
new CopyWebpackPlugin([{
from: path.join(cesiumSource, 'Widgets'),
to: 'Widgets'
}]),
new CopyWebpackPlugin([{
from: path.join(cesiumSource, 'Assets'),
to: 'Assets'
}]),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('./')
})
]
}
至此步驟的github
7.但發現靠太近了,所以需要調整zoomTo的程度
先把heading pitch 與 range通通都歸零
至此步驟的github
addDragon() {
let myTileset = new Cesium.Cesium3DTileset({
url : '/my-dragon/tileset.json'
})
let tileset = this.viewer.scene.primitives.add(myTileset);
let heading = 0
let pitch = 0
let range = 0
this.viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(heading, pitch, range));
},
8.試著改變heading
9.試著改變pitch
9.試著改變range
10.由官方文件介紹可知
https://cesium.com/docs/cesiumjs-ref-doc/HeadingPitchRange.html
10.1.heading是偏航角,單位是弧度(0~2π)
2π大概是6.283....
上面gif示範的0.5大概是28°左右
10.2.pitch是俯仰角,單位是弧度(0~2π)
2π大概是6.283....
上面gif示範的0.5大概是28°左右
10.3.range是相機與目標中心點的距離,單位是公尺
上面gif示範大概是3000公尺可以看到全貌
11.若想在這條龍的中心點加一張圖片
import squirtleImage from '@/assets/squirtle.png'
export default {
....
mounted() {
this.initCesium()
this.addDragon()
this.addImageToDragonCenter()
},
methods: {
initCesium() {
this.viewer = new Cesium.Viewer("cesiumContainer");
},
addDragon() {
let myTileset = new Cesium.Cesium3DTileset({
url : '/my-dragon/tileset.json'
})
this.tileset = this.viewer.scene.primitives.add(myTileset);
let heading = 0
let pitch = 0
let range = 0
this.viewer.zoomTo(this.tileset, new Cesium.HeadingPitchRange(heading, pitch, range));
},
addImageToDragonCenter() {
this.tileset.readyPromise.then(() => {
let center = this.tileset.boundingSphere.center //龍的中心點
let newBillboardCollection = new Cesium.BillboardCollection()
let billboards = this.viewer.scene.primitives.add(newBillboardCollection)
billboards.add({
position: center,
image: squirtleImage
})
})
},
唉呀傑尼龜太大隻
至此步驟的github
12.修改一下長寬以後發現,他真得很中心耶
billboards.add({
position: center,
image: squirtleImage,
width : 50,
height : 100,
})
13.為了瞭解中心點以及怎麼調整,我印出了center的值
console.log(this.tileset.boundingSphere.center);
---------------------------------------------------------
Cartesian3
x: 1215107.7612304366
y: -4736682.902037748
z: 4081926.095098698
14.原來是一個Cartesian3(3D笛卡爾座標)
這是一個用x y z表示3D座標的概念
然後我發現官方文件有可以從經緯度轉成x y z的方法
https://cesium.com/docs/cesiumjs-ref-doc/Cartesian3.html
二話不說就把台北經緯度放進去
console.log(Cesium.Cartesian3.fromDegrees(121.5654, 25.0330));
---------------------------------------------------------
Cartesian3
x: -3026957.1459976556
y: 4926912.803821924
z: 2682387.0380952046
15.決定把傑尼龜從龍裡面拿出來
15.1先調整x軸
先調整視角
heading: 1.5
pitch: -1.5
喔原來x軸是這個方向
addDragon() {
let myTileset = new Cesium.Cesium3DTileset({
url : '/my-dragon/tileset.json'
})
this.tileset = this.viewer.scene.primitives.add(myTileset);
let heading = 1.5
let pitch = -1.5
let range = 0
this.viewer.zoomTo(this.tileset, new Cesium.HeadingPitchRange(heading, pitch, range));
},
addImageToDragonCenter() {
this.tileset.readyPromise.then(() => {
let center = this.tileset.boundingSphere.center //龍的中心點
let x = center.x + 500
let y = center.y
let z = center.z
let newCenter = new Cesium.Cartesian3(x, y, z)
let newBillboardCollection = new Cesium.BillboardCollection()
let billboards = this.viewer.scene.primitives.add(newBillboardCollection)
billboards.add({
position: newCenter,
image: squirtleImage,
width : 50,
height : 100,
})
})
},
15.2調整y軸
先調整視角
heading: 1.2
pitch: -0.5
15.3調整z軸
先調整視角
heading: 1.2
pitch: 0
至此步驟的github
下一篇: [3D地圖]了解笛卡爾座標系
沒有留言:
張貼留言