SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics

时间:2024-04-14 12:08:19

作者:为梦齐舞

本文同步更新于简书文章https://www.jianshu.com/p/457f06a89ee5
BillboardGraphics类是隶属于实体对象的一个类型,从字面意思能够理解,广告牌,其实就是一张图片,图片方向始终朝向用户,不随着三维球的旋转而改变图片的朝向。我们经常在使用标注点图标的时候使用到这个类型,效果如下图所示:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
基础使用方法如下,我们添加了一个简单的Billboard

viewer.entities.add({
					id: "test",
					position: Cesium.Cartesian3.fromDegrees(101.80089882736969, 26.60700234866561, 20),
					billboard: {
						image: 'data/logo.png',
					}
				});

接下来我们来一探BillboardGraphics的奥秘。

一、主要参数介绍

1、image:必须设置,这个是Billboard需要显示的广告牌图片,可以是本地图片、在线图片链接或者是Canvas,需要注意不支持gif动图。
2、scale:用于控制广告牌的显示缩放比例,默认是1.0
3、horizontalOrigin:广告牌的水平对齐方式,默认是Cesium.HorizontalOrigin.CENTER(水平居中),也可以设置为Cesium.HorizontalOrigin.LEFT/Cesium.HorizontalOrigin.RIGHT,我们添加一个白色参照点,右对齐效果如图所示SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
4、verticalOrigin:广告牌的垂直对齐方式,默认VerticalOrigin.CENTER(垂直居中),也可以设置为Cesium.VerticalOrigin.BOTTOM / Cesium.VerticalOrigin.TOP /Cesium.VerticalOrigin.BASELINE ,我们依然添加一个白色的参照点,底部对齐效果如下所示:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
这里多介绍下Cesium.VerticalOrigin.BASELINE,这个文档解释说"如果对象包含文本,则原点位于文本的基线处,否则原点位于对象的底部。"经过测试这个和Cesium.VerticalOrigin.BOTTOM效果一致,没有特别的变化。
5、eyeOffset:广告牌相对用户观察位置偏移,是一个Cartesian3类型,X和Y分量分别表示水平方向和垂直方向的偏移,那么Z分量是什么,Z分量是指的相当用户观察位置的射线偏移位置,来对比下。我们将eyeOffset设置为new Cesium.Cartesian3(0,0,10)SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
我们将eyeOffset设置为new Cesium.Cartesian3(0,0,-10)
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
注意观察白色点对广告牌的遮蔽效果,由此说明Z分量是由屏幕和用户观察位置形成的射线方向。
6、pixelOffset:广告牌在场景中的像素偏移,是一个Cartesian2类型,可以设置XY分量,也是水平方向和垂直方向的偏移,但是区别于eyeOffset的XY分量
7、rotation:广告牌的旋转参数值,一个数值类型,此处需要注意的是需要设置一个弧度值,如果是度的话需要进行转换,转换方式:弧度= π/180×角度
8、alignedAxis:相当于是广告牌的基点位置。
9、width/height:广告牌的宽高属性,以像素为单位,这个会改变默认图片的大小。
10、color:设置广告牌的颜色属性,这个颜色和图片本身的颜色将进行混合显示,如果我们希望设置广告牌的透明度,也可以通过这个参数进行设置,如:color:new Cesium.Color(1,1,1,0.5),这样透明度设置为了0.5
11、scaleByDistance:设置基于相机距离的广告牌大小,也就是说可以根据不同的相机高度来设置广告牌的不同大小,一个NearFarScalar类型,比如我设置scaleByDistance为new Cesium.NearFarScalar(1500, 3, 50000, 0.5)
效果如下:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
12、translucencyByDistance:设置基于相机距离的广告牌透明度,也就是说可以根据不同的相机高度来设置广告牌的透明度,一个NearFarScalar类型,比如我设置scaleByDistance为new Cesium.NearFarScalar(1500, 0.1, 8000, 1)
效果如下:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
13、pixelOffsetScaleByDistance:设置基于相机距离的像素偏移缩放倍数,需要配合pixelOffset属性一起进行使用,如果pixelOffset没有设置则该属性设置无效,例如我们进行如下设置:

pixelOffset:new Cesium.Cartesian2(20,0),
pixelOffsetScaleByDistance:new Cesium.NearFarScalar(1500, 20, 8000, 1)

效果如***意观察白色点和图片的位置变化关系:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics

14、sizeInMeters:一个布尔属性,指定此广告牌的大小是否应以米为单位。设置此参数为true后,广告牌将随场景的缩放而缩放,效果如下:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
15、heightReference:高度模式,支持Cesium.HeightReference.NONE(绝对高度)、Cesium.HeightReference.RELATIVE_TO_GROUND(相对地面)、Cesium.HeightReference.CLAMP_TO_GROUND(贴地)三种高度模式,高度模式通过字面意思理解即可。

15、distanceDisplayCondition:即是控制广告牌在什么相机位置下显示出来。例如设置distanceDisplayCondition:new Cesium.DistanceDisplayCondition(1500,5000),即是在相机距离1500-5000的位置显示,其他具体广告牌都不显示。
16、disableDepthTestDistance:指定从相机到禁用深度测试的距离,关于深度测试我们将在后面的文章中介绍到,由于深度测试的存在,我们的对象很多时候会被地形挡住,如下:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
我们设置disableDepthTestDistance后,比如我们设置disableDepthTestDistance:50000,对象即可在高度50000下不再受深度的影响而显示
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics

主要的参数就介绍到此。

二、使用方法

BillboardGraphics隶属于Entity大类,操作当然全部在EntityCollection中进行操作,接下来我们来一步一步的实现。
1、添加BillboardGraphics
我们使用viewer.entities.add方法进行添加
添加对象有几个必填参数id(对象的唯一标识符。如果没有提供,则生成GUID,所以建议自己添加)、position、billboard

viewer.entities.add({
					id: "test",
					position: Cesium.Cartesian3.fromDegrees(101.80089882736969, 26.60700234866561, 20),
					billboard: {
						image: 'data/logo.png',
					}
				});

这样即可添加一个BillboardGraphics,其他参数可以按照上一步介绍到的参数进行按需添加
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
那么问题来了,有没有发现一个问题,广告牌被地球挡住了,如何解决这个问题,这个就涉及到我们说的深度测试,我们可以设置disableDepthTestDistance值来解决,
如下:

viewer.entities.add({
					id: "test",
					position: Cesium.Cartesian3.fromDegrees(101.80089882736969, 26.60700234866561, 20),
					billboard: {
						image: 'data/logo.png',
						disableDepthTestDistance:Number.POSITIVE_INFINITY//返回正无穷大
					}
				});

或者设置viewer.scene.globe.depthTestAgainstTerrain=false取消深度测试

viewer.scene.globe.depthTestAgainstTerrain=false;
viewer.entities.add({
					id: "test",
					position: Cesium.Cartesian3.fromDegrees(101.80089882736969, 26.60700234866561, 20),
					billboard: {
						image: 'data/logo.png'
					}
				});

都可以达到效果
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics
2、定位BillboardGraphics
我们添加的对象,范围太大时不容易被找到,如何进行定位呢?
我们可以使用viewer.flyTo飞向广告牌,但是我们首先需要找到这个BillboardGraphics,才能使用flyTo方法,我们使用viewer.entities.getById方法获取到对象,这个就是为什么添加的时候建议自己添加ID,以下代码就能直接飞到添加的广告牌

viewer.flyTo(viewer.entities.getById("test"));

3、判断BillboardGraphics是否已存在,可以使用viewer.entities.contains方法进行判断。
4、移除对象我们可以使用viewer.entities.remove或viewer.entities.removeById方法进行移除。

viewer.entities.remove(viewer.entities.getById("test"));
viewer.entities.removeById("test");

三、综合使用

我们添加一个BillboardGraphics,并且让他随时间逐渐放大变化,并飞向这个对象。
代码如下:

function onload(Cesium) {
				var viewer = new Cesium.Viewer('cesiumContainer');
				viewer.imageryLayers.addImageryProvider(
					new Cesium.BingMapsImageryProvider({
						url: "https://dev.virtualearth.net",
						mapStyle: Cesium.BingMapsStyle.AERIAL,
						key: "BingMaps的KEY"
					})
				);
				var clock = viewer.cesiumWidget.clock;
				clock.currentTime = Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z');
				var property = new Cesium.SampledProperty(Number);

				property.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z'),
					1);

				property.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:10.00Z'),
					5);

				viewer.entities.add({
					id: "test",
					position: Cesium.Cartesian3.fromDegrees(101.80089882736969, 26.60700234866561, 20),
					billboard: {
						image: 'data/logo.png',
						scale: property,
						disableDepthTestDistance: Number.POSITIVE_INFINITY
					}
				});

				viewer.flyTo(viewer.entities.getById("test"));
			}

效果如下:
SuperMap iClient3D for WebGL教程(Entity)-BillboardGraphics

里面使用到了property的相关接口,后续文章中会介绍使用方法。