3.Cesium中实体Entity创建(超详细)

前言

在学习 Cesium 的过程中,我发现官方文档冗长且阅读困难,为此我结合官方文档与自己的学习笔记,对其进行归类总结;本文中,我将介绍 Cesium 中创建实体的方法,并对其进行分类,帮助读者快速理解 Cesium 中实体的类别,创建代码以及具体效果;

一、概述

1 . Cesium概念

  • Cesium 是一个开源的 JavaScript 库,用于在 Web 浏览器中创建 3 D 地球和地图。它提供了丰富的 API 和工具,可以帮助开发人员快速构建基于 WebGL 的地理信息系统(GIS)应用程序。
  • Entity 类是 Cesium 中描述和呈现地球上实体对象的核心类。它具有丰富的属性和方法,用于控制和定制地理实体的外观和行为。对 Entity 类进行实例化后,我们就可以得到 Entity 对象;
  • Entity 对象可以表示各种地理实体,如点、线、面等,并具有位置、方向、模型、标牌、折线、多边形等属性,通过设置这些属性可以实现各种类型的地理可视化;Entity 也是构建各种三维开发应用的核心基础;

在这里插入图片描述

在 Cesium 中,开发人员可以使用 Entity 类来创建并定制地球上的实体对象,以实现复杂的地理可视化和交互效果。例如,可以使用 Entity 类来创建标记城市位置的标记,或者绘制飞机航线等。在上面的演示图片中,红色的就是我们创建的立方体实体;

2. Entity分类

Entity 是一个单独的实体类,我们常见的实体就是这个类的实例;类似 viewer ,我们创建不同的界面,需要我们对 viewer 的属性进行配置,因此我们创建不同的实体,也要对 entity 实体属性进行配置;而官方文档中属性繁多,且没有进行整理,不易学习与阅读,我这里对 cesium 中实体属性进行分类归纳;如下图所示:

[Entity属性]

这里的符合地球曲率表示,随着实体的增大,其是否会贴着地球表面增长;而符合地球曲率的二维实体当其被拉伸或给予高度后就会失去贴地效果;

3 . Entity 应用场景

在 Cesium 中,Entity 类可以用于实现各种类型的地理可视化和交互效果。下面是一些常见的应用场景:

  • 在地图上添加标记:你可以使用Entity类来创建标记,标记城市位置、地标或其他感兴趣的点。
  • 绘制路径和航线:你可以使用Entity类来绘制路径和航线,例如飞机航线、迁徙路线等。
  • 创建自定义图形:你可以使用Entity类来创建各种自定义图形,例如多边形、圆形、椭圆形等,以表示特定区域或地理特征。
  • 添加标签和描述:你可以使用Entity类来添加标签和描述信息,以提供更多关于地理实体的信息。
  • 实现动画效果:你可以使用Entity类来实现动画效果,例如移动标记、改变颜色等。

这些只是一些常见的应用场景。由于 Entity 类具有丰富的属性和方法,开发人员可以使用它来实现各种复杂的地理可视化和交互效果。

二、代码演示

1 . 符合地球曲率的实体创建

二维 :

(1)创建椭圆 ellipse

//绘制椭圆const ellipse =  new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 100),ellipse: {semiMinorAxis: 30000, //椭圆的短半轴semiMajorAxis: 40000, //椭圆的长半轴extrudedHeight: 4000.0, //拉伸高度material: Cesium.Color.WHITE.withAlpha(0.5), //椭圆颜色outline: true, //是否显示边框outlineColor: Cesium.Color.BLUE, //边框颜色rotation: Cesium.Math.toRadians(45), //旋转角度,从正北方向开始顺时针旋转},});

椭圆

(2)创建线

const polyline =  new Cesium.Entity({polyline: {positions: Cesium.Cartesian3.fromDegreesArray([112.3, 39.9, 114.4, 39.9]), //返回笛卡尔坐标数组width: 10,material: Cesium.Color.RED,},});

因为线的坐标是由多个坐标对组成,我们这里使用. FromDegreesArray 方法批量转换坐标;

一定要注意 api 的名称写对,cesium 中属性名写错是不会报错的;

line

(3)创建多边形

  var polygon = new Cesium.Entity({name: "多边形",polygon: {hierarchy: Cesium.Cartesian3.fromDegreesArray([114.3, 39.9, 114.3, 32.0, 107.0, 32.0, 107.0, 39.9, 114.3, 39.9,]),material: Cesium.Color.RED.withAlpha(0.5),outline: true,outlineColor: Cesium.Color.BLACK,},});

相比平面 plane ,我们可以看到多边形是紧贴地面的;

多边形

(4)创建矩形

 var rectangle = new Cesium.Entity({name : '矩形',rectangle : {coordinates : Cesium.Rectangle.fromDegrees(114.3, 39.9, 0.4, 50),material : Cesium.Color.RED.withAlpha(0.5),outline : true,outlineColor : Cesium.Color.BLACK,height : 0,heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,extrudedHeight : 500000}
});

矩形

乍一看,矩形似乎和 box 没什么区别,但是矩形是一个二维区域,由经纬度坐标指定,它可以被挤压成一个立体的形状,且会随着地球的曲率而弯曲。而盒子是一个三维的几何体,它可以用来表示一个立方体或长方体,不会随着地球的曲率而弯曲。

三维

(1)创建走廊 corridor
描述走廊,走廊由中心线和宽度定义的形状符合地球曲率的线。它可以放置在地面上或高空并可以选择挤出成一个体积,可看作是复合地球曲率的线。

  //绘制走廊const corridor = new Cesium.Entity({name: "走廊",corridor: {positions: Cesium.Cartesian3.fromDegreesArray([114.3, 39.9, -114.0, 40.0, -0.0, 40.0, 114.3, 39.9,]), // 走廊的位置与形状height: 200.0, // 走廊的高度extrudedHeight: 100.0, //拉伸高度width: 2000.0, // 走廊的宽度cornerType: Cesium.CornerType.BEVELED, //走廊拐角类型 默认圆角,可选BEVELED或MITERED:material: Cesium.Color.BLUE.withAlpha(0.5), //走廊颜色outline: true, // 是否展示轮廓outlineColor: Cesium.Color.WHITE, //轮廓颜色},});

走廊

(2)创建墙
描述定义为线带和可选的最大和最小高度的二维墙。墙符合地球曲率,可以沿着地面或在高处放置。

{name: "起伏之墙",wall: {positions: Cesium.Cartesian3.fromDegreesArray([-115.0,50.0,-112.5,50.0,-110.0,50.0,-107.5,50.0,-105.0,50.0,-102.5,50.0,-100.0,50.0,-97.5,50.0,-95.0,50.0,-92.5,50.0,-90.0,50.0,]),maximumHeights: [100000,200000,100000,200000,100000,200000,100000,200000,100000,200000,100000,],minimumHeights: [0,100000,0,100000,0,100000,0,100000,0,100000,0,],material: Cesium.Color.BLUE.withAlpha(0.5),outline: true,outlineColor: Cesium.Color.BLACK,},
}

wall

(3)创建折线体积:

var polylineVolume = new Cesium.Entity({name: "折线体积",polylineVolume: {positions: Cesium.Cartesian3.fromDegreesArray([114.3, 39.9, 112.0, 36.0, 115.0, 38.0,]),shape: [new Cesium.Cartesian2(-50000, -50000),new Cesium.Cartesian2(50000, -50000),new Cesium.Cartesian2(50000, 50000),new Cesium.Cartesian2(-50000, 50000),],material: Cesium.Color.GREEN.withAlpha(0.5),outline: true,outlineColor: Cesium.Color.BLACK,},});

折线体积

2. 不符合地球曲率的实体创建

(1)创建一个立方体:

//创建实体所在的坐标
const position = Cesium.Cartesian3.fromDegrees(113.3, 39.9, 5000)const box = new Cesium.Entity({position: position, //位置box: {dimensions: new Cesium.Cartesian3(4000, 3000, 5000), //盒子的长宽高material: Cesium.Color.RED.withAlpha(0.5), //盒子颜色outline: true, //边框outlineColor: Cesium.Color.WHITE, //边框颜色},});//将立方体添加到场景中 viewer.entities.add(box);

这里 cesium 中使用的不是经纬度坐标,而是笛卡尔三维空间直角坐标系,所以需要对我们的坐标进行一次转化;可以看到 box 就是我们创建的立方体对象,这里的 position 就是实体在 cesium 空间中的位置;如果不设置这个属性,程序不会报错,但实体也不会显示;

box

(2)创建点:

  const point = new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),point: {pixelSize: 10,//点像素大小color: Cesium.Color.RED,//点颜色,不能用rgb等css方法,需要用Cesium.ColoroutlineColor: Cesium.Color.WHITE,outlineWidth: 2,},});

point

(3)创建图片标注:

//绘制图片const billboard = new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 10),billboard: {image: "/src/assets/position.png",width: 30,//图片宽度,单位pxheight: 30,//图片高度,单位pxeyeOffset: new Cesium.Cartesian3(0, 0, -10),//与坐标位置的偏移距离color: Cesium.Color.RED,//颜色scale: 1,//缩放比例},});

pic

(4)创建文字标注:

const label = new Cesium.Entity({position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 10),label: {text: "GISer Liu",font: "40px sans-serif",fillColor: Cesium.Color.red,showBackground: true,outlineColor: Cesium.Color.BLACK,outlineWidth: 2,style: Cesium.LabelStyle.FILL_AND_OUTLINE,pixelOffset: new Cesium.Cartesian2(0, 20),eyeOffset: new Cesium.Cartesian3(0, 0, -10),horizontalOrigin: Cesium.HorizontalOrigin.CENTER,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,scale: 0.5,showBackground: true,backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8),backgroundPadding: new Cesium.Cartesian2(10, 10),},});

label

(5)创建圆柱体:

var cylinder = new Cesium.Entity({name : '圆柱体',position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),cylinder : {length : 500000.0,topRadius : 200000.0,bottomRadius : 200000.0,material : Cesium.Color.RED.withAlpha(0.5),outline : true,outlineColor : Cesium.Color.BLACK,heightReference : Cesium.HeightReference.CLAMP_TO_GROUND}
});

cylinder

(6)创建椭球:

var ellipsoid = new Cesium.Entity({name : '椭球体',position: Cesium.Cartesian3.fromDegrees(114.3, 39.9),ellipsoid : {radii : new Cesium.Cartesian3(300000.0, 200000.0, 100000.0),//长半轴,短半轴,高度material : Cesium.Color.BLUE.withAlpha(0.5),outline : true,//开启轮廓outlineColor : Cesium.Color.BLACK,//轮廓颜色heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,//底部位置贴地fill : true //填充色启用}
});

椭球

当长半轴,短半轴,高度都一致时,我们就创建了球体;

(7)创建模型:

  var model = new Cesium.Entity({name: "模型",position: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 1000),//位置model: {uri: "/src/assets/Cesium_Air.glb",minimumPixelSize: 128, //模型最小像素maximumScale: 200, //模型最大放大倍数},});

model

glTF 文件有两种格式:.gltf.glb
.gltf 是一种基于 JSON 的文本格式,它以人类可读的形式存储模型数据。它通常与其他二进制文件(如纹理图像)一起使用,这些文件包含模型的其他数据。
.glb 是一种二进制格式,它将所有模型数据(包括纹理图像)打包到一个单独的文件中。这种格式更紧凑,更适合在网络上传输。
两种格式都可以表示相同的模型数据,只是存储方式不同。开发者可以根据需要选择适当的格式。

(8)创建轨迹:

  //启用动画viewer.clock.shouldAnimate = true;// 定义路径的起始和结束时间var start = Cesium.JulianDate.fromDate(new Date());var stop = Cesium.JulianDate.addSeconds(start, 360, new Cesium.JulianDate());// 配置时钟以控制动画viewer.clock.startTime = start.clone();viewer.clock.stopTime = stop.clone();viewer.clock.currentTime = start.clone();viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;viewer.clock.multiplier = 10;// 创建一个 SampledPositionProperty 来存储随时间变化的位置数据var position = new Cesium.SampledPositionProperty();//SampledPositionProperty 是 Cesium 中的一个类,它用于存储随时间变化的位置数据。它可以用来定义路径实体的形状,或者用来控制模型、点等其他实体随时间移动的轨迹。//开发者可以使用 addSample 方法向 SampledPositionProperty 中添加位置数据。每个位置数据都包含一个时间值和一个位置值for (var i = 0; i <= 360; i += 45) {// 计算每个时间点的位置var radians = Cesium.Math.toRadians(i);var time = Cesium.JulianDate.addSeconds(start, i, new Cesium.JulianDate());var height = 10000 + 500 * Math.sin(radians); // 计算飞机的高度var positionValue = new Cesium.Cartesian3.fromDegrees(114.3 + 0.1 * Math.cos(radians),39.9 + 0.1 * Math.sin(radians),height);// 将位置数据添加到 SampledPositionProperty 中position.addSample(time, positionValue);}//设置插值算法,平滑路径position.setInterpolationOptions({interpolationDegree: 4, //插值程度interpolationAlgorithm: Cesium.HermitePolynomialApproximation, //插值算法});// 创建一个路径实体,并为其提供位置数据和样式var path = viewer.entities.add({name: "路径",position: position,orientation: new Cesium.VelocityOrientationProperty(position),path: {leadTime: 0,trailTime: 60, //路径持续时间width: 20, //路径宽度resolution: 10, //路径分辨率material: new Cesium.PolylineGlowMaterialProperty({glowPower: 1, //发光强度或者粗细程度color: Cesium.Color.BLUEVIOLET, //发光颜色}),},model: {uri: "/src/assets/Cesium_Air.glb",minimumPixelSize: 128, //模型最小像素maximumScale: 200, //模型最大放大倍数,},});//视角飞行至路径viewer.zoomTo(path);

path

路径这里坑比较多,我这里加入了路径的详细使用过程,一般而言我们只需要设定 path 部分就好,使用时一定要设定启动动画,不然是没有效果且不会显示路径的;
代码中我加入了优化路径轨迹的插值功能,实际应用中,我们可以直接使用 CZML 的时序路径数据,我这里用的是自己创建的数据;加入模型可以更好地展现路径;
如果想要静态的路径,可以直接用 polyline 替代;

(9)创建平面 :

var plane = new Cesium.Entity({name : '平面',position: Cesium.Cartesian3.fromDegrees(114.3, 40),plane : {plane : new Cesium.Plane(Cesium.Cartesian3.UNIT_Z, 0),dimensions : new Cesium.Cartesian2(400000.0, 300000.0),material : Cesium.Color.RED.withAlpha(0.5),outline : true,outlineColor : Cesium.Color.BLACK}
});

plane

3.组合实体 :

就我们之前的案例代码而言,我们创建都是单个实体,我们也可以创建组合实体,即一个实体元素内包含多个要素;如点和标签,代码如下:

  // 线的顶部位置var lineTopPosition = Cesium.Cartesian3.fromDegrees(114.3, 39.9, 1000);//创建组合实体var entity = new Cesium.Entity({position: lineTopPosition,// 线polyline: {positions: Cesium.Cartesian3.fromDegreesArrayHeights([114.3, 39.9, 0, 114.3, 39.9, 1000,]),material: Cesium.Color.AQUA,//线的颜色},// 标签label: {text: "Hello World", // 标签显示的文本内容font: "14px sans-serif", // 标签文本的字体fillColor: Cesium.Color.RED, // 标签文本的填充颜色outlineColor: Cesium.Color.WHITE, // 标签文本的轮廓颜色outlineWidth: 2, // 标签文本的轮廓宽度style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 标签文本的样式,这里设置为填充和轮廓pixelOffset: new Cesium.Cartesian2(0, -10), // 标签相对于其原点的像素偏移量eyeOffset: new Cesium.Cartesian3(0, 0, -50), // 标签相对于相机位置的偏移量horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 标签的水平原点,这里设置为中心verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 标签的垂直原点,这里设置为底部scale: 1, // 标签的缩放比例showBackground: true, // 是否显示标签的背景backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 标签背景的颜色backgroundPadding: new Cesium.Cartesian2(10, 10), // 标签背景与文本之间的内边距},});//将立方体添加到场景中const Entity = viewer.entities.add(entity);//视角飞行至立方体viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(114.3, 39.9, 4000), // 目的地的经纬度坐标duration: 4,} // 动画持续时间,默认为3秒);

combination

三、总结

通过上面的示例,我们介绍了 Cesium 中创建各类实体的方法,既有符合地球曲率的二维和三维实体,也有不符合地球曲率的基本几何体,同时也可以通过组合实体实现多个要素的混合显示。这为我们使用 Cesium 进行三维可视化提供了重要支持。

项目地址:

Github地址
Gitee地址
拓展阅读
专栏地址


如果觉得我的文章对您有帮助,三连+关注便是对我创作的最大鼓励!或者一个star🌟也可以😂.

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

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

相关文章

集成VCO-Cadence ADE相位噪声分析

集成VCO-Cadence ADE相位噪声分析 简介环境软件工艺 参考振荡器原理图相位噪声说明pss设置1234 pnoise设置12345 结果 简介 本文主要是使用Cadence ADE仿真1GHz交叉耦合振荡器&#xff0c;得到相位噪声曲线&#xff0c;主要记录仿真设置过程&#xff0c;仅供参考&#xff0c;如…

数据结构01-线性结构-链表栈队列-队列篇

文章目录 参考&#xff1a;总结大纲要求线性结构-队列QQ号码解密 参考&#xff1a; 总结 本系列为C数据结构系列&#xff0c;会介绍 线性结构&#xff0c;简单树&#xff0c;特殊树&#xff0c;简单图等。本文为线性结构部分。 大纲要求 线性结构 【 3 】链表&#xff1a;单…

【socket编程】TCP服务器、UDP服务器、本地套接字【C语言代码实现】

目录 0. 准备知识 0.1 大小端概念 0.2 网络字节序和主机字节序的转换 0.3 点分十进制串转换&#xff08;IP地址转换函数&#xff09; 0.4 IPV4结构体&#xff1a;&#xff08;man 7 ip&#xff09; 0.5 IPV6套接字结构体&#xff1a;&#xff08;man 7 ipv6&#xff09; …

安卓和苹果页面和逻辑是否有必要追求百分之百统一

安卓和苹果存在操作系统系统差异&#xff0c;所以有些不一样。如&#xff1a;安卓的启动页面是根页面&#xff0c;并且可以设置显示时间&#xff1b;而苹果的启动页面是一个类似图片的容器&#xff08;Launch Screen.storyboard&#xff09;&#xff0c;不像其它页面可以控制页…

手搓一台简单的网络损伤仪——弱网测试

1、介绍 支持对链路带宽、传输时延、丢包率和无码率的手动设置&#xff1b; 1.1、网络损伤仪在使用时&#xff0c;网络拓扑连接 1.2、网络损伤仪管理页面展示 2、使用的设备及相关技术栈 一台Intel 赛扬 J1900的迷你主机【拥有4个千兆网口】&#xff1b;ubuntu-18.04.5-live…

Stable Diffusion - 高清局部重绘 (Inpaint) 调整脸部和手部细节

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131775232 在 Stable Diffusion 中&#xff0c;局部重绘(Inpaint)功能是一种可以让你在图像上删除不想要的区域&#xff0c;并用周围的像素自动填…

springCloud通过两种方式配置热更新

该热更新实际就是通过改动nacos官网里面的配置管理的妹纸内容实现 定义一个config包&#xff0c;在该包下面复制该代码 package cn.itcast.user.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.spring…

【LLM】Langchain使用[三](基于文档的问答)

文章目录 一、基于文档的问答1. 创建向量存储2. 不同类型的chain链 二、本地知识库问答1.1 整体框架2. 文本切分3. 图解流程 Reference 一、基于文档的问答 1. 创建向量存储 CSVLoader加载csv数据&#xff0c;loader结合模型使用使用Dock Array内存搜索向量存储&#xff0c;作…

PostgreSQL MVCC的弊端优化方案

我们之前的博客文章“我们最讨厌的 PostgreSQL 部分”讨论了大家最喜欢的 DBMS 多版本并发控制 (MVCC) 实现所带来的问题。其中包括版本复制、表膨胀、索引维护和真空管理。本文将探讨针对每个问题优化 PostgreSQL 的方法。 尽管 PostgreSQL 的 MVCC 实现是 Oracle 和 MySQL 等…

Jenkins动态化阶段步骤

Jenkins中如何去根据入参动态化阶段步骤呢&#xff1f; Groovy语言基础 定义一个列表变量 def list []定义一个map的kv结构变量 def map [:]如何可以动态化阶段步骤 动态化步骤&#xff1a;其实就是&#xff0c;在jenkins pipeline中根据入参或者其他变量列表&#xff0c;动…

微服务 云原生:gRPC 客户端、服务端的通信原理

gRPC Hello World protoc 是 Protobuf 的核心工具&#xff0c;用于编写 .proto 文件并生成 protobuf 代码。在这里&#xff0c;以 Go 语言代码为例&#xff0c;进行 gRPC 相关代码编写。 下载 protoc 工具&#xff1a;https://github.com/protocolbuffers/protobuf/releases&a…

【单谐波非线性振动问题求解器 GUI 】使用单个谐波表示解决 MDOF 非线性振动问题(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…