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

 在本教程中,您将学习如何创建 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.mzph.cn/news/761743.shtml

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

相关文章

Web and HTTP

Web and HTTP First, a review… ▪ web page consists of objects ▪ object can be HTML file, JPEG image, Java applet, audio file,… ▪ web page consists of base HTML-file which includes several referenced objects ▪ each object is addressable by a URL, e.g.,…

MAC本安装telnet

Linux运维工具-ywtool 目录 1.打开终端1.先安装brew命令2.写入环境变量4.安装telnet 1.打开终端 访达 - 应用程序(左侧) - 实用工具(右侧) - 终端 #注意:登入终端用普通用户,不要用MAC的root用户1.先安装brew命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/H…

Databend x CubeFS:面向未来的企业级云原生数据存储与分析

用场景的丰富&#xff0c;企业面临着前所未有的数据存储挑战。大规模数据存储变得日常化&#xff0c;伴随着超大容量和快速变化的I/O需求&#xff0c;传统的存储解决方案已经难以满足企业对弹性、运维效率及总体拥有成本&#xff08;TCO&#xff09;的更高要求。这些挑战促使基…

基于傅里叶描述子的手势动作识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

数学建模(灰色关联度 python代码 案例)

目录 介绍&#xff1a; 模板&#xff1a; 案例&#xff1a;哪些原因影响结婚率 数据标准化&#xff1a; 灰色关联度系数&#xff1a; 完整代码&#xff1a; 结果&#xff1a; 介绍&#xff1a; 灰色关联度是一种多指标综合评价方法&#xff0c;用于分析和评价不同指标之…

由浅到深认识Java语言(9):Eclipse IDE简介

该文章Github地址&#xff1a;https://github.com/AntonyCheng/java-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

华为配置蓝牙终端定位实验

配置蓝牙终端定位示例 组网图形 图1 配置蓝牙终端定位示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 商场管理员希望在已有WLAN覆盖业务的基础上&#xff0c;使用蓝牙定位技术&#xff0c;根据顾客所在的位置&#xff0c;提供商场导航、导…

php 对接Vungle海外广告平台收益接口Reporting API

今天对接的是Vungle广告reporting api接口&#xff0c;拉取广告收益回来自己做统计。记录分享给大家 首先是文档地址,进入到Vungle后台就能看到文档地址以及参数&#xff1a; 文档地址&#xff1a;https://support.vungle.com/hc/en-us/articles/211365828-Publisher-Reporting…

AI助力生产制造质检,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建工业生产制造场景下的瓷砖瑕疵检测识别分析系统

瓷砖生产环节一般经过原材料混合研磨、脱水、压胚、喷墨印花、淋釉、烧制、抛光&#xff0c;最后进行质量检测和包装。得益于产业自动化的发展&#xff0c;目前生产环节已基本实现无人化。而质量检测环节仍大量依赖人工完成。一般来说&#xff0c;一条产线需要配数名质检工&…

【C++】1416. 求长方形的周长和面积

问题&#xff1a;1416. 求长方形的周长和面积 类型&#xff1a; 基本运算、整数运算 题目描述&#xff1a; 从键盘读入2个整数&#xff0c;分别代表一个长方形的长和宽&#xff0c;请计算长方形的周长和面积&#xff1b; 输入&#xff1a; 从键盘读入2个整数&#xff0c;用…

STM32利用串口外设发送数据

今天2024.3.21日上午学习了一下基本的串口初始化&#xff0c;利用串口发送一个字节的数据&#xff0c;看时间也快11点了&#xff0c;上午就学习这么多吧&#xff0c;把上午的知识总结一下&#xff0c;串口初始化的过程&#xff1a; 看着图来编写串口初始化的过程&#xff1a; …

GPT-4 vs. ChatGPT:19个弱项问题(多步逻辑推理、概念间接关联)的横向对比

测试对比&#xff1a;在逻辑推理和概念关联方面&#xff0c;GPT-4 显著优于 ChatGPT&#xff0c;准确率从37%提升至100%。智力水平&#xff1a;GPT-4 的思维智力表现可能超过了95%的人。技术进步&#xff1a;短时间内&#xff0c;GPT-4 显著进步&#xff0c;尤其在逻辑能力和多…

超越 GPT-4V 和 Gemini Pro!HyperGAI 发布最新多模态大模型 HPT,已开源

随着AI从有限数据迈向真实世界&#xff0c;极速增长的数据规模不仅赋予了模型令人惊喜的能力&#xff0c;也给多模态模型提供了更多的可能性。OpenAI在发布GPT-4V时就已经明确表示&#xff1a; 将额外模态&#xff08;如图像输入&#xff09;融入大语言模型&#xff08;LLMs&am…

java JVM详解(持续更新)

JVM定义 JVM结构 类装载子系统 双亲委派模型 运行时数据区 方法区&#xff08;Method Area&#xff09; 堆区&#xff08;Heap&#xff09; 虚拟机栈区 程序计数区 执行引擎子系统 垃圾回收机制 内存分代机制 JVM调优 JVM面试题 JVM定义 JVM它是jre的一部分&#xff0c;也…

静态路由实验(HCIP部分)

1、拓扑信息 2、需求分析 3、IP规划 4、配置截图 5、测试 1、拓扑信息 2、需求分析 1、 R6为isp,接口IP地址均为公有地址&#xff1b;该设备只能配置IP地址&#xff0c;之后不能再对其进行其他任何配置; 分析&#xff1a; R6只需配置一个环回和链路物理接口IP即可 2 、R1-R5为…

导出excel按动态表头导出

一、实现代码 使用Map方式添加head头&#xff0c;对应填充值 /*** 导出查看发车明细* param query* return*/Overridepublic ExportResult monthResourcePlanDepartureProgressDetailsExportExcelData(ResourceSituationListQuery query) {log.info("导出参数:{}",Ds…

FPGA开源项目分享——基于FPGA加速的热扩散模拟器

导语 今天继续分享康奈尔大学FPGA课程ECE 5760的典型案例——基于FPGA加速的热扩散模拟器。 &#xff08;更多其他案例请参考网站&#xff1a; Final Projects ECE 5760&#xff09; 1. 项目概述 项目网址 https://people.ece.cornell.edu/land/courses/ece5760/FinalProje…

多区域ISIS路由计算

多区域ISIS路由计算&#xff1a; 1、骨干区域是如何访问非骨干区域&#xff1f;&#xff08;R4如何学习到200.200/32的路由&#xff1f;&#xff09; 1.1 默认情况下&#xff0c;L1/2级别路由器会将L1级别LSDB中的叶子信息&#xff0c;作为自己L2级别实节点的叶子信息添加到L2的…

旅游小程序的市场与发展趋势

随着科技的发展&#xff0c;移动互联网已经成为我们生活中不可或缺的一部分。在这个时代&#xff0c;小程序已经成为了一种新的趋势&#xff0c;尤其是在旅游行业。那么&#xff0c;旅游小程序有哪些市场&#xff0c;发展趋势又怎么样呢&#xff1f; 一、旅游小程序的市场 1. 用…

3D高斯泼溅的崛起

沉浸式媒体领域正在以前所未有的速度发展&#xff0c;其中 3D 高斯溅射成为一项关键突破。 这项技术在广泛的应用中看起来非常有前景&#xff0c;并且可能会彻底改变我们未来创建数字环境以及与数字环境交互的方式。 在本文中&#xff0c;我们将通过与摄影测量和 NeRF 等前辈进…