Mapbox加载Cesium 3dtiles的实践
1.第一部分,使用deck.gl的Tile3DLayerdeck.gl提供了Tile3DLayer的实现,我们需要一定的改造。首先我们环境是Vue2+mapbox,安装相关依赖npm i vue-deck.gl dekc.gl我们直接使用vud-deck.gl的样例改造一下<template><VueDeckgl :layers="layers":viewState="viewS
·
1.第一部分,使用deck.gl的Tile3DLayer
deck.gl提供了Tile3DLayer的实现,我们需要一定的改造。
首先我们环境是Vue2+mapbox,安装相关依赖
npm i vue-deck.gl dekc.gl
我们直接使用vud-deck.gl的样例改造一下
<template>
<VueDeckgl :layers="layers"
class="vc"
:viewState="viewState"
@view-state-change="updateViewState">
<div id="map"
ref="map"></div>
</VueDeckgl>
</template>
<script>
import { Tile3DLayer } from "@deck.gl/geo-layers";
import { CesiumIonLoader } from '@loaders.gl/3d-tiles';
import mapboxgl from "mapbox-gl";
import VueDeckgl from 'vue-deck.gl'
export default {
components: {
VueDeckgl
},
data () {
return {
accessToken: 'pk.eyJ1IjoiaWxZWt4bDFncGI3ZjYifQ.Pu9l94qL1MEDdDim2-s6RA',//replace with your token
mapStyle: "mapbox://styles/haxzie/ck0aryyna2lwq1crp7fwpm5vz",
viewState: {
latitude: 30.5,
longitude: 121,
zoom: 4,
bearing: 0,
pitch: 0,
},
};
},
computed: {
layers () {
const layer = new Tile3DLayer({
id: 'tile-3d-layer',
data: 'tileset.json',//replace with your tileset
loader: CesiumIonLoader,
loadOptions: {
// 'cesium-ion': { accessToken: 'eyJhbGciOiJIUzI1' }//replace with your token
},
onTileError: (err) => {
console.log(err)
},
onTilesetLoad: (tileset) => {
tileset
const { cartographicCenter, zoom } = tileset;
this.viewState = {
...this.viewState,
longitude: cartographicCenter[0],
latitude: cartographicCenter[1],
zoom
}
},
_subLayerProps: {
'scenegraph': { _lighting: "flat" }
}
})
return [layer];
},
},
created () {
// We need to set mapbox-gl library here in order to use it in template
this.map = null;
},
methods: {
updateViewState (viewState) {
console.log("updating view state...");
this.viewState = {
...viewState
}
this.map.jumpTo({
center: [viewState.longitude, viewState.latitude],
zoom: viewState.zoom,
bearing: viewState.bearing,
pitch: viewState.pitch,
});
},
hnadleClick () {
console.log('a')
}
},
mounted () {
// creating the map
this.map = new mapboxgl.Map({
accessToken: this.accessToken,
container: this.$refs.map,
interactive: false,
style:
this.mapStyle || "mapbox://styles/haxzie/ck7h838qb0bik1iofe0k2i3f2",
center: [this.viewState.longitude, this.viewState.latitude],
zoom: this.viewState.zoom,
pitch: this.viewState.pitch,
bearing: this.viewState.bearing,
});
// setTimeout(() => {
// const { latitude, longitude, pitch, bearing } = this.viewState;
// this.viewState = {
// latitude,
// longitude,
// pitch,
// bearing,
// zoom: 12,
// transitionDuration: 3000,
// };
// }, 5000);
},
};
</script>
<style lang="css">
#map,
.vc {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #e5e9ec;
overflow: hidden;
}
</style>
2 我们改造几个东西
1.网络请求中:https://api.cesium.com/v1/assets 出错 ,需要修改ion.js这个文件在/node_modules/@loaders.gl/3d-tiles/dist/esm/lib/ion/ion.js,由于CesiumIonLoader使用了acess_token,但是这个ion.js有些旧了,需要将
export async function getIonAssets(accessToken) {
assert(accessToken);
// const url = CESIUM_ION_URL;
const headers = {
// Authorization: "Bearer ".concat(accessToken)
};
const url = CESIUM_ION_URL+"?access_token="+accessToken;
const response = await fetchFile(url, {
fetch: {
headers
}
});
if (!response.ok) {
throw new Error(response.statusText);
}
return await response.json();
}
3.然后就可以看到加载效果
我们需要设置一下cesium常见的maximumScreenSpaceError即可
onTilesetLoad: (tileset) => {
tileset.setProps({ maximumScreenSpaceError: 1 })
const { cartographicCenter, zoom } = tileset;
this.viewState = {
...this.viewState,
longitude: cartographicCenter[0],
latitude: cartographicCenter[1],
zoom
}
},
4.上诉方式使用deck.gl来管理mapbox.gl,会造成一个问题就是地图上的事件出问题,应该是两个canvas,下面则将deck.gl置于mapbox之下
layers () {
const layer = new MapboxLayer({
id: 'tile-3d',
type: Tile3DLayer,
data: 'http://cloudv2bucket.oss-cn-shanghai.aliyuncs.com/185/1254/resultCC/Production_1.json',
loader: CesiumIonLoader,
loadOptions: {
'cesium-ion': { accessToken: 'as' }
},
onTileError: (err) => {
console.log(err)
},
onTilesetLoad: (tileset) => {
tileset.setProps({ maximumScreenSpaceError: 1 })
const { cartographicCenter, zoom } = tileset;
this.viewState = {
...this.viewState,
longitude: cartographicCenter[0],
latitude: cartographicCenter[1],
zoom
}
let viewState = this.viewState
this.map.jumpTo({
center: [viewState.longitude, viewState.latitude],
zoom: viewState.zoom,
bearing: viewState.bearing,
pitch: viewState.pitch,
});
},
_subLayerProps: {
'scenegraph': { _lighting: "flat" }
}
})
return layer;
},
this.map.on('load', () => {
window.map = this.map
this.map.addLayer(this.layers)
...
}
更多推荐
已为社区贡献1条内容
所有评论(0)