关于Vite+vue3+ts+Cesium 搭建项目

记录目的:方便下次环境搭建

vue3的组合式APP开发真的不要太舒服 以前写个业务逻辑,代码到处写(data、method、created、等),现在只需要在setup里就能搞定。这么好的东西大家赶紧学起来用起来呀,因为做的项目需要用到Cesium,所以记录以下项目搭建过程 同时git上也会有完整的对应demo


创建文件夹:demo

进入文件夹初始化

yarn init -y

安装相关依赖

本来以前的vue-cli版本需要自己搭配一些Cesium相关静态资源的配置,现在出了vite-plugin-cesium这个插件可以很轻松的完成配置
·yarn add -D cesium CesiumNavigation vite vite-plugin-cesium·

vite.config.ts配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium';
import vueJsx from '@vitejs/plugin-vue-jsx'
import { join } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(), cesium(), vueJsx()],
  resolve: {
    // 配置别名
    alias: {
      '@': join(__dirname, './src'),
      '@components': join(__dirname, './src/components'),
      '@utils': join(__dirname, './src/utils'),
      '@public': join(__dirname, './public')
    }
  },
  server: {
    proxy: {
      '/api': {
        target: 'https://data.stats.gov.cn',
        changeOrigin: true,
        secure: false,
        prependPath: true
        //ws: true,//websocket支持
      }
    }
  }
})

声明types.d文件,将Windows上挂上Cesium属性便于全局使用

declare interface Window {
    Cesium: any,
    Viewer: any
}

创建Map组件供全局使用

<template>
  <div id="CesiumViewer">
    <slot></slot>
  </div>
</template>
<script lang="ts" setup>
import * as Cesium from "cesium";
import CesiumNavigation from 'cesium-navigation-es6' //地图指南针插件
import { ref, defineEmits } from "vue";
import { onMounted, onBeforeUnmount } from "vue";
window.Cesium = Cesium;
const options = defineProps({
  options: Object,
  navigatorOptions: {
    type: Object,
    default () {
      return {
        show: true
      }
    }
  }
});

const $emit = defineEmits(["onViewerLoaded"]);
const MapConfig = {
  ION: "", //自己的token
  global: {
    enableLighting: false,
    depthTestAgainstTerrain: true, //高度检测
    highDynamicRange: true,
  },
  MAPOPTIONS: {
    imageryProviderViewModels: [
      new Cesium.ProviderViewModel({
        name: "Google卫星",
        iconUrl:
          "http://img3.cache.netease.com/photo/0031/2012-03-22/7T6QCSPH1CA10031.jpg",
        tooltip: "Google卫星",
        creationFunction: function () {
          return new Cesium.UrlTemplateImageryProvider({
            url: "http://www.google.cn/maps/vt?lyrs=s&x={x}&y={y}&z={z}", //影像图 (中国范围无偏移)
            tilingScheme: new Cesium.WebMercatorTilingScheme(),
            minimumLevel: 1,
            maximumLevel: 200,
            credit: "Google Earth",
          });
        },
      }),
    ], //设置影像图列表
    shouldAnimate: true,
    geocoder: false, //右上角查询按钮
    shadows: false,
    terrainProviderViewModels: [], //设置地形图列表
    animation: false, //动画小窗口
    baseLayerPicker: false, //图层选择器
    fullscreenButton: false, //全屏
    vrButton: false, //vr按钮
    homeButton: false, //home按钮
    infoBox: false,
    sceneModePicker: false, //2D,2.5D,3D切换
    selectionIndicator: false,
    timeline: false, //时间轴
    navigationHelpButton: false, //帮助按钮
    terrainShadows: Cesium.ShadowMode.DISABLED,
  },
};
let beActive = ref<Boolean>(false);
let viewer: Cesium.Viewer | null;
let beforeDestroy = new Cesium.Event();
const destroy = (): void => {
  beforeDestroy.raiseEvent();
  console.warn("cesium destroy!!");
  viewer?.destroy();
  viewer = null;
};
onMounted(() => {
  viewer = new Cesium.Viewer("CesiumViewer", {
    ...MapConfig.MAPOPTIONS,
    ...options.options,
  });
  (viewer.cesiumWidget.creditContainer as HTMLElement).style.display = "none"; //去除版权信息
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
    Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  ); //移除双击选中
  // var terrainProvider = Cesium.createWorldTerrain({
  //   requestVertexNormals: true,
  // });
  let terrainProvider;
  if (options.options?.terrainProvider) {
    terrainProvider = options.options.terrainProvider;
  } else {
    terrainProvider = new Cesium.CesiumTerrainProvider({
      url: "./Terran",
    });
  }
  viewer.terrainProvider = terrainProvider;
  viewer.scene.globe.enableLighting = MapConfig.global.enableLighting; //光照开关
  viewer.scene.globe.depthTestAgainstTerrain =
    MapConfig.global.depthTestAgainstTerrain; //depth
  viewer.scene.highDynamicRange = MapConfig.global.highDynamicRange;
  viewer.frameUpdate = new Cesium.Event();
  let lasTime: null | number;
  viewer.scene.preUpdate.addEventListener((time) => {
    let dateNow = Date.now();
    let deltaTime = lasTime != null ? dateNow - lasTime : 0;
    lasTime = dateNow;
    viewer.frameUpdate.raiseEvent(deltaTime);
  });
  const { navigatorOptions } = options
  if(navigatorOptions?.show === true) {
     //指南针比例尺
    let CesiumNavigationOptions = {
      // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和Cesium.Rectangle.
      defaultResetView: navigatorOptions.defaultResetView || Cesium.Cartographic.fromDegrees(115, 30, 2000000),
      // 用于启用或禁用罗盘。true是启用罗盘,false是禁用罗盘。默认值为true。如果将选项设置为false,则罗盘将不会添加到地图中。
      enableCompass: true,
      // 用于启用或禁用缩放控件。true是启用,false是禁用。默认值为true。如果将选项设置为false,则缩放控件 将不会添加到地图中。
      enableZoomControls: true,
      // 用于启用或禁用距离图例。true是启用,false是禁用。默认值为true。如果将选项设置为false,距离图例将不会添加到地图中。
      enableDistanceLegend: true,
        // 用于启用或禁用指南针外环。true是启用,false是禁用。默认值为true。如果将选项设置为false,则该环将可见但无效。
      enableCompassOuterRing: true
    }
    new CesiumNavigation(viewer, CesiumNavigationOptions)
  }

  window.Viewer = viewer;
  beActive.value = true;
  console.warn("cesium 启动!!");
  $emit("onViewerLoaded", viewer);
});
onBeforeUnmount(() => {
  destroy();
});
</script>
<style lang="less" scoped>
#CesiumViewer {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
</style>

你可能感兴趣的:(Cesium,vue.js,前端,javascript)