Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型
今天简单实现一个Cesium.js的小Demo,加强自己对Cesium知识的掌握与学习,先简单对这个开源库进行一个简单的介绍吧!
Cesium 是一个开源的地理空间可视化引擎,用于创建基于 Web 的三维地球应用程序。它允许开发人员在网页上呈现高度可视化的地球数据,包括地形、卫星影像、建筑物、地理信息系统 (GIS) 数据等。其提供了强大的 JavaScript 库和 API,使开发人员可以轻松地构建交互式、高性能的地球应用。
总的来说,Cesium 是一个强大的工具,可以帮助开发者构建高度交互和可视化的地球应用,适用于各种领域,包括地理信息系统、虚拟旅游、航空航天等。接下来开始正式的学习!
目录
项目搭建
添加纽约建筑模型
划分城市区域
设置地图标记
设置模型运动轨迹
项目搭建
本案例还是借助框架书写cesium项目,借用vite构建工具搭建vue项目,vite这个构建工具如果有不了解的朋友,可以参考我之前对其讲解的文章:vite脚手架的搭建与使用。搭建完成之后,用编辑器打开该项目,在终端执行 npm i 安装一下依赖即可。
接下来简单的介绍一下Cesium,该开源库在vite官网社区插件中已经给出了相关的链接,如下:
社区插件链接中提供了许多vite工具集成的插件,并提供了相关插件的链接,cesium如下:
我们点击该 链接 ,就跳转到cesium相关介绍的github页面,这里提供了该插件的下载命令以及相关的配置使用介绍,下载命令如下,直接复制即可:
npm i cesium vite-plugin-cesium vite -D
根据官网的介绍,我们需要在vite.config.js中进行相应的代码配置,如下:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 导入cesium插件
import cesium from 'vite-plugin-cesium';export default defineConfig({plugins: [vue(), cesium()], // 调用cesium插件
})
配置完成之后,我们回到App根组件,然后我们引入cesium的全局对象进行测试,如下:
<template><div id="cesiumContainer"></div>
</template><script setup>
import { ref, onMounted } from 'vue'
import * as Cesium from 'cesium';onMounted(() => {const viewer = new Cesium.Viewer('cesiumContainer', { infoBox: false });});
</script><style scoped lang="scss">
#cesiumContainer {width: 100%;height: 100vh;overflow: hidden;
}
</style>
运行我们的项目,打开浏览器就可以看到我们下面的一个地球样式,我们也可以对其进行相关操作
当然我们也可以查看 https://cesium.com/ 查阅相关Cesium相关的知识:
通过翻阅 Cesium相关API进行查看相应的使用 提供了相应的解释:
我们对代码进行如下修改,可以查看到相应的地形地貌:
onMounted(() => {let custom = new Cesium.ArcGisMapServerImageryProvider({url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'});const viewer = new Cesium.Viewer('cesiumContainer', { infoBox: false, // 关闭信息窗口imageryProvider: custom, // 自定义图层terrain: Cesium.Terrain.fromWorldTerrain(), // 开启地形});
});
当然我们也可以设置一开始聚焦的相机位置:
onMounted(() => {let custom = new Cesium.ArcGisMapServerImageryProvider({url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'});const viewer = new Cesium.Viewer('cesiumContainer', { infoBox: false, // 关闭信息窗口imageryProvider: custom, // 自定义图层terrain: Cesium.Terrain.fromWorldTerrain(), // 开启地形});viewer.camera.setView({destination: Cesium.Cartesian3.fromDegrees(116.2317, 39.5427, 200), // 坐标orientation: {heading: Cesium.Math.toRadians(90), // 方向pitch: Cesium.Math.toRadians(25), // 倾斜}})
});
定位的坐标方向,画面还是挺壮观的。(我爱说实话!)
添加纽约建筑模型
根据上文我们了解到的cesium的基本操作,接下来我们拿纽约这个地方进行举例,首先我们先掌握如何加载模型,我们打开 cesium官网 ,进行一个简单的注册,该官网和github联动的,和github关联一下即可,注册完毕会进入我们这一个控制台,如下:
因为纽约模型,cesium官网是提供的,我们点击Asset Depot选择相应的模型添加到My Assets:
选择我们相应添加的模型,复制代码到我们的项目即可,非常方便:
我们在场景加载的时候相机直接定位到纽约的位置,然后加载纽约的模型,如下:
onMounted(async () => {let custom = new Cesium.ArcGisMapServerImageryProvider({url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'});const viewer = new Cesium.Viewer('cesiumContainer', { infoBox: false, // 关闭信息窗口imageryProvider: custom, // 自定义图层terrain: Cesium.Terrain.fromWorldTerrain(), // 开启地形});viewer.camera.setView({destination:new Cesium.Cartesian3(1332761, -4662399, 4137888),orientation:{heading: 0.60,pitch: -0.66}})// 加载3DTiles纽约数据let city = viewer.scene.primitives.add( await Cesium.Cesium3DTileset.fromIonAssetId(2275207));
});
最终达到的效果如下,画面还不错(我爱说实话!)
划分城市区域
接下来我们通过GeoJSON来划分城市区域,GeoJSON(JavaScript Object Notation, 简称JSON)是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法的地理空间信息数据交换格式,可以表示几何、特征或者特征集合。
接下来我们调用GeoJson文件加载纽约区域的领域边界:
// 调用 GeoJson 文件加载邻域边界
let neighborhoodsPromise = Cesium.GeoJsonDataSource.load('/public/assets/SampleData/sampleNeighborhoods.geojson');
接下来将加载的地理数据(如街区或区域)添加到 Cesium 地球查看器(viewer)中,并对这些数据进行着色调整,并确保它们贴在地图表面上。
// 贴在地图表面
neighborhoodsPromise.then((dataSource) => {// 将数据添加到查看器viewer.dataSources.add(dataSource);// 把数据进行着色的调整以及放到地图的表面// 拿到区域的实例 Get the array of entitieslet neighborhoodsEntities = dataSource.entities.values;for (let i = 0; i < neighborhoodsEntities.length; i++) {let entity = neighborhoodsEntities[i];// 判断存不存在相应的图形 if (Cesium.defined(entity.polygon)) {entity.name = entity.properties.neighborhood;// 设置多边形颜色entity.polygon.material = Cesium.Color.fromRandom({red: 0.1, // 随机颜色maximumGreen: 0.5, // 最大绿色minimumBlue: 0.5, // 最小蓝色alpha: 0.6 // 透明度});// 设置地形着色entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;// 设置位置 贴到多边形最底下let polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;entity.position = Cesium.Ellipsoid.WGS84.scaleToGeocentricSurface(Cesium.BoundingSphere.fromPoints(polyPositions).center,);}}
})
加载地理数据并在地图上显示,同时对加载的多边形进行着色调整,并确保它们贴在地球表面上,并为每个多边形添加标签。
// 生成标签
entity.label = {text: entity.name,showBackground: true,scale: 0.6,horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,// 设置显示的距离范围distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10, 8000),// 禁用的距离disableDepthTestDistance: 100
}
最终呈现的效果如下所示:
然后我们也可以通过鼠标点击某个标签进行区域的锁定,然后滑动鼠标进行详细查看:
设置地图标记
接下来通过KML文件进行图标标记,KML文件是谷歌公司创建的一种地标性文件,用于记录某一地点、或连续地点的时间、经度、纬度、海拔等地理信息数据,供GE等有关软件使用。
let kmlOptions = {camera : viewer.scene.camera,canvas : viewer.scene.canvas,// 如果我们想要将几何特征(多边形、线串和线性环)固定在地面上,则为 true。clampToGround : true
};
let geocachePromise = Cesium.KmlDataSource.load('/public/assets/SampleData/sampleGeocacheLocations.kml', kmlOptions);
接下来将 geocache 广告牌实体添加到场景中并为其设置样式:
geocachePromise.then(function(dataSource) {// 将新数据作为实体添加到查看器viewer.dataSources.add(dataSource);// 获取实体数组var geocacheEntities = dataSource.entities.values;for (var i = 0; i < geocacheEntities.length; i++) {var entity = geocacheEntities[i];if (Cesium.defined(entity.billboard)) {// 调整垂直原点,使图钉位于地形上entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;entity.billboard.image = '/public/assets/tagpark.png'// 禁用标签以减少混乱entity.label = undefined;// 添加距离显示条件entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);// 以度为单位计算纬度和经度var cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now()));var latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);var longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);// 修改描述var description = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>' +'<tr><th>' + "Longitude" + '</th><td>' + longitude.toFixed(5) + '</td></tr>' +'<tr><th>' + "Latitude" + '</th><td>' + latitude.toFixed(5) + '</td></tr>' +'<tr><th>' + "实时人流" + '</th><td>' + Math.floor(Math.random()*20000) + '</td></tr>' +'<tr><th>' + "安全等级" + '</th><td>' + Math.floor(Math.random()*5) + '</td></tr>' +'</tbody></table>';entity.description = description;}}
});
最终呈现的效果如下所示,感觉还不错!(我爱说实话)
设置模型运动轨迹
接下来我们实现一个3D模型沿着地图上我们设置的轨迹进行运动,这里需要加载一个czml文件,该文件是一种用于描述三维场景的文本格式,通常与Cesium.js一起使用。它允许开发者以一种结构化的方式描述地球上的实体、图形、动画和其他地理空间信息,从而创建动态的、交互式的地理可视化应用程序。具体代码如下:
// 从czml文件加载模型运动路径
var dronePromise = Cesium.CzmlDataSource.load('/public/assets/SampleData/sampleFlight.czml');// 模型实体
var drone;
dronePromise.then(function(dataSource){viewer.dataSources.add(dataSource);drone = dataSource.entities.getById('Aircraft/Aircraft1');drone.model = {// uri:'/public/assets/SampleData/Models/CesiumDrone.gltf', // 飞机模型uri:'/public/assets/SampleData/Models/ferrari2.gltf', // 汽车模型minimumPixelSize:128, // 最小像素大小maximumScale:1000, // 最大比例silhouetteColor:Cesium.Color.WHITE, // 轮廓颜色silhouetteSize:2 // 轮廓大小}drone.orientation = new Cesium.VelocityOrientationProperty(drone.position); // 运行姿态drone.viewFrom = new Cesium.Cartesian3(0,-30,30) // 运行视角viewer.clock.shouldAnimate = true; // 自动播放
})
最终达到的效果如下:
CZML文件可以手动编写,也可以由各种地理信息系统(GIS)工具或数据源生成。它使用JSON格式,因此易于阅读和编辑。Cesium.js库能够解析和渲染CZML文件,从而在Web浏览器中呈现出动态的地理可视化效果,如下可以看到czml对路径的绘制:
ok,效果完成了,喜欢的朋友点个赞收藏一下吧!
相关文章:
Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型
今天简单实现一个Cesium.js的小Demo,加强自己对Cesium知识的掌握与学习,先简单对这个开源库进行一个简单的介绍吧! Cesium 是一个开源的地理空间可视化引擎,用于创建基于 Web 的三维地球应用程序。它允许开发人员在网页上呈现高度…...
.NET i18n 多语言支持与国际化
环境 WIN10 VS2022 .NET8 1.👋创建项目 2.👀创建Resources Controllers HomeController.en.resx HomeController.fr.resx HomeController.zh.resx 3.🌱Program.cs添加国际化支持 // 添加国际化支持 builder.Services.AddLocalization(…...
基于Pytorch实现图像分类——基于jupyter
分类任务 网络基本构建与训练方法,常用函数解torch.nn.functional模块nn.Module模块 MNIST数据集下载 from pathlib import Path import requestsDATA_PATH Path("data") PATH DATA_PATH / "mnist"PATH.mkdir(parentsTrue, exist_okTrue)U…...
如何将CSDN的文章以PDF文件形式保存到本地
1.F12 打开开发者工具窗口 2.console下输入命令 (function(){$("#side").remove();$("#comment_title, #comment_list, #comment_bar, #comment_form, .announce, #ad_cen, #ad_bot").remove();$(".nav_top_2011, #header, #navigator").remove…...
面试经典150题——删除有序数组中的重复项
面试经典150题 day3 题目来源我的题解方法一 双指针 题目来源 力扣每日一题;题序:26 我的题解 方法一 双指针 使用两个指针分别指向相同元素的左右边界,再利用一个count记录最终需要的数组长度。 时间复杂度:O(n) 空间复杂度&a…...
Unity3D知识点精华浓缩
一、细节 1、类与组件的关系 2、Time.deltaTime的含义 3、怎么表示一帧的移动距离 4、Update和LateUpdate的区别和适用场景 5、找游戏对象的方式(别的对象 / 当前对象的子对象) 6、组件1调用组件2中方法的方式 7、在面板中获取外部数据的方法 8、序列化属…...
HTML的文档说明
1.告诉浏览器当前网页的版本 2.写法: !以前的写法:要依据网页的HTML的版本去确定,紫萼发油很多很多。 具体的写法可以参考:W3C官网的文档说明 !新写法:W3C都推荐用h5的写法 <DOCTYPE ht…...
ubuntu 更新或更改GCC/G++
最近遇到一些问题,需要用到gcc-9/g-9,但是我自带的ubuntu18.04是gcc-7.5/g-7.5,所以升级一下,奈何文章太多而且很多无效,所以在此记录一下: 参考:https://stackoverflow.com/questions/19836858…...
Java --- Java语言基础
这个Java可是个好东西,是一门面对对象的程序设计语言,其语法很类似C,所以学过C的伙伴们就很好上手,另外Java对C进行了简化与提高,这个在后期学习会感受到,Java还有很多的类库API文档以及第三方开发包。 这…...
【C++算法竞赛 · 图论】图的存储
前言 图的存储 邻接矩阵 方法 复杂度 应用 例题 题解 邻接表 方法 复杂度 应用 前言 上一篇文章中(【C算法竞赛 图论】图论基础),介绍了图论相关的概念和一种图的存储的方法,这篇文章将会介绍剩下的两种方法ÿ…...
Spring AOP IOC
spring的优缺点 IOC集中管理对象,对象之间解耦,方便维护对象AOP在不修改原代码的情况下,实现一些拦截提供众多辅助类,方便开发方便集成各种优秀框架 紧耦合和松耦合 松耦合可以使用单一职责原则、接口分离原则、依赖倒置原则 …...
Linux ARM平台开发系列讲解(QEMU篇) 1.1 编译QEMU 构建RISC-V64架构 运行Linux kernel
1. 概述 QEMU可以模拟很多架构的CPU(ARM,RISC-V等),重点是免费,用来学Linux简直太适合不过了,所以,我打算开一章节来教QEMU的使用,这样也方便环境统一调试,本章节就讲解如何在Ubuntu搭建QEMU,我的环境是全新的Ubuntu22,QEMU下载的9.0,kernel下载的6.0. 2. 源码下载…...
Day19-【Java SE进阶】网络编程
一、网络编程 1.概述 可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)。java.net,*包下提供了网络编程的解决方案! 基本的通信架构 基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)。 网络通信的…...
pyqt写个星三角降压启动方式2
星三角降压启动用可以用类进行封装,就像博图FB块那样。把逻辑都在类里完成,和外界需要交互的暴露出接口。测试过程中,发现类中直接用定时器QTimer会出现问题。然后就把定时器放到外面了。然后测试功能正常。 from PySide6.QtWidgets import …...
js可视化爬取数据生成当前热点词汇图
功能 可以爬取到很多数据,并且生成当前的热点词汇图,词越大越热门(词云图) 这里以b站某个评论区的数据为例,爬取63448条数据生成这样的图片 让我们能够更加直观的看到当前的热点 git地址 可以直接使用,中文…...
研发岗-面临统信UOS系统配置总结
第一步 获取root权限 配置环境等都需要用到root权限,所以我们先获取到root权限,方便下面的操作 下载软件 在UOS应用商店下载的所需应用 版本都比较低 安装node 官网下载了【arm64】的包,解压到指定文件夹,设置链接࿰…...
【STL详解 —— list的介绍及使用】
STL详解 —— list的介绍及使用 list的介绍list的介绍使用list的构造list iterator的使用list capacitylist element accesslist modifiers 示例list的迭代器失效 list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭…...
cocos creator开发中遇到的问题和解决方案
前言 总结一下使用cocos开发遇到的坑,不定期更新。 问题汇总 代码修改Position坐标不生效 首先要通过打log或者断点排除下是不是逻辑上的问题,还有是不是有动画相关把位置修改了。我遇到的问题是坐标修改被widget组件覆盖了。 纹理压缩包体变大 co…...
10分钟带你学会配置DNS服务正反向解析
正向解析 服务端IP客户端IP网址192.168.160.134192.168.160.135www.openlab.com 一、首先做准备工作: 关闭安全软件,关闭防火墙,下载bind软件 [rootserver ~]# setenforce 0 [rootserver ~]# systemctl stop firewalld [rootserver ~]# y…...
【vim 学习系列文章 19 -- 映射快捷键调用两个函数 A 和B】
请阅读【嵌入式开发学习必备专栏 之 Vim】 文章目录 映射快捷键调用两个函数 映射快捷键调用两个函数 在 Vim 中,如果想通过按下 gcm 来调用两个函数,比如 FunctionA 和 FunctionB,需要先定义这两个函数,然后创建一个映射。这个映…...
Windows安装MongoDB结合内网穿透轻松实现公网访问本地数据库
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
sgg大数据全套技术链接[plus]
写在开头:感谢尚硅谷,尚硅谷万岁,我爱尚硅谷 111个技术栈43个项目,兄弟们,冲! 最近小米又又又火了一把,致敬所有造福人民的企业和伟大的企业家,致敬雷军,小米ÿ…...
OpenHarmony南向嵌入式:【XR806开发板指导文档】
一. 简介 芯片介绍 XR806是全志科技旗下子公司广州芯之联研发设计的一款支持WiFi和BLE的高集成度无线MCU芯片,支持OpenHarmony轻量设置系统。具有集成度高、硬件设计简单、BOM成本低、安全可靠等优点。可广泛满足 智能家居、智慧楼宇、工业互联、儿童玩具、电子竞…...
Rust 实战练习 - 10. JSON、XML、YAML/TOML、Ini专题
配置文件 常见的配置文件有很多:JSON, Ini, XML, TOML, YAML … 目标: JSON/YAML/TOMLIniXML Rust中序列化用的最多的是 serde, 依赖它,有很多出色的第三方库可以使用。 其中,serde本身支持JSON/YAML/TOML/JSON5…多种&#…...
5.Hexo为页面标记标签和类别
Hexo的标签和类别基本上是可以在Hexo中将内容分组的两种方式 如果在网站上有一堆内容,有不同的博客文章 将博客文章分类为不同的类别会很有帮助 用特定的关键词为博客文章标记 如果可以同时分类和标记页面,会使网站用户更轻松地找到他们想要的页面类型 …...
·13·1dawwd
c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…...
Docker - PostgreSQL
博文目录 文章目录 说明命令 说明 Docker Hub PostgreSQL 数据卷数据卷印射在容器内的路径postgres/var/lib/postgresql/data |容器内的路径|说明| |–|–|–| |/var/lib/postgresql/data|数据目录| 部分环境变量是否必要说明POSTGRES_PASSWORD必需设置超级用户密码POSTGRES…...
Python | Leetcode Python题解之第26题删除有序数组中的重复项
题目: 题解: class Solution:def removeDuplicates(self, nums: List[int]) -> int:if not nums:return 0n len(nums)fast slow 1while fast < n:if nums[fast] ! nums[fast - 1]:nums[slow] nums[fast]slow 1fast 1return slow...
【电控笔记4】拉普拉斯-传递函数-pid
数据标幺化 拉普拉斯变换 欧拉公式 常见s变换 s变换性质...
针对“AI+医疗”的可行方案
针对“AI医疗”的可行方案如下: 一、方案目标 利用AI技术,结合医疗数据,开发一套高效、准确的医疗辅助系统,旨在提高医疗诊断的精度、加速药物研发进程、优化疾病预测模型,从而辅助医生进行疾病诊断和治疗方案制定。…...
成都个人网站建设/小红书seo优化
1. ResultSet executeQuery(String sql); 执行SQL查询,并返回ResultSet 对象。 2.int executeUpdate(String sql); 可执行增,删,改,返回执行受到影响的行数。 3. boolean execute(String sql); 可执行任何SQL语句,返回…...
北京网站建设模板下载/关键词查询网站
### 一,MySQL的数据类型数据类型是定义列中可以存储什么类型的数据以及该数据实际怎样存储的基本规则数据类型限制存储在数据列列中的数据。例如,数值数据类型列只能接受数值类型的的数据在设计表时,应该特别重视所用的数据类型。使用错误的数据类型可能…...
桥头网站建设/seo搜索引擎优化人员
CPP之面向对象篇 引述,物体,对象,物体共性,pre-defined-class标准库函数; string.a("Ruiy") 成员操作符,操作动作 posted on 2014-05-23 12:05 秦瑞It行程实录 阅读(...) 评论(...) 编辑 收藏 转载于:https://www.cnblogs.com/ruiy/p/vector.html...
网站建设合同.doc/湖北seo诊断
为了练习代码规范,代码逻辑写的一个控制台小游戏。可以无限玩,随时可以选择退出。import java.util.Scanner;public class MonkeyGuess {private static Scanner scanner new Scanner(System.in);private static Random random new java.util.Random()…...
用wordpress仿一个网站模板下载/站长工具亚洲
在上篇博客中说到有两种方式启动进程,其中一种就是点击Launcher界面,在点击Launcher最后也会调用Activity的startActivity方法,但是在Launcher中会调用如下代码: [cpp] view plaincopyintent.setFlags(Intent.FLAG_ACTIVITY_NEW_T…...
电商app制作开发/京东关键词优化技巧
历经300多个日夜,2021年8月,基于国产企业级分布式数据库腾讯云TDSQL打造的昆山农商银行新一代核心系统成功投产上线。它采用“微服务应用国产分布式数据库”架构,该架构在同类银行中尚属首次。 新核心系统整体处理能力可以达到6300TPS&#x…...