Mapbox加载Cesium 3dtiles的实践

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
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值