【Cesium 入门】在3D城市中可视化一个拟建的建筑

cesium教程系列是将CesiumJS官网教程文章翻译为中文,并且提供Vue3版本的代码GitHub - cesiumjs教程的vue3版本。希望这个系列可以帮助你更好的学习cesium。

官网地址:https://cesium.com/learn/cesiumjs-learn/cesiumjs-interactive-building/

在本教程中,你将学习如何创建一个Cesium应用程序,用你自己的3D模型替换真实城市中的建筑。 你可以用这种方法来可视化拟建建筑的影响。它会如何改变天际线?从特定楼层或房间看,视图会是什么样的? 我们将介绍如何:

  1. 设置并部署你的Cesium网络应用程序。
  2. 添加全球3D建筑、地形和影像的基础图层。
  3. 隐藏单个建筑并用你自己的3D模型替换它们

开始前

我们将从Cesium ion获取全球卫星影像、3D建筑和地形数据,这是一个用于流式传输和托管3D内容的开放平台。
如果你还没有Cesium ion账号,请注册一个免费的账号。
登录后:

  1. 进入你的访问令牌标签页令牌
  2. 注意默认令牌旁边的复制按钮。我们将在下一步使用这个令牌。

Step1:创建Cesium应用

官网使用Glitch在线IDE创建Cesium的html应用。本文介绍Vue3使用CesiumJS库,使用步骤如下:
1 添加依赖

npm install cesium
npm install vite-plugin-cesium -D 

注:由于 Cesium 不是一个普通纯JavaScript包,需要依赖一些 css ,图片,json等静态资源,参考 Cesium 官方的 webpack 教程来做一堆额外的工作。 现在vite-plugin-cesium插件可以在Vite中轻松搭建Cesium项目, 强烈推荐!!!。

2 配置vite-plugin-cesium
只要vite.config.js文件添加 cesium,完整代码

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cesium from 'vite-plugin-cesium' # 导入cesium 

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(), cesium() # 添加插件
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

3 引用cesium建立应用
cesium添加了Treeshaking,可以按需引入,也可以全局引入
设置Token: Ion.defaultAccessToken = ‘xxx’
初始Viewer:const viewer = new Cesium.Viewer(‘cesiumContainer’)
就完成了基本的cesium应用

// import { Cartesian3, createOsmBuildingsAsync, Ion, Math as CesiumMath, Terrain, Viewer, GeoJsonDataSource, ClassificationType, Model, Cesium3DTileStyle,Ellipsoid} from 'cesium';
import * as Cesium from 'cesium';
import "cesium/Build/Cesium/Widgets/widgets.css"; # 注意引入样式

Cesium.Ion.defaultAccessToken = 'xxx';
const viewer = new Cesium.Viewer("cesiumContainer", {
    terrain: Cesium.Terrain.fromWorldTerrain()
  })
  // Fly the camera to Denver, Colorado at the given longitude, latitude, and height.
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(-104.9965, 39.74248, 4000)
  });
}

在这里插入图片描述

Step2:添加Cesium OSM Buildings和Cesium World Terrain

Cesium OSM Buildings 是一个全球基础层,拥有来自 OpenStreetMap 数据的超过 3.5 亿座建筑物。它被用作 3D Tiles,这是由 Cesium 创建的开放标准,可以将 3D 内容流式传输到任何兼容的客户端。
让我们添加这些图层,然后将摄像机移动到我们虚构的新建筑将位于的城市——美国科罗拉多州丹佛市。

// Add Cesium OSM Buildings.
const buildingsTileset = await Cesium.createOsmBuildingsAsync();
viewer.scene.primitives.add(buildingsTileset);

image.png
此时,完整的 index.html 将如下所示(访问令牌除外)。在后续步骤中,您将在脚本标记内的现有代码下方添加新代码。

Cesium OSM Buildings 被固定在全球高分辨率 3D 地形层——Cesium World Terrain 上。这使得它非常适合需要精确建筑高度的应用,例如洪水分析工具。

Step3: 显示新建筑地面范围

在添加新建筑物之前,让我们添加一个 GeoJSON 文件来标记它的覆盖区(footprint)。这将向我们展示哪些现有建筑物需要拆除。
1 下载GeoJSON
2 添加代码

// STEP 3 CODE
async function addBuildingGeoJSON() {
  const new_building_denver = '/new_building_denver.json';
  const buildingGeoJSON = await Cesium.GeoJsonDataSource.load(new_building_denver, { clampToGround: true });
  // Add it to the scene.
  const dataSource = await viewer.dataSources.add(buildingGeoJSON);
  // By default, polygons in CesiumJS will be draped over all 3D content in the scene.
  // Modify the polygons so that this draping only applies to the terrain, not 3D buildings.
  for (const entity of dataSource.entities.values) {
    entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;
  }
}

您现在会在地面上看到黄色建筑物的范围,使用鼠标滚轮放大或右键单击并拖动以仔细查看。
在这里插入图片描述
在这里插入图片描述

Step4: 隐藏场地上现有的 3D 建筑物

现在我们已经确定了新建筑的去向,我们可以看到目前有哪些建筑。我们将使用 3D Tiles 样式语言来隐藏它们。
在上面的足迹中,我们可以看到我们新拟建建筑的场地上有六栋建筑——一栋大型建筑和五栋小得多的建筑。

// STEP 4 CODE
// Hide individual buildings in this area using 3D Tiles Styling language.
buildingsTileset.style = new Cesium.Cesium3DTileStyle({
  // Create a style rule to control each building's "show" property.
  show: {
    conditions : [
      // Any building that has this elementId will have `show = false`.
      ['${elementId} === 332469316', false],
      ['${elementId} === 332469317', false],
      ['${elementId} === 235368665', false],
      ['${elementId} === 530288180', false],
      ['${elementId} === 530288179', false],
      // If a building does not have one of these elementIds, set `show = true`.
      [true, true]
    ]
  },
  // Set the default color style for this particular 3D Tileset.
  // For any building that has a `cesium#color` property, use that color, otherwise make it white.
  color: "Boolean(${feature['cesium#color']}) ? color(${feature['cesium#color']}) : color('#ffffff')"
});

Step5: 将新建筑添加到场景中

1 下载新建筑的glb
2 添加代码

async function showNewBuilding () {
  if (newBuildingTileset) {
    newBuildingTileset.show = !newBuildingTileset.show
    return 
  }

  // STEP 6 CODE
  // Add the 3D Tileset you created from your Cesium ion account.
  const newBuildingTilesetUrl = '/PSFS.glb'

  // Position a model with modelMatrix and display it with a minimum size of 128 pixels
  const position = Cesium.Cartesian3.fromDegrees(
    -104.9909,
    39.73579,
    1577
  );

  const headingPositionRoll = new Cesium.HeadingPitchRoll(-8,0,0);
  // const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
  //   "north",
  //   "west"
  // );

  newBuildingTileset = await Cesium.Model.fromGltfAsync({
    url: newBuildingTilesetUrl,
    modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
     position,
     headingPositionRoll,
     Cesium.Ellipsoid.WGS84,
    //  fixedFrameTransform
   )
  })
  // const newBuildingTileset = await Cesium.Cesium3DTileset.fromIonAssetId();
  viewer.scene.primitives.add(newBuildingTileset);
  // Move the camera to the new building.
  // viewer.flyTo(newBuildingTileset);

 newBuildingTileset.silhouetteSize = 2 // 轮廓大小
}

在这里插入图片描述
在这里插入图片描述
在这里,通过控制新建筑的显示,可视化新建筑对周边环境的影响
到这里就结束啦

源码可从_GitHub - cesiumjs教程的vue3版本_下载

如果文章对你有帮助,希望可以收获你的点赞收藏加关注,我会持续带来更多有价值的内容!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值