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

一、添加物体与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);
相关推荐
gis_rc2 天前
python下shp转3dtiles
python·3d·cesium·3dtiles·数字孪生模型
grasperp3 天前
3DTiles数据切片工具,支持LAS、OBJ、FBX 3DTiles怎么切片?3DTiles切片
cesium·3dtiles·三维gis·3dtiles切片·数据切片
duansamve5 天前
Cesium中实现在地图上移动/旋转点、线、面
cesium
冥界摄政王6 天前
CesiumJS学习第四章 替换指定3D建筑模型
3d·vue·html·webgl·js·cesium
冥界摄政王8 天前
Cesium学习第二章 camera 相机
node.js·html·vue3·js·cesium
冥界摄政王9 天前
Cesium学习第一章 安装下载 基于vue3引入Cesium项目开发
vue·vue3·html5·webgl·cesium
你们瞎搞10 天前
Cesium加载20GB航测影像.tif
前端·cesium·gdal·地图切片
闲云一鹤12 天前
Cesium 使用 Turf 实现坐标点移动(偏移)
前端·gis·cesium
二狗哈12 天前
Cesium快速入门34:3dTile高级样式设置
前端·javascript·算法·3d·webgl·cesium·地图可视化
二狗哈13 天前
Cesium快速入门33:tile3d设置样式
3d·状态模式·webgl·cesium·地图可视化