在 3D 虚拟城市中展示自定义建筑

news2024/9/20 8:00:21

 在本教程中,您将学习如何创建 Cesium 应用程序,用您自己的 3D 模型替换真实城市中的建筑物。您可以使用它来可视化拟建建筑的影响,及如何改变天际线?从特定楼层或房间看到的景色会是什么样子?

我们将介绍如何:

  • 在网络上设置并部署您的 Cesium 应用程序。

  • 添加全球 3D 建筑物、地形和图像的基础图层。

  • 隐藏单个建筑物并用您自己的 3D 模型替换它们。

开始之前

我们将从 Cesium ion(一个用于流式传输和托管 3D 内容的开放平台)获取全球卫星图像、3D 建筑物和地形。

 如果您还没有免费的Cesium ion帐户,请注册一个。

登录后:

  1. 转到您的 访问令牌 选项卡。

  2. 请注意默认令牌旁边的复制按钮。我们将在下一步中使用此令牌。

图片

1 设置你的Cesium应用程序

我们将使用 CesiumJS(一个开源 JavaScript 引擎)创建我们的应用程序。我们将使用 Glitch(一个在线 IDE)来托管我们的应用程序。

1 使用我们组合的基本模板创建一个新的 Glitch 项目。

2单击  左侧面板中的index.html以查看应用程序的代码。

3替换 为您的令牌页面your_token_here 中的访问令牌 。

4单击  顶部的 “显示”并选择“代码旁边”来运行应用程序。

图片

 到目前为止,index.html中的代码 做了三件事:

  • 导入 CesiumJS 库。JavaScript 和 CSS 文件在这两行中加载:

<script src="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Cesium.js"></script><link href="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

  • 为场景添加一个 HTML 容器:  <div id="cesiumContainer"></div>

  • 用 ; 初始化查看器 const viewer = new Cesium.Viewer('cesiumContainer')

现在,您的浏览器中运行了一个基本的 CesiumJS 应用程序,其中包含来自 Cesium ion 的全球卫星图像。

配置自动刷新

每次代码更改时,Glitch 都会自动刷新页面。您可以通过单击左上角的项目名称并取消选中此框来切换此选项:

图片

使用应用程序窗口顶部的刷新按钮重新运行应用程序:

图片

2添加Cesium OSM建筑物和Cesium世界地形

Cesium OSM Buildings是一个全球基础层,拥有来自 OpenStreetMap 数据的超过 3.5 亿座建筑物。它被用作 3D Tiles,这是由 Cesium 创建的开放标准,可以将 3D 内容流式传输到任何兼容的客户端。

让我们添加这些图层,然后将摄像机移动到我们虚构的新建筑将位于的城市 - 美国科罗拉多州丹佛市。

1将index.html中的 JavaScript 代码替换  为以下代码,保留之前的访问令牌行。

2单击并拖动以移动相机。按住 CTRL 键的同时拖动可倾斜。

3单击任何建筑物以查看其元数据。

// Keep your Cesium.Ion.defaultAccessToken = 'your_token_here' line above. // STEP 2 CODE// Initialize the viewer with Cesium World Terrain.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)});
// Add Cesium OSM Buildings.const buildingsTileset = await Cesium.createOsmBuildingsAsync();viewer.scene.primitives.add(buildingsTileset);

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

<!DOCTYPE html><html lang="en"><head>  <script src="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Cesium.js"></script>  <link href="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Widgets/widgets.css" rel="stylesheet">  <link href="style.css" rel="stylesheet"></head><body>  <div id="cesiumContainer"></div>  <script type="module">    // Your access token can be found at: https://ion.cesium.com/tokens.    // Replace `your_access_token` with your Cesium ion access token.    Cesium.Ion.defaultAccessToken = 'your_access_token';        // Keep your Cesium.Ion.defaultAccessToken = 'your_token_here' line above.     // STEP 2 CODE    // Initialize the viewer with Cesium World Terrain.    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)    });
    // Add Cesium OSM Buildings.    const buildingsTileset = await Cesium.createOsmBuildingsAsync();    viewer.scene.primitives.add(buildingsTileset);</script></body></html>

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

3确定新建筑面积

在添加新建筑物之前,让我们添加一个 GeoJSON 文件来标记它的占地面积。这将向我们展示哪些现有建筑物需要拆除。

1下载 GeoJSON 文件。

2将 GeoJSON 文件拖放到 Cesium ion 仪表板中。

3按 UPLOAD

4上传后,记下预览窗口下的3D对象 ID。

图片

1在index.html中添加以下代码。

  • 替换 your_asset_id 为您的3D对象ID。ID 是一个数字,因此不需要引号。

// STEP 3 CODEasync function addBuildingGeoJSON() {  // Load the GeoJSON file from Cesium ion.  const geoJSONURL = await Cesium.IonResource.fromAssetId(your_asset_id);  // Create the geometry from the GeoJSON, and clamp it to the ground.  const geoJSON = await Cesium.GeoJsonDataSource.load(geoJSONURL, { clampToGround: true });  // Add it to the scene.  const dataSource = await viewer.dataSources.add(geoJSON);  // 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;  }  // Move the camera so that the polygon is in view.  viewer.flyTo(dataSource);}addBuildingGeoJSON();

您现在会在地面上看到建筑物的足迹。使用鼠标滚轮放大或右键单击并拖动以仔细查看。

图片

5隐藏现场现有的3D建筑物

现在我们已经确定了新建筑的去向,我们可以看到当前有哪些建筑。我们将使用 3D Tiles 样式语言 来隐藏它们。

在上面的足迹中,我们可以看到我们新拟建建筑的场地上有六栋建筑——一栋大型建筑和五栋小得多的建筑。

1添加以下代码。它隐藏了所有较小的 3D 建筑物。​​​​​​​

// 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')"});

2扩展此代码以隐藏剩余的 3D 建筑。

  • 单击建筑物即可找到其 elementId

  • 添加另一行,例如: ['${elementId} === large_building_elementId', false],.

6上传并定位新建筑

让我们上传建议的建筑模型。

1下载此 glTF 模型。

2将其拖放到 Cesium ion 仪表板中。

3选择 3D 模型(平铺为 3D 平铺) 并按 UPLOAD

4平铺完成后,单击  资源预览窗口顶部的“调整平铺集位置”按钮。

图片

5在搜索框中 输入建筑物的地址 1250 Cherokee Street ,然后单击NEXT。

6使用查看器上的控件,直观地定位并旋转建筑物,使其与下方的卫星图像对齐。您的最终设置应约为:

  • 经度:-104.9909

  • 纬度: 39.73579

  • 身高:1577

  • 标题:-8

7按SAVE。

7将新建筑添加到场景中

现在让我们将新建筑添加到场景中。

1在资源预览窗口下获取我们刚刚地理定位的建筑模型的3D对象 ID。

2在index.html 中添加以下代码。

  • 替换 your_asset_id 为您的3D对象 ID。

// STEP 6 CODE// Add the 3D Tileset you created from your Cesium ion account.const newBuildingTileset = await Cesium.Cesium3DTileset.fromIonAssetId(your_asset_id);viewer.scene.primitives.add(newBuildingTileset);
// Move the camera to the new building.viewer.flyTo(newBuildingTileset);

8添加一个按钮来切换新建筑

1在 index.html中,将按钮添加到 <body> 标记内的上方 <script>

<button id="toggle-building">Toggle new building</button>

2style 在标签内 添加以下 CSS 标签head 。​​​​​​​

  <style type="text/css">    #toggle-building { z-index: 1; position: fixed; top: 5px; left: 5px; }</style>

3在index.html中添加以下JavaScript  ​​​​​​​

// STEP 7 CODE// Toggle the tileset's show property when the button is clicked.document.querySelector('#toggle-building').onclick = function() {  newBuildingTileset.show = !newBuildingTileset.show;};

9考虑建筑物对周围环境的影响

现在您可以比较有和没有这座新建筑的场景!丹佛的全景山景非常珍贵。这座建筑如何影响其他地点(例如科罗拉多州议会大厦)的景观?

图片

对科罗拉多州议会大厦景观的影响。
要重现此效果,请搜索State Capitol Building, Denver, CO, USA并调整相机。

我们甚至可以探索国会大厦入口处的景色将如何变化。

图片

从更接近地面的角度对视野的影响。

完整教程源码

这是此应用程序的完整源代码,带有 your_token_here 和 your_asset_id 占位符​​​​​​​

<!DOCTYPE html><html lang="en"><head>  <script src="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Cesium.js"></script>  <link href="https://cesium.com/downloads/cesiumjs/releases/1.115/Build/Cesium/Widgets/widgets.css" rel="stylesheet">  <link href="style.css" rel="stylesheet">  <style type="text/css">    #toggle-building { z-index: 1; position: fixed; top: 5px; left: 5px; }</style></head><body type="module">  <div id="cesiumContainer"></div>  <button id="toggle-building">Toggle new building</button>    <script>    // Your access token can be found at: https://ion.cesium.com/tokens.    // Replace `your_access_token` with your Cesium ion access token.    Cesium.Ion.defaultAccessToken = 'your_access_token';
    // Keep your Cesium.Ion.defaultAccessToken = 'your_token_here' line from above.     // STEP 2 CODE    // Initialize the viewer with Cesium World Terrain.    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)    }); */
    // Add Cesium OSM Buildings.    const buildingsTileset = await Cesium.createOsmBuildingsAsync();    viewer.scene.primitives.add(buildingsTileset);
    // STEP 3 CODE    async function addBuildingGeoJSON() {      // Load the GeoJSON file from Cesium ion.      const geoJSONURL = await Cesium.IonResource.fromAssetId(your_asset_id);      // Create the geometry from the GeoJSON, and clamp it to the ground.      const geoJSON = await Cesium.GeoJsonDataSource.load(geoJSONURL, { clampToGround: true });      // Add it to the scene.      const dataSource = await viewer.dataSources.add(geoJSON);      // 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;      }      // Move the camera so that the polygon is in view.      // viewer.flyTo(dataSource);    }    addBuildingGeoJSON();
    // 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} === 532245203', 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')"    });
    // STEP 6 CODE    // Add the 3D Tileset you created from your Cesium ion account.    const newBuildingTileset = await Cesium.Cesium3DTileset.fromIonAssetId(your_asset_id);    viewer.scene.primitives.add(newBuildingTileset);
    // Move the camera to the new building.    viewer.flyTo(newBuildingTileset);
    // STEP 7 CODE    // Toggle the tileset's show property when the button is clicked.    document.querySelector('#toggle-building').onclick = function() {      newBuildingTileset.show = !newBuildingTileset.show;    };</script></body></html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1532893.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态规划(算法竞赛、蓝桥杯)--斜率优化DP打印文章

1、B站视频链接&#xff1a;E51【模板】斜率优化DP 打印文章_哔哩哔哩_bilibili 题目链接&#xff1a;Problem - 3507 #include <bits/stdc.h> using namespace std; typedef long long LL; const int N500010; int n,m,q[N]; LL s[N],f[N];double sl(int i,int j){ret…

Qt笔记 事件处理_鼠标事件

什么是事件&#xff1f; 点击鼠标左键&#xff0c;双击鼠标左键&#xff0c;鼠标来回移动&#xff0c;按下键盘按钮&#xff0c;这些都是事件。 那么事件的响应机制是什么样的呢&#xff1f; 首先main函数中有一个QApplication&#xff0c;其作用是创建一个应用程序对象&…

web自动化3-pytest前后夹具

一、pytest前后置&#xff08;夹具&#xff09;-fixture 夹具的作用&#xff1a;在用例执行之前和之后&#xff0c;需要做的准备工作之前和收尾工作。 用于固定测试环境&#xff0c;以及清理回收资源。 举个例子&#xff1a;访问一个被测页面-登录页面&#xff0c;执行测试用…

my2sql —— go语言版binlog解析及闪回工具

之前学习过python语言版binlog解析及闪回工具 MySQL闪回工具简介 及 binlog2sql工具用法 最近听同事介绍有了新的go语言版的my2sql。优点是不需要安装一大堆依赖包&#xff0c;直接可以安装使用&#xff0c;并且解析更高效&#xff0c;试用一下。 一、 下载安装 1. 软件下载 …

React函数组件Hook

问题: 相对于类组件, 函数组件的编码更简单, 效率也更高, 但函数组件不能有state (旧版) 解决: React 16.8版本设计了一套新的语法来让函数组件也可以有state Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 Hook也叫钩子…

从边缘设备丰富你的 Elasticsearch 文档

作者&#xff1a;David Pilato 我们在之前的文章中已经了解了如何丰富 Elasticsearch 本身和 Logstash 中的数据。 但如果我们可以从边缘设备中做到这一点呢&#xff1f; 这将减少 Elasticsearch 要做的工作。 让我们看看如何从具有代理处理器的 Elastic 代理中执行此操作。 E…

Introduction to Data Mining 数据挖掘

Why Data Mining? • The Explosive Growth of Data: from terabytes to petabytes — Data collection and data availability ◦ Automated data collection tools, database systems, Web, computerized society — Major sources of abundant data ◦ Business: Web, e-co…

Linux-shell中变量的引用($变量名,${变量名})

1. 背景 最近写脚本时&#xff0c;发现有个变量在某个地方生效&#xff0c;某个地方又不生效&#xff0c;引用方式为 $变量名。 2. 方法 其实 shell 脚本中对变量的引用有两种方式&#xff1a; $变量名${变量名} 用下面的脚步&#xff0c;去测试效果&#xff1a; a100 b2…

excel处理_多个excel文件合并

data文件夹内&#xff0c;有多个xls文件。每个xls文件格式一致&#xff0c; 表头占两行&#xff0c;表位汇总数据占一行。 表头两行&#xff0c;拼接前第二行设置为表头&#xff0c;且删除第二行。 在python读入的dataframe中&#xff0c;游轮成本表是表头&#xff0c;第一行是…

Python 深度学习第二版(GPT 重译)(四)

九、高级计算机视觉深度学习 本章涵盖 计算机视觉的不同分支&#xff1a;图像分类、图像分割、目标检测 现代卷积神经网络架构模式&#xff1a;残差连接、批量归一化、深度可分离卷积 可视化和解释卷积神经网络学习的技术 上一章通过简单模型&#xff08;一堆Conv2D和MaxP…

【鸿蒙HarmonyOS开发笔记】通知模块之为通知添加行为意图

概述 WantAgent提供了封装行为意图的能力&#xff0c;这里所说的行为意图主要是指拉起指定的应用组件及发布公共事件等能力。HarmonyOS支持以通知的形式&#xff0c;将WantAgent从发布方传递至接收方&#xff0c;从而在接收方触发WantAgent中指定的意图。例如&#xff0c;在通…

js【详解】深拷贝

什么是深拷贝&#xff1f; 对于引用类型的数据&#xff0c;才有深浅拷贝的说法 浅拷贝 &#xff1a;执行拷贝的变量只复制被拷贝变量内存的引用数据的地址。 被拷贝变量内地址指向的数据发生变化时&#xff0c;执行拷贝的变量也会同步改变 深拷贝&#xff1a; 在堆内存中开…

迁移学习的技术突破与应用前景

目录 前言1 迁移学习技术1.1 原理与分类1.2 主要挑战 2 迁移学习应用2.1 计算机视觉2.2 医疗健康 3 未来展望3.1 推动各领域发展3.2 提高模型泛化能力和效果3.3 在新兴领域中广泛应用 结语 前言 迁移学习作为机器学习领域的重要技术之一&#xff0c;以其能够将从一个任务中学到…

[C语言]——内存函数

目录 一.memcpy使用和模拟实现&#xff08;内存拷贝&#xff09; 二.memmove 使用和模拟实现 三.memset 函数的使用&#xff08;内存设置&#xff09; 四.memcmp 函数的使用 C语言中规定&#xff1a; memcpy拷贝的就是不重叠的内存memmove拷贝的就是重叠的内存但是在VS202…

腾讯和香港中文大学发布文字生成视频AI模型DynamiCrafter

前言 在数字化时代&#xff0c;视觉内容的创造和动态化已成为创意表达和信息传递的重要工具。最近由香港中文大学、腾讯AI Lab联合研发的视频AI模型DynamiCrafter&#xff0c;这一模型能够将静态图像转化为逼真的动态视频&#xff0c;开创了文本到视频生成技术的新纪元。 Hugg…

Nexus介绍

1.什么是Nexus Nexus是一个强大的仓库管理器&#xff0c;主要用于搭建和管理公司内部的软件构件仓库。 以下是一些关于Nexus的重要信息&#xff1a; 功能&#xff1a;Nexus可以作为Maven、NuGet、npm等工具的仓库服务器&#xff0c;允许用户在本地网络中共享和管理依赖项和构…

计算机三级——网络技术(综合题第二题)

路由器工作模式 用户模式 当通过Console或Telnet方式登录到路由器时&#xff0c;只要输入的密码正确&#xff0c;路由器就直接进入了用户模式。在该模式下&#xff0c;系统提示符为一个尖括号(>)。如果用户以前为路由器输入过名称&#xff0c;则该名称将会显示在尖指号的前…

目标检测——YOLOX算法解读

论文&#xff1a;YOLOX: Exceeding YOLO Series in 2021(2021.7.18) 作者&#xff1a;Zheng Ge, Songtao Liu, Feng Wang, Zeming Li, Jian Sun 链接&#xff1a;https://arxiv.org/abs/2107.08430 代码&#xff1a;https://github.com/Megvii-BaseDetection/YOLOX YOLO系列算法…

序列化与反序列化介绍

文章目录 一、序列化与反序列化二、PHP反序列化漏洞成因三、JAVA反序列化 一、序列化与反序列化 在PHP语言开发层面上基本都是围绕着serialize()&#xff0c;unserialize()这两个函数。serialize()函数序列化对象后&#xff0c;可以很方便的将它传递给其他需要它的地方&#x…

【数据结构和算法初阶(C语言)】二叉树的顺序结构--堆的实现/堆排序/topk问题详解---二叉树学习日记②12

目录 ​编辑 1.二叉树的顺序结构及实现 1.1 二叉树的顺序结构 2 堆的概念及结构 3 堆的实现 3.1堆的代码定义 3.2堆插入数据 3.3打印堆数据 3.4堆的数据的删除 3.5获取根部数据 3.6判断堆是否为空 3.7 堆的销毁 4.建堆以及堆排序 4.1堆排序---是一种选择排序 4.2升序建大堆&a…