Cesium.js--》探秘Cesium背后的3D模型魔力—加载纽约模型
时间:2024-04-18 15:50:19 来源:网络cs 作者:焦糖 栏目:选词工具 阅读:
今天简单实现一个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 entities let 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,效果完成了,喜欢的朋友点个赞收藏一下吧!
本文链接:https://www.kjpai.cn/news/2024-04-18/160088.html,文章来源:网络cs,作者:焦糖,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!
上一篇:HTML基础——表单标签
下一篇:返回列表