Cesium快速入门到精通系列教程三:添加物体与3D建筑物

发布于:2025-06-02 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、添加物体与3D建筑物

1、添加一个点:

在 Cesium 1.93 中在广州塔(经度:113.3244,纬度:23.1049)上空 800 米处添加一个红点

<template>
  <div id="cesiumContainer"></div>
  <div class="controls">
    <h3>交互控制</h3>
    <button id="flyToGZTBtn">飞向广州塔</button>
    <button id="toggleRedPointBtn">显示/隐藏红点</button>
    <button id="resetViewBtn">重置视角</button>
    <div style="margin-top: 10px;">
      <strong>红点位置:</strong><br>
      经度: 113.3244°<br>
      纬度: 23.1049°<br>
      高度: 800米
    </div>
  </div>
</template>

<script setup>
Cesium.Ion.defaultAccessToken = 'defaultAccessToken'
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";

window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)

// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  89.5, // 西边经度
  20.4, // 南边维度
  110.4, // 东边经度
  61.2) // 北边维度

onMounted(() => {
  const MAP_KEY = '7bb06f53f4753bbfe922d81d9d3006c1';
  const viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: false, //设置搜索框可见
    homeButton: false, // 返回初始位置键是否可见
    sceneModePicker: false, // 查看器选择模式选择键是否可见
    baseLayerPicker: false, // 图层选择键是否可见
    navigationHelpButton: false, // 是否显示帮助按钮
    animation: false, // 是否显示播放控制按钮
    timeline: false, // 是否显示时间轴
    fullscreenButton: false, // 是否显示全屏按钮
  });

  viewer.cesiumWidget.creditContainer.style.display = "none"; // 隐藏logo

  // 广州塔位置(经纬度和高度)
  const guangzhouTowerPosition = {
    longitude: 113.3244,
    latitude: 23.1049,
    height: 600  // 广州塔实际高度约600米
  };

  // 红点位置(广州塔上空800米)
  const redPointPosition = {
    longitude: guangzhouTowerPosition.longitude,
    latitude: guangzhouTowerPosition.latitude,
    height: guangzhouTowerPosition.height + 800  // 上空800米
  };

  // 创建红点实体
  const redPointEntity = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
      redPointPosition.longitude,
      redPointPosition.latitude,
      redPointPosition.height
    ),
    point: {
      color: Cesium.Color.RED,         // 红色
      pixelSize: 10,                   // 像素大小
      outlineColor: Cesium.Color.WHITE, // 白色边框
      outlineWidth: 2,                 // 边框宽度
      heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND // 相对地面高度
    },
    label: {
      text: '广州塔上空800米',
      font: '14pt monospace',
      fillColor: Cesium.Color.WHITE,
      backgroundColor: Cesium.Color.BLACK.withAlpha(0.5),
      padding: new Cesium.Cartesian2(7, 5),
      showBackground: true,
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
      pixelOffset: new Cesium.Cartesian2(0, -10),
      disableDepthTestDistance: Number.POSITIVE_INFINITY // 始终显示在最前面
    }
  });

  // 初始视角(中国东南部)
  const initialView = {
    destination: Cesium.Cartesian3.fromDegrees(113.3, 23.1, 15000),
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-30.0),
      roll: 0.0
    }
  };

  // 广州塔视角
  const guangzhouTowerView = {
    destination: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude,
      guangzhouTowerPosition.latitude,
      2000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-30.0),
      roll: 0.0
    },
    duration: 3 // 飞行时间(秒)
  };

  // 设置初始视角
  viewer.camera.setView(initialView);

  // 按钮事件
  document.getElementById('flyToGZTBtn').addEventListener('click', function () {
    viewer.camera.flyTo(guangzhouTowerView);
  });

  document.getElementById('toggleRedPointBtn').addEventListener('click', function () {
    redPointEntity.show = !redPointEntity.show;
  });

  document.getElementById('resetViewBtn').addEventListener('click', function () {
    viewer.camera.setView(initialView);
  });
})

</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
}

#cesiumContainer {
  width: 100wh;
  height: 100vh;
}

.controls {
  position: absolute;
  top: 10px;
  right: 10px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 10px;
  border-radius: 5px;
  font-family: Arial, sans-serif;
  font-size: 14px;
  z-index: 100;
}

button {
  margin-top: 5px;
  width: 100%;
  padding: 5px;
  cursor: pointer;
}
</style>

2、添加Cesium自带的建筑:

以广州塔为中心添加Cesium自带的建筑

<template>
  <div id="cesiumContainer"></div>
</template>

<script setup>
Cesium.Ion.defaultAccessToken = 'edefaultAccessToken'
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";

window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)

// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  89.5, // 西边经度
  20.4, // 南边维度
  110.4, // 东边经度
  61.2) // 北边维度

onMounted(() => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: false, //设置搜索框可见
    homeButton: false, // 返回初始位置键是否可见
    sceneModePicker: false, // 查看器选择模式选择键是否可见
    baseLayerPicker: false, // 图层选择键是否可见
    navigationHelpButton: false, // 是否显示帮助按钮
    animation: false, // 是否显示播放控制按钮
    timeline: false, // 是否显示时间轴
    fullscreenButton: false, // 是否显示全屏按钮
  });

  const guangzhouTowerPosition = {
    longitude: 113.3244,
    latitude: 23.1049,
    height: 600  // 广州塔实际高度约600米
  };

  // 广州塔视角
  const guangzhouTowerView = {
    destination: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude,
      guangzhouTowerPosition.latitude,
      2000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-30.0),
      roll: 0.0
    },
    duration: 3 // 飞行时间(秒)
  };

  viewer.scene.primitives.add(new Cesium.createOsmBuildings());

  viewer.camera.flyTo(guangzhouTowerView);
})

</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
}

#cesiumContainer {
  width: 100wh;
  height: 100vh;
}
</style>

3、添加标签与广告牌

  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(guangzhouTowerPosition.longitude, guangzhouTowerPosition.latitude, guangzhouTowerPosition.height + 50), // 广告牌位于塔顶上方50米
    billboard: {
      image: './gzt.png', // 在public目录
      width: 60,
      height: 60,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,    // 垂直底部对齐
      scale: 1.0,
      color: Cesium.Color.RED.withAlpha(0.8)           // 半透明红色
    },
    label: {
      text: '广州塔',
      font: '30px Microsoft YaHei', // 字体样式
      fillColor: Cesium.Color.WHITE,  // 文字颜色
      outlineColor: Cesium.Color.BLACK, // 描边颜色
      outlineWidth: 2,                // 描边宽度
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 填充+描边
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.TOP, // 标签位于广告牌上方
      pixelOffset: new Cesium.Cartesian2(0, 20), // 垂直偏移量
      scale: 0.8
    }
  });

完整代码

<template>
  <div id="cesiumContainer"></div>
</template>

<script setup>
Cesium.Ion.defaultAccessToken = 'defaultAccessToken'
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";

window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)

// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  89.5, // 西边经度
  20.4, // 南边维度
  110.4, // 东边经度
  61.2) // 北边维度

onMounted(() => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: false, //设置搜索框可见
    homeButton: false, // 返回初始位置键是否可见
    sceneModePicker: false, // 查看器选择模式选择键是否可见
    baseLayerPicker: false, // 图层选择键是否可见
    navigationHelpButton: false, // 是否显示帮助按钮
    animation: false, // 是否显示播放控制按钮
    timeline: false, // 是否显示时间轴
    fullscreenButton: false, // 是否显示全屏按钮
  });

  const guangzhouTowerPosition = {
    longitude: 113.3244,
    latitude: 23.1049,
    height: 600  // 广州塔实际高度约600米
  };

  // 广州塔视角
  const guangzhouTowerView = {
    destination: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude,
      guangzhouTowerPosition.latitude,
      2000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-30.0),
      roll: 0.0
    },
    duration: 3 // 飞行时间(秒)
  };

  viewer.scene.primitives.add(new Cesium.createOsmBuildings());

  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(guangzhouTowerPosition.longitude, guangzhouTowerPosition.latitude, guangzhouTowerPosition.height + 50), // 广告牌位于塔顶上方50米
    billboard: {
      image: './gzt.png', // 替换为实际图标路径
      width: 60,
      height: 60,
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
      verticalOrigin: Cesium.VerticalOrigin.BOTTOM,    // 垂直底部对齐
      scale: 1.0,
      color: Cesium.Color.RED.withAlpha(0.8)           // 半透明红色
    },
    label: {
      text: '广州塔',
      font: '30px Microsoft YaHei', // 字体样式
      fillColor: Cesium.Color.WHITE,  // 文字颜色
      outlineColor: Cesium.Color.BLACK, // 描边颜色
      outlineWidth: 2,                // 描边宽度
      style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 填充+描边
      horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      verticalOrigin: Cesium.VerticalOrigin.TOP, // 标签位于广告牌上方
      pixelOffset: new Cesium.Cartesian2(0, 20), // 垂直偏移量
      scale: 0.8
    }
  });

  viewer.camera.flyTo(guangzhouTowerView);
})

</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
}

#cesiumContainer {
  width: 100wh;
  height: 100vh;
}
</style>

4、3D模型添加与设置

在广州塔上空添加一架GLB模型飞机

  const guangzhouTowerPosition = {
    longitude: 113.3244,
    latitude: 23.1049,
    height: 600  // 广州塔实际高度约600米
  };

  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude + 0.001,  // 东经偏移100米
      guangzhouTowerPosition.latitude + 0.0005, // 北纬偏移50米
      1500                 // 飞行高度100米
    ),
    model: {
      uri: './model/Cesium_Air.glb', // Cesium_Air.glb在public目录下
      scale: 1.0,                  // 缩放比例(根据模型实际尺寸调整)
      minimumPixelSize: 128,
      maximumScale: 10000,
      // 启用动画(假设模型包含螺旋桨动画)
      animations: [{
        id: 'propeller',
        loop: Cesium.ModelAnimationLoop.REPEAT,
        speed: 2.0 // 转速倍数
      }]
    }
  });

完整代码

<template>
  <div id="cesiumContainer"></div>
</template>

<script setup>
Cesium.Ion.defaultAccessToken = 'defaultAccessToken'
import { onMounted } from "vue";
import * as Cesium from "cesium";
import "./Widgets/widgets.css";

window.CESIUM_BASE_URL = "/"; // 设置Cesium静态资源路径(public目录)

// 设置Cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
  89.5, // 西边经度
  20.4, // 南边维度
  110.4, // 东边经度
  61.2) // 北边维度

onMounted(() => {
  const viewer = new Cesium.Viewer("cesiumContainer", {
    geocoder: false, //设置搜索框可见
    homeButton: false, // 返回初始位置键是否可见
    sceneModePicker: false, // 查看器选择模式选择键是否可见
    baseLayerPicker: false, // 图层选择键是否可见
    navigationHelpButton: false, // 是否显示帮助按钮
    animation: false, // 是否显示播放控制按钮
    timeline: false, // 是否显示时间轴
    fullscreenButton: false, // 是否显示全屏按钮
  });

  const guangzhouTowerPosition = {
    longitude: 113.3244,
    latitude: 23.1049,
    height: 600  // 广州塔实际高度约600米
  };

  // 广州塔视角
  const guangzhouTowerView = {
    destination: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude,
      guangzhouTowerPosition.latitude,
      2000
    ),
    orientation: {
      heading: Cesium.Math.toRadians(0.0),
      pitch: Cesium.Math.toRadians(-30.0),
      roll: 0.0
    },
    duration: 3 // 飞行时间(秒)
  };

  viewer.scene.primitives.add(new Cesium.createOsmBuildings());

  viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(
      guangzhouTowerPosition.longitude + 0.001,  // 东经偏移100米
      guangzhouTowerPosition.latitude + 0.0005, // 北纬偏移50米
      1500                 // 飞行高度100米
    ),
    model: {
      uri: './model/Cesium_Air.glb', // 替换为实际模型路径
      scale: 1.0,                  // 缩放比例(根据模型实际尺寸调整)
      minimumPixelSize: 128,
      maximumScale: 10000,
      // 启用动画(假设模型包含螺旋桨动画)
      animations: [{
        id: 'propeller',
        loop: Cesium.ModelAnimationLoop.REPEAT,
        speed: 2.0 // 转速倍数
      }]
    }
  });

  viewer.camera.flyTo(guangzhouTowerView);
})

</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
}

#cesiumContainer {
  width: 100wh;
  height: 100vh;
}
</style>

5、创建一个多边形实体

const viewer = new Cesium.Viewer("cesiumContainer");

const wyoming = viewer.entities.add({
  polygon: {
    hierarchy: Cesium.Cartesian3.fromDegreesArray([
      -109.080842, 45.002073, -105.91517, 45.002073, -104.058488, 44.996596,
      -104.053011, 43.002989, -104.053011, 41.003906, -105.728954, 40.998429,
      -107.919731, 41.003906, -109.04798, 40.998429, -111.047063, 40.998429,
      -111.047063, 42.000709, -111.047063, 44.476286, -111.05254, 45.002073,
    ]),
    height: 0,
    material: Cesium.Color.RED.withAlpha(0.5),
    outline: true,
    outlineColor: Cesium.Color.BLACK,
  },
});

// viewer.flyTo(viewer.entities);
viewer.zoomTo(wyoming);


网站公告

今日签到

点亮在社区的每一天
去签到