Vue 第三方集成之 Cesium
最近项目有三维地图展示需求,甲方提供了三维数据,要求使用Cesium集成。利用一天时间集中突击了一下做个笔记,后面再用到的话也好自查。声明一下,作者也是最近刚接触cesium,目前的探索也只是作为初学者一个导引吧,避免少走弯路。不喜勿喷,谢谢。资源官网地址:https://cesium.com/platform/文档示例很多,API也很全,就是全部英文看起来费劲,建议深度学习可以看看。GitHub
最近项目有三维地图展示需求,甲方提供了三维数据,要求使用Cesium集成。
利用一天时间集中突击了一下做个笔记,后面再用到的话也好自查。
声明一下,作者也是最近刚接触cesium,目前的探索也只是作为初学者一个导引吧,避免少走弯路。不喜勿喷,谢谢。
资源
官网地址:https://cesium.com/platform/
文档示例很多,API也很全,就是全部英文看起来费劲,建议深度学习可以看看。
GitHub地址:https://github.com/CesiumGS
有几个JavaScript分类的demo可以看看,因为做vue集成,作者参考了一下:
cesium-webpack-example 这个demo,其它的建议深度学习可以看一下。
Cesium ion
在开始之前先引入个Cesium ion,这是官方提供的一个云服务,用来上传自己的图形文件,也提供了几个资源供大家使用,作者自己写的demo用的就是官方提供的。
页面长这个样子:
有几个页签:
stories
个人理解是一个地图制作工具,可以根据自己的需求并且加入自己上传过的资源,制作完成以后可以生成访问链接,具体操作步骤官方有教程: stories生成步骤
我这里简单做了一个,保存以后可以看到生成了id和访问地址。不过这里有个问题,在自己项目中本地打开页面会跨域错误,还需要自行配置代理。
My Assets
这里是用户上传资源的地方,可以上传3dtiles和其它类型文件,同时这里上传的资源可以在前面的stories里面使用的。
下图我并没有上传我的资源,这些事cesium官方提供的几个地图,做demo的时候会用到其中的资源。
Access Token
作为认证使用,以便自己上传的资源不被他人盗用,很关键,在使用云平台资源的时候代码中会用到。
CesiumJS
介绍完云平台,下面该进入主题了,CesiumJS的集成。
首先npm安装插件
npm install cesium
安装后的package.json文件(目前最新版本1.91.0)
"dependencies": {
"cesium": "^1.91.0",
}
在页面中引入组件
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
这里我采用全部引入的方式,如果为了避免加载不必要插件可以按需引入,如下:
import { Ion, Viewer, createWorldTerrain, createOsmBuildings, Cartesian3, Math } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
两种方式在使用上稍有区别,下面使用第一种方式继续编写代码。
第一步,要使地图能够显示,首先在页面中添加一个显示的区域,如下:
<template>
<div class="map-index">
<div id="cesiumContainer" class="cesiumContainer"></div>
</div>
</template>
其中 div 的 id 非常关键,下面实例化的时候要用到,这里记得给div设置宽高,以便地图显示。
第二步,进行地图的初始化工作。上面讲了因为要用到云平台的资源,所以要先设置token,然后再初始化地图。
initCesium() {
//设置云平台 AccessToken ,使用本地3dtiles文件可以不设置
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5MjcxYzM2Yy1mYjQ4LTQ5ZTYtODg3Ny1hN2JjOGIxMjVmYTIiLCJpZCI6NjM1MTYsImlhdCI6MTYyODIxNjcyMX0'
//cesiumContainer 即为上一步显示区域设置的 id
var viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false, //控制图层选择器是否显示
geocoder: false, //控制位置选择器是否显示
});
第三步,初始化3dtiles文件,使用viewer显示加载:
//创建实例
var tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(354307)});
// readyPromise,资源加载完成后会 resolved ,此时可以使用viewer加载显示
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(
tileset,
new Cesium.HeadingPitchRange(
0.0,
-0.5,
tileset.boundingSphere.radius * 2.0
)
);
})
.otherwise(function (error) {
console.log(error);
});
这里 Cesium.IonResource.fromAssetId(354307) 里的数字id就是前面提到云平台提供的一个默认的3dtiles数据的id
最终代码如下
<template>
<div class="map-index">
<div id="cesiumContainer" class="cesiumContainer"></div>
</div>
</template>
<script>
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
export default {
data() {
return {};
},
mounted() {
this.initCesium();
},
methods: {
initCesium() {
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5MjcxYzM2Yy1mYjQ4LTQ5ZTYtODg3Ny1hN2JjOGIxMjVmYTIiLCJpZCI6NjM1MTYsImlhdCI6MTYyODIxNjcyMX0.jWrOsZ95ATIT6rhY2hkx2_9yvZ8FDvpLOpfsuaDyc9Q'
var viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false,
geocoder: false,
});
//初始化资源
var tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(354307)});
//加载资源
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(
tileset,
new Cesium.HeadingPitchRange(
0.0,
-0.5,
tileset.boundingSphere.radius * 2.0
)
);
})
.otherwise(function (error) {
console.log(error);
});
},
},
};
</script>
<style lang="scss" scoped>
.map-index {
.cesiumContainer {
height: 1080px;
width: 1920px;
}
}
</style>
运行一下,不出意外,报错了。
提示找不到 CESIUM_BASE_URL 配置,针对这项配置官方解释如下:
Configuring CESIUM_BASE_URL
CesiumJS requires a few static files to be hosted on your server, like web workers and SVG icons.
说的简单就是需要找到网站静态资源,但是有什么用暂时不清楚,具体的配置方式也有说明:
The window.CESIUM_BASE_URL global variable must be set before CesiumJS is imported. It must point to the URL where those four directories are served.
For example, if the image at Assets/Images/cesium_credit.png is served with a static/Cesium/ prefix under http://localhost:8080/static/Cesium/Assets/Images/cesium_credit.png, then you would set the base URL as follows:
window.CESIUM_BASE_URL = '/static/Cesium/';
那这就简单了,由于我们服务都在根目录嘛,所以增加了一段代价如下:
window.CESIUM_BASE_URL = "/";
而上面也说明了,这段配置要在 import cesium 之前,所以最终代码:
<template>
<div class="map-index">
<div id="cesiumContainer" class="cesiumContainer"></div>
</div>
</template>
<script>
window.CESIUM_BASE_URL = "/";
import * as Cesium from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
export default {
data() {
return {};
},
mounted() {
this.initCesium();
},
methods: {
initCesium() {
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5MjcxYzM2Yy1mYjQ4LTQ5ZTYtODg3Ny1hN2JjOGIxMjVmYTIiLCJpZCI6NjM1MTYsImlhdCI6MTYyODIxNjcyMX0.jWrOsZ95ATIT6rhY2hkx2_9yvZ8FDvpLOpfsuaDyc9Q'
var viewer = new Cesium.Viewer("cesiumContainer", {
baseLayerPicker: false,
geocoder: false,
});
//初始化资源
var tileset = new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(354307)});
//加载资源
tileset.readyPromise
.then(function (tileset) {
viewer.scene.primitives.add(tileset);
viewer.zoomTo(
tileset,
new Cesium.HeadingPitchRange(
0.0,
-0.5,
tileset.boundingSphere.radius * 2.0
)
);
})
.otherwise(function (error) {
console.log(error);
});
},
},
};
</script>
<style lang="scss" scoped>
.map-index {
.cesiumContainer {
height: 1080px;
width: 1920px;
}
}
</style>
那么再次运行项目结果:
地图加载暂时完成,稍后会补充视角控制和扎点的方法。
更多推荐
所有评论(0)