技术标签: cesium 图形图像 javascript
Cesium是国外一个基于javascript的地图引擎,支持3D、2D、2.5D形式的展示,可以自行绘制图形、高亮区域,并提供良好的触摸支持,并支持大多数的浏览器和移动端。
当前案例基于vue3+vite
构建
npm i cesium vite-plugin-cesium vite -D
# yarn add cesium vite-plugin-cesium vite -D
vite.config.js
配置:
import {
defineConfig } from 'vite';
import cesium from 'vite-plugin-cesium';
export default defineConfig({
plugins: [cesium()]
});
<template>
<div id="cesiumContainer"></div>
</template>
<script lang="ts" setup>
import {
onMounted } from "vue";
import {
Viewer } from 'cesium';
onMounted(() => {
const viewer = new Viewer('cesiumContainer');
})
</script>
<style lang="scss" scoped></style>
在我们使用Cesium的过程中,如果没有申请ion,同时没有自己的数据源用的cesium提供的数据源,viewer的底部常常会提示一行小的英文字母。大意就是需要申请access token
.
Access Tokens page
页面。Cesium Viewer
的时候,将access token
填为自己的access token即可。Cesium.Ion.defaultAccessToken = '<YOUR ACCESS TOKEN HERE>';
此时底部的小字就消失了!
以上就能畅快的访问Cesium ion提供的各种数据源了。
Cesium应用程序另一个关键元素是Imagery(图层)。瓦片图集合根据不同的投影方式映射到虚拟的三维数字地球表面。依赖于相机指向地表的方向和距离,Cesium会去请求和渲染不同层级的图层详细信息。
多种图层能够被添加、移除、排序和适应到Cesium中。
Cesium提供了一系列方法用于处理图层,比如颜色自适应,图层叠加融合。一些样例代码如下:
Cesium提供了各种 接口 支持各样的图层数据源。
支持的图层格式
注意:不同的数据源需要不同的认证 - 需要确保自己能够有权限访问到这些数据源,自然地需要注册特定的认证才可以
默认地,Cesium使用Bing Maps
作为默认的图层。这个图层被打包进Viewer中用于演示。Cesium需要您自己创建ion account然后生成一个access key用于访问图层数据。
去Cesium ion
页面,将Sentinel-2图层加入到自己的assets中。点击在导航栏中点击“Asset Depot
”
点击 Add to my assets。Sentinel-2将在你个人用户中的asset列表(My Assets)中出现,此时将在个人的app中图层数据源变得可用。
代码修改
我们创建一个IonImageryProvider
,将assetId传给对应的Sentinel-2
图层。然后我们将ImageryProvider
添加到viewer.imageryLayers
。
// Remove default base layer
viewer.imageryLayers.remove(viewer.imageryLayers.get(0));
// Add Sentinel-2 imagery
viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({
assetId : 3954 }));
Sentinel-2:全世界的无云卫星图像,分辨率可降至10米
Cesium支持流式的、可视化的全球高程投影地形地势、水形数据,包括海洋、湖泊、河流、山峰、峡谷和其他能够被三维展示出来的且效果比二维好的地形数据。像图层数据一样,Cesium引擎会从一个服务器上请求流式地形数据,仅请求那些基于当前相机能看到的需要绘制的图层上的数据。
Cesium官方提供了一些地形数据集的例子,以及如何配置这些参数。
支持的地形数据格式:
为了添加地形数据,我们需要创建一个CesiumTerrainProvider
,提供一个url和一些配置项,然后将这个provider赋值给viewer.terrainProvider
。
此处,我们使用Cesium WorldTerrian
图层,该图层由Cesium ion
提供,在“My Assets”中是默认提供的。我们可以用createWorldTerrainhelper
函数创建一个由Cesium ion提供服务的Cesium WorldTerrian。
// Load Cesium World Terrain
viewer.terrainProvider = Cesium.createWorldTerrain({
requestWaterMask : true, // required for water effects
requestVertexNormals : true // required for terrain lighting
});
*requestWaterMask
和requestVertexNormals
是可选的配置项,告诉Cesium是否需要请求额外的水、光数据。这两个选项默认是设为false的。*
最终,既然我们有了地形数据,我们需要更多的线条来使得地形数据背后的objects能够正确地显示,只有最前面、最上面的objects才能是可见的。
// Enable depth testing so things behind the terrain disappear.
viewer.scene.globe.depthTestAgainstTerrain = true;
我们现在有地形数据和运动的水。纽约非常平坦,所以可以在上面的地形数据上自由的探索。举一个显而易见的例子,你可以跳转到更加崎岖的区域比如 Grand Canyon 或者 San Francisco。
接下来将添加一些更多的正确的时间和空间设置到Viewer中。涉及到与viewer.scene进行交互,该类控制了viewer中的所有图形元素。
// Enable lighting based on sun/moon positions
viewer.scene.globe.enableLighting = true;
按照以上配置,我们scene(场景)中的光照将会随着每天时间的变化而变化。如果你zoom out,你就会看到一部分数字地球位于黑暗之中,因为模拟真实的地球,太阳只能照射到地球的一部分。
这些是在场景中定位和定位Cesium objects所必需的基本类型,并且有许多有用的转换方法。请参阅每种类型的文档以了解更多信息。
现在让我们把相机定位在我们数据所在的NYC(纽约)的场景中。
相机是viewer.scene
中的属性,用来控制当前可见的域。我们可以通过直接设置它的位置和方向来控制相机,或者通过使用Cesium提供的API来控制相机,它被设计成指定相机的位置和方向随时间的变化。
一些最常用的方法如下:
Camera.setView(options): 在特定位置和方向立即设置相机。
Camera.zoomIn(amount): 沿着视角矢量移动摄像机。
Camera.zoomOut(amount): 沿视角矢量向后移动摄像机。
Camera.flyTo(options): 创建从当前相机位置到新位置的动画相机飞行。
Camera.lookAt(target, offset) : 定位并定位摄像机以给定偏移量瞄准目标点。
Camera.move(direction, amount) : 朝任何方向移动摄像机。
Camera.rotate(axis, angle) : 绕任意轴旋转相机。
进一步获得API功能,看看这些相机演示:
Camera API Demo
Custom Camera Controls Demo
让我们尝试一种方法将相机跳转到纽约。使用camera.setView()
初始化view,使用Cartesian3和HeadingpitchRoll指定相机的位置和方向:
// Create an initial camera view
var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431);
var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306);
var homeCameraView = {
destination : initialPosition,
orientation : {
heading : initialOrientation.heading,
pitch : initialOrientation.pitch,
roll : initialOrientation.roll
}
};
// Set the initial view
viewer.scene.camera.setView(homeCameraView);
相机现在被定位和定向以俯瞰曼哈顿,并且我们的视图参数被保存在一个对象中,我们可以将其传递给其他相机方法。
效果如下:
实际上,我们可以使用这个相同的视角来更新按下home按钮的效果。我们不必让它从远处返回地球的默认视角,我们可以重写按钮,使我们看到曼哈顿的初始视角。我们可以通过添加几个选项来调整动画,然后添加一个取消默认航班的事件侦听器,并调用FlyTo()
我们的Home视角:
// Add some camera flight animation options
homeCameraView.duration = 2.0;
homeCameraView.maximumHeight = 2000;
homeCameraView.pitchAdjustHeight = 2000;
homeCameraView.endTransform = Cesium.Matrix4.IDENTITY;
// Override the default home button
viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (e) {
e.cancel = true;
viewer.scene.camera.flyTo(homeCameraView);
});
点击Home按钮后,视图会直接跳转到纽约上空
更多关于基本相机控制,请访问我们的Camera Tutorial。
接下来,我们配置viewer的Clock和Timline来控制scene的时间进度。
这里是clock的相关API
当使用特定时间时,Cesium使用JulandDATE类型,它存储了1月1日中午以来的天数-4712(公元前4713年)。为了提高精度,该类将日期和秒的全部部分存储在单独的组件中。为了计算安全和代表跳跃秒,日期总是存储在国际原子时间标准中。
下面是我们如何设置场景时间选项的例子:
// Set up clock and timeline.
viewer.clock.shouldAnimate = true; // make the animation play when the viewer starts
viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z");
viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:20:00Z");
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z");
viewer.clock.multiplier = 2; // sets a speedup
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // tick computation mode
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop at the end
viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // set visible range
这设置场景动画的速率、开始和停止时间,并告诉时钟在到达停止时间时循环回到开始。它还将时间线控件设置为适当的时间范围。看看这个时钟示例代码来测试时钟设置。
这是我们的初始场景配置!现在,当你运行你的应用程序时,你应该看到以下内容:
效果如下:
实体使用Cesium官网提供的实体:kml下载地址
var options = {
camera: viewer.scene.camera,
canvas: viewer.scene.canvas,
screenOverlayContainer: viewer.container,
};
var dataSourcePromise= Cesium.KmlDataSource.load('/cesium/gdpPerCapita2008.kmz', options);
// viewer.dataSources.add(dataSourcePromise); 可以选择一次性加载
dataSourcePromise.then(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的样式
}
}
})
viewer.camera.flyHome(0);
效果如下:
Entity结构如下:
【引用教程】
新手入门中文教程
文章浏览阅读15次。空化气泡的大小和相应的空化能量可以通过调整完全标度的振幅水平来操纵和数字控制。通过强调超声技术中的更高通量处理和防止样品污染,Epigentek EpiSonic超声仪可以轻松集成到现有的实验室工作流程中,并且特别适合与表观遗传学和下一代应用的兼容性。Epigentek的EpiSonic已成为一种有效的剪切设备,用于在染色质免疫沉淀技术中制备染色质样品,以及用于下一代测序平台的DNA文库制备。该装置的经济性及其多重样品的能力使其成为每个实验室拥有的经济高效的工具,而不仅仅是核心设施。
文章浏览阅读4.2k次,点赞3次,收藏14次。目录点击这里查看所有博文 本系列博客,理论上适用于合宙的Air202、Air268、Air720x、Air720S以及最近发布的Air720U(我还没拿到样机,应该也能支持)。 先不管支不支持,如果你用的是合宙的模块,那都不妨一试,也许会有意外收获。 我使用的是Air720SL模块,如果在其他模块上不能用,那就是底层core固件暂时还没有支持,这里的代码是没有问题的。例程仅供参考!..._合宙获取天气
文章浏览阅读7.7k次,点赞2次,收藏41次。1 关于meshMesh的意思是网状物,以前读书的时候,在自动化领域有传感器自组网,zigbee、蓝牙等无线方式实现各个网络节点消息通信,通过各种算法,保证整个网络中所有节点信息能经过多跳最终传递到目的地,用于数据采集。十多年过去了,在无线路由器领域又把这个mesh概念翻炒了一下,各大品牌都推出了mesh路由器,大多数是3个为一组,实现在面积较大的住宅里,增强wifi覆盖范围,智能在多热点之间切换,提升上网体验。因为节点基本上在3个以内,所以mesh的算法不必太复杂,组网形式比较简单。各厂家都自定义了组_802.11s
文章浏览阅读5.2k次,点赞8次,收藏21次。线程的几种状态_线程状态
文章浏览阅读4.2w次,点赞124次,收藏688次。stack翻译为栈,是STL中实现的一个后进先出的容器。要使用 stack,应先添加头文件include<stack>,并在头文件下面加上“ using namespacestd;"1. stack的定义其定义的写法和其他STL容器相同, typename可以任意基本数据类型或容器:stack<typename> name;2. stack容器内元素的访问..._stack函数用法
文章浏览阅读71次。<li> <a href = "“#”>-</a></li><li>子节点:文本节点(回车),元素节点,文本节点。不同节点树: 节点(各种类型节点)childNodes:返回子节点的所有子节点的集合,包含任何类型、元素节点(元素类型节点):child。node.getAttribute(at...
文章浏览阅读3.4k次。//config的设置是全局的layui.config({ base: '/res/js/' //假设这是你存放拓展模块的根目录}).extend({ //设定模块别名 mymod: 'mymod' //如果 mymod.js 是在根目录,也可以不用设定别名 ,mod1: 'admin/mod1' //相对于上述 base 目录的子目录}); //你也可以忽略 base 设定的根目录,直接在 extend 指定路径(主要:该功能为 layui 2.2.0 新增)layui.exten_layui extend
文章浏览阅读3.2k次,点赞6次,收藏13次。分层思想分层思想分层思想-1分层思想-2分层思想-2OSI七层参考模型物理层和数据链路层物理层数据链路层网络层传输层会话层表示层应用层OSI七层模型的分层结构TCP/IP协议族的组成数据封装过程数据解封装过程PDU设备与层的对应关系各层通信分层思想分层思想-1在现实生活种,我们在喝牛奶时,未必了解他的生产过程,我们所接触的或许只是从超时购买牛奶。分层思想-2平时我们在网络时也未必知道数据的传输过程我们的所考虑的就是可以传就可以,不用管他时怎么传输的分层思想-2将复杂的流程分解为几个功能_5g分层结构
文章浏览阅读191次。在激光雕刻中,单向扫描(Unidirectional Scanning)是一种雕刻技术,其中激光头只在一个方向上移动,而不是来回移动。这种移动方式主要应用于通过激光逐行扫描图像表面的过程。具体而言,单向扫描的过程通常包括以下步骤:横向移动(X轴): 激光头沿X轴方向移动到图像的一侧。纵向移动(Y轴): 激光头沿Y轴方向开始逐行移动,刻蚀图像表面。这一过程是单向的,即在每一行上激光头只在一个方向上移动。返回横向移动: 一旦一行完成,激光头返回到图像的一侧,准备进行下一行的刻蚀。
文章浏览阅读577次。强连通:在有向图G中,如果两个点u和v是互相可达的,即从u出发可以到达v,从v出发也可以到达u,则成u和v是强连通的。强连通分量:如果一个有向图G不是强连通图,那么可以把它分成躲个子图,其中每个子图的内部是强连通的,而且这些子图已经扩展到最大,不能与子图外的任一点强连通,成这样的一个“极大连通”子图是G的一个强连通分量(SCC)。强连通分量的一些性质:(1)一个点必须有出度和入度,才会与其他点强连通。(2)把一个SCC从图中挖掉,不影响其他点的强连通性。_强连通分量
文章浏览阅读3.9k次,点赞5次,收藏18次。在做web开发,要给用户提供一个页面,页面包括静态页面+数据,两者结合起来就是完整的可视化的页面,django的模板系统支持这种功能,首先需要写一个静态页面,然后通过python的模板语法将数据渲染上去。1.创建一个templates目录2.配置。_django templates
文章浏览阅读1.7k次。Ubuntu等Linux系统显卡性能测试软件 Unigine 3DUbuntu Intel显卡驱动安装,请参考:ATI和NVIDIA显卡请在软件和更新中的附加驱动中安装。 这里推荐: 运行后,F9就可评分,已测试显卡有K2000 2GB 900+分,GT330m 1GB 340+ 分,GT620 1GB 340+ 分,四代i5核显340+ 分,还有写博客的小盒子100+ 分。relaybot@re...