在 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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

陈巍:Sora大模型技术精要万字详解(上)——原理、关键技术、模型架构详解与应用

​目录 收起 1 Sora的技术特点与原理 1.1 技术特点概述 1.2 时间长度与时序一致性 1.3 真实世界物理状态模拟 1.4 Sora原理 1.4.1扩散模型与单帧图像的生成 1.4.2 Transformer模型与连续视频语义的生成 1.4.3 从文本输入到视频生成 2 Sora的关键技术 2.1 传统文生图技…

什么是智能物联网关?有哪些作用?

随着物联网技术的不断发展和普及&#xff0c;智能物联网关已经成为连接物理世界与数字世界的桥梁&#xff0c;成为实现万物互联的重要枢纽。那么&#xff0c;什么是智能物联网关&#xff1f;它又有哪些价值呢&#xff1f;今天&#xff0c;就让我们一起走进HiWoo Box的世界&…

uniapp微信小程序_购物车_下单页面

先说下整体逻辑以方便总体理解 1、首先画出下单页面 2、此次画出结算价格页面 3、怎么点击下完单变成结算页面&#xff1f;其实就是把下单页面的信息传递给结算页面就行 问题难点&#xff1f; 点击加号的时候把物品加入一个数组传到下单页面&#xff0c;但是点击的时候不能…

SpringMVC | Spring MVC中的“拦截器”

目录: 拦截器 &#xff1a;1. 拦截器的 “概述”2. 拦截器的 “定义” (创建“拦截器”对象)3. 拦截器的 “配置” (让“拦截器”对象生效)4. 拦截器的 “执行流程”“单个拦截器”的执行流程“多个拦截器”的执行流程 作者简介 &#xff1a;一只大皮卡丘&#xff0c;计算机专业…

sentinel整合gateway实现服务限流

导入依赖: <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.csp</groupId><…

LeetCode_Java_递归系列(题目+思路+代码)

206.反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]以此类推&#xff0c;直到反转结束返回头结点 class Solution {public ListNode rever…

仅用一个月,游卡完成从MySQL到上线OceanBase的实践

编者按&#xff1a;自2023年9月起&#xff0c;游卡——国内最早卡牌游戏研发者之一&#xff0c;开始测试OceanBase&#xff0c;并在短短两个月内成功将三个核心业务应用迁移至OceanBase上。究竟是何因素促使游卡放弃游戏行业普遍采用的MySQL方案&#xff0c;转而大胆选择OceanB…

微服务网关介绍

1. 为什么是Spring Cloud Gateway 一句话&#xff0c;Spring Cloud已经放弃Netflix Zuul了。现在Spring Cloud中引用的还是Zuul 1.x版本&#xff0c;而这个版本是基于过滤器的&#xff0c;是阻塞IO&#xff0c;不支持长连接。Zuul 2.x版本跟1.x的架构大一样&#xff0c;性能也有…

图像分割论文阅读:Adaptive Context Selection for Polyp Segmentation

这篇论文的主要内容是关于一种用于息肉分割的自适应上下文选择网络&#xff08;Adaptive Context Selection Network&#xff0c;简称ACSNet&#xff09; 1&#xff0c;模型的整体结构 模型的整体结构基于编码器-解码器框架&#xff0c;并且包含了三个关键模块&#xff1a;局部…

【文末附gpt升级4.0方案】FastGPT详解

FastGPT知识库结构讲解 FastGPT是一个基于GPT模型的知识库&#xff0c;它的结构可以分为以下几个部分&#xff1a; 1. 数据收集&#xff1a;FastGPT的知识库是通过从互联网上收集大量的文本数据来构建的。这些数据可以包括维基百科、新闻文章、论坛帖子等各种类型的文本。 2…

HTML静态网页成品作业(HTML+CSS+JS)——中华美食八大菜系介绍(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;使用Javacsript代码实现图片轮播切换&#xff0c;共有1个页面。 二、…

探索国内ip切换App:打破网络限制

在国内网络环境中&#xff0c;有时我们会遇到一些限制或者屏蔽&#xff0c;使得我们无法自由访问一些网站或服务。而国内IP切换App的出现&#xff0c;为解决这些问题提供了非常便捷的方式。这些App可以帮助用户切换IP地址&#xff0c;让用户可以轻松地访问被限制或屏蔽的网站&a…

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

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

鸿蒙一次开发,多端部署(一)简介

背景 随着终端设备形态日益多样化&#xff0c;分布式技术逐渐打破单一硬件边界&#xff0c;一个应用或服务&#xff0c;可以在不同的硬件设备之间随意调用、互助共享&#xff0c;让用户享受无缝的全场景体验。而作为应用开发者&#xff0c;广泛的设备类型也能为应用带来广大的…

Unity访问安卓(Android)或苹果(iOS)相册

1.下载Native Gallery for Android & iOS插件 2.在场景中添加截图按钮、选择图片按钮、选择视频按钮等 using OpenCVForUnity.CoreModule; using OpenCVForUnity.ImgprocModule; using OpenCVForUnity.UnityUtils; using System.Collections; using System.Collections.Gen…

线段树+暴力区修 P4145 上帝造题的七分钟 2 / 花神游历各国

传送门https://www.luogu.com.cn/problem/P4145 这道题着实想了好久&#xff0c;本来想的是用数学方法找规律&#xff0c;结果写了好久&#xff0c;发现想假了&#xff0c;于是只好看思路&#xff0c;暴力区修&#xff01;原因是被开根号一定次数就会变成1&#xff0c;是有限的…

安卓studio连接手机之后,一两秒之后就自动断开了。问题解决。

太坑了&#xff0c;安卓studio链接手机之后。几秒之后就断开了。我以为是adb的问题&#xff0c;就重新安装了一下adb。并且在环境变量中配置了Path的路径。然而并没有什么用啊。 后来查看是wps的服务和ADB有冲突。直接把WPS卸载掉之后就没有出现链接手机闪现的的问题。

网络通信——IP地址、端口号、协议(TCP、UDP)

通信架构 网络通信三要素 IP地址 IPv4地址 IPv6地址 IP域名 IP常识 端口号 概念 协议 开放式网络互联标准&#xff1a;OSI、TCP/IP 传输层的2个通信协议——UDP、TCP TCP协议&#xff1a;三次握手建立建立可靠连接 进行三次握手的原因&#xff1a;为了确保客户端和服务端…

在基于Android相机预览的CV应用程序中使用 OpenCL

查看&#xff1a;OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV4.9.0在Android 开发简介 下一篇&#xff1a;在 MacOS 中安装 本指南旨在帮助您在基于 Android 相机预览的 CV 应用程序中使用 OpenCL ™。教程是为 Android Studio 20…

复习斐波那契(用C++写)

或者这样写&#xff1a; 斐波那契数列 题目描述 斐波那契数列是指这样的数列&#xff1a;数列的第一个和第二个数都为 1 1 1&#xff0c;接下来每个数都等于前面 2 2 2 个数之和。 给出一个正整数 a a a&#xff0c;要求斐波那契数列中第 a a a 个数是多少。 输入格式…