vite vue3 使用 cesium 加载 geojson LineString

<template>
  <div id="CesiumContainer" class="CesiumContainer" ref="cesium"></div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import * as Cesium from "cesium";

import line from "./line.json";

const cesium = ref(null);
const viewer = ref<Cesium.Viewer | null>(null);


/**
 * 初始化Cesium地图并设置暗色主题
 * 绘制GeoJSON数据并定位到数据中心
 */
onMounted(() => {
  // 配置Cesium Token(如果需要)
  // Cesium.Ion.defaultAccessToken = 'your-token-here';

  // 初始化Cesium查看器
  viewer.value = new Cesium.Viewer(cesium.value as unknown as HTMLElement, {
    // 设置暗色主题
    baseLayerPicker: false, // 禁用默认的图层选择器
    animation: false, // 禁用动画控件
    timeline: false, // 禁用时间线控件
    fullscreenButton: false, // 禁用全屏按钮
    infoBox: false, // 禁用信息框
    navigationHelpButton: false, // 禁用导航帮助按钮
    homeButton: false, // 禁用home按钮
    sceneModePicker: false, // 禁用场景模式选择器
    selectionIndicator: false, // 禁用选择指示器
    geocoder: false, // 禁用地理编码器
    skyBox: false, // 禁用天空盒
    skyAtmosphere: false, // 禁用大气层
    contextOptions: {
      webgl: {
        alpha: true,
      },
    },
  });

  // 设置地球为暗色
  viewer.value.scene.globe.baseColor = new Cesium.Color(0.0, 0.0, 0.0, 1.0);
  viewer.value.scene.backgroundColor = new Cesium.Color(0.0, 0.0, 0.0, 1.0);

  // 禁用地形光照
  viewer.value.scene.globe.enableLighting = false;

  // 绘制GeoJSON数据
  if (line && line.coordinates && line.coordinates.length > 0) {
    // 生成所有坐标点的Cartesian3数组
    const positions = line.coordinates.map(coord => Cesium.Cartesian3.fromDegrees(coord[0], coord[1]));

    // 创建LineString实体
    viewer.value.entities.add({
      name: "线路",
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(
          line.coordinates.flat()
        ),
        width: 3,
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.2,
          color: Cesium.Color.CYAN,
        }),
      },
    });

    // 计算包围球并自动定位视野
    const boundingSphere = Cesium.BoundingSphere.fromPoints(positions);
    viewer.value.camera.flyToBoundingSphere(boundingSphere, {
      duration: 2,
      offset: new Cesium.HeadingPitchRange(
        Cesium.Math.toRadians(0), // heading
        Cesium.Math.toRadians(-60), // pitch
        boundingSphere.radius * 3 // range,保证整体可见(原为*2,现改为*3以提升相机高度)
      )
    });
  } else {
    console.error("GeoJSON数据无效或为空");

    // 如果GeoJSON数据无效,使用默认位置
    const defaultPosition = Cesium.Cartesian3.fromDegrees(
      119.73, // 默认经度(基于lineline.json中的一个点)
      31.65,  // 默认纬度(基于lineline.json中的一个点)
      50000   // 默认高度(米)
    );

    // 设置相机位置到默认位置
    viewer.value.camera.flyTo({
      destination: defaultPosition,
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-60),
        roll: 0
      },
      duration: 2
    });
  }

});

/**
 * 组件卸载时销毁Cesium实例,释放资源
 */
onUnmounted(() => {
  if (viewer.value) {
    viewer.value.destroy();
    viewer.value = null;
  }
});
</script>

<style scoped lang="scss">
.CesiumContainer {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}
</style>

四下皆无人