最近在学习Cesium,简单做了一个示例,过程中也是各种坑,特此记录。有不对的地方请多多指教。
1.安装Cesium
npm install cesium@1.93 --save
2.webpack 配置
①配置webpack.base.conf.js
定义cesium源码路径:
const cesiumSource = '../node_modules/cesium/Source'
在module.exports中,output添加sourcePrefix:' ',让webpack正确处理多行字符串
module.exports = {
...
output: {
path: config.build.assetsRoot,
filename: '[name].js',
sourcePrefix: '', //Cesium 配置
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
...
}
在output后面,添加amd模式支持
module.exports = {
...
output: {
...
sourcePrefix: '', //Cesium 配置
...
},
//Cesium 配置
amd: {
toUrlUndefined: true
},
...
}
在resolve中设置cesium别名,引入的时候直接根据别名就可以找到cesium包了
module.exports = {
...
output: {
...
sourcePrefix: '', //Cesium 配置
},
//Cesium 配置
amd: {
toUrlUndefined: true
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'@': resolve('src'),
cesium: path.resolve(__dirname, cesiumSource) //Cesium 配置
}
},
...
}
module里添加unknownContextCritical:false,让webpack打印载入特定库时候告警
module.exports = {
output: {
...
sourcePrefix: '', //Cesium 配置
},
//Cesium 配置
amd: {
toUrlUndefined: true
},
resolve: {
...
cesium: path.resolve(__dirname, cesiumSource) //Cesium 配置
}
},
module: {
unknownContextCritical: false, //Cesium 配置
...
},
}
②配置webpack.dev.conf.js
配置路径:
//Cesium 配置
const cesiumSource = 'node_modules/cesium/Source'
const cesiumWorkers = '../Build/Cesium/Workers'
在plugins下面添加如下插件:
plugins: [
...
//Cesium 配置
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }
]),
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }
]),
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }
]),
new CopyWebpackPlugin([
{
from: path.join(cesiumSource, 'ThirdParty/Workers'),
to: 'ThirdParty/Workers'
}
]),
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('')
}),
//new CopyWebpackPlugin([ { from: path.join('./static', 'model'), to: 'model3D'}]),
]
③配置webpack.prod.conf.js文件
配置路径:
//Cesium 配置
const cesiumSource = 'node_modules/cesium/Source'
const cesiumWorkers = '../Build/Cesium/Workers'
在plugins下面添加如下插件,拷贝静态资源。与dev配置略有不同
//Cesium 配置
/* cesium */
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' }
]),
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, 'Assets'), to: 'Assets' }
]),
new CopyWebpackPlugin([
{ from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }
]),
new CopyWebpackPlugin([
{
from: path.join(cesiumSource, 'ThirdParty/Workers'),
to: 'ThirdParty/Workers'
}
]),
new webpack.DefinePlugin({
// Define relative base path in cesium for loading assets
// 定义 Cesium 从哪里加载资源,如果使用默认的'',却变成了绝对路径了,所以这里使用'./',使用相对路径
CESIUM_BASE_URL: JSON.stringify('./')
})
]
3.引用Cesium
import * as Cesium from 'cesium/Cesium'
import * as widget from "cesium/Widgets/widgets.css"
4.加载三维球
methods: {
// 实例cesium
getCesiumDemo() {
//在Cesium官网中自己申请
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiMTdmY2IwYi04YzBjLTQxMTctODhlOS0zMzRhNDI2ZDRjM2IiLCJpZCI6OTUzNzgsImlhdCI6MTY1MzYyMDY4Nn0.SDC6j-_vD_guLX5baRmhbfZC6pW3VnRjybvFytj2uvc'
this.CesiumObj = new Cesium.Viewer('cesiumDemo', {
animation: false, // 是否显示动画控件
baseLayerPicker: true, // 是否显示图层选择控件
vrButton: true, // 是否显示VR控件
geocoder: false, // 是否显示地名查找控件
timeline: false, // 是否显示时间线控件
sceneModePicker: true, // 是否显示投影方式控件
navigationHelpButton: true, // 是否显示帮助信息控件
navigationInstructionsInitiallyVisible: false, // 帮助按钮,初始化的时候是否展开
infoBox: true, // 是否显示点击要素之后显示的信息
fullscreenButton: true, // 是否显示全屏按钮
selectionIndicator: true, // 是否显示选中指示框
homeButton: true, // 是否显示返回主视角控件
scene3DOnly: false, // 如果设置为true,则所有几何图形以3D模式绘制以节约GPU资源
selectionIndicator : false, //不显示选中
infoBox : false, //不弹出box框
terrainProvider: Cesium.createWorldTerrain({
// 光照阴影
requestVertexNormals: true,
// 水流效果
requestWaterMask: true
}) // 显示地形
// terrainProvider: new Cesium.EllipsoidTerrainProvider({}) // 不显示地形
})
},
}
5.去掉logo
// 去除logo
this.CesiumObj.cesiumWidget.creditContainer.style.display = "none"; /* 隐藏cesium标志 */
6.界面控件汉化
参考了两个https://www.cnblogs.com/mazhenyu/p/15735438.html、https://blog.csdn.net/qq_42899245/article/details/114920944
// 汉化
this._local = new CesiumLocal(this.CesiumObj);
7.加载json数据
Load3DTiles(){
let tileset = new Cesium.Cesium3DTileset({
url: './data/tileset.json', // 相对路径
})
this.CesiumObj.scene.primitives.add(tileset) // 添加到球体
this.CesiumObj.zoomTo(tileset, new Cesium.HeadingPitchRange(0.0, -0.5, 2500)) //定位过去视角高度
},
8.记载shp数据
cesium不能直接加载shp数据,引用了CesiumVectorTile 库,还是有一些问题,知道如何正确使用的同学欢迎留言!谢谢!
LoadShp() {
// VectorTileImageryProvider = Cesium.VectorTileImageryProvider;
var worldLayer = null;
var worldProvider = new VectorTileImageryProvider({
source: "../../static/model/sheng.shp",
defaultStyle: {
outlineColor: "rgb(255,0,0)",
lineWidth: 1,
fill: false,
tileCacheSize: 200,
showMaker: false,
showCenterLabel: true,
fontColor: "rgba(255,0,0,1)",
labelOffsetX: -10,
labelOffsetY: -5,
fontSize: 13,
fontFamily: "黑体",
centerLabelPropertyName: "NAME"
},
maximumLevel: 20,
minimumLevel: 1,
simplify: false
});
worldProvider.readyPromise.then(function () {
worldLayer = this.CesiumObj.imageryLayers.addImageryProvider(worldProvider);
});
},
9.测距
测距也是引用了cesium-measure-es6.js库,参考https://blog.csdn.net/Fascinated0525/article/details/125559541
//界面部分,antd
<a-card title="三维量测面板" style="width: 800px">
<template #extra><a href="#">more</a></template>
<div>量测:
<a-button type="primary" @click="ClampToGround">不贴地</a-button>
<a-button type="primary" @click="DrawLineMeasure">空间距离</a-button>
<a-button type="primary" @click="DrawAreaMeasure">空间面积</a-button>
<a-button type="primary" @click="DrawTrianglesMeasure">三角量测</a-button>
</div>
<br>
<div>清除:
<a-button @click="ClearMeasure">清除量测</a-button>
</div>
</a-card>
//点击事件
let measure = new MeasureTool(this.CesiumObj);
//测距
DrawLineMeasure(){
// let measure = new CesiumMeasure(this.CesiumObj);
this.measure.drawLineMeasureGraphics({
clampToGround: this.clamp,
callback: () => {}
});
},
//空间面积
DrawAreaMeasure(){
// let measure = new MeasureTool(this.CesiumObj);
this.measure.drawAreaMeasureGraphics({
clampToGround: this.clamp,
callback: () => {}
});
},
// 三角测量
DrawTrianglesMeasure(){
// let measure = new MeasureTool(this.CesiumObj);
this.measure.drawTrianglesMeasureGraphics({
callback: () => {}
});
},
//清除测量结果
ClearMeasure(){
this.measure._drawLayer.entities.removeAll();
},
10.遇到的问题
①运行报错
"export 'default' (imported as 'Cesium') was not found in 'cesium/Cesium'
一般都是cesium没有引用对
② 添加测距功能时报错“Cesium is not defined”
cesium-measure-es6.js库中未引用Cesium。https://blog.csdn.net/weixin_45782925/article/details/122924146链接中所用的cesium-measure库在引入后总是出问题,还没有搞懂。
所有代码可参考:https://download.csdn.net/download/honey_Jessica/86657295