Cesium 绘制点Point

一、概述

在Cesium中绘制一个点通常是用Cesium.Entity,也可以用Cesium.PointPrimitive。

用Entity API方式绘制数据是Cesium官方推荐的方式。Entity API实际上是在底层使用Primitive API

通过封装,屏蔽了不同Primitivie图元绘制方法的差异,实现了绘制点、线、面等不同图形的API一致性,易于理解,使用简单。

Primitive API为图形开发人员提供灵活的实现,而不是为了实现API一致性。加载不同类型的图元有各自不同的API,相对复杂,但更加灵活

如果需要绘制多个点可以通过Cesium.EntityCollection添加多个Cesium.Entity对象,也可以用Cesium.PointPrimitiveCollection,后者在绘制大量图元时更加高效。

二、Entity方式绘制一个点

Entity绘制的Point的所有参数如下:

效果和代码如下,绘制了一个30像素大小的点,轮廓宽度为10像素,设置了颜色,并设置了随着距离摄像机Camera的距离改变大小和透明度。

Entity的position属性用于设置点的位置,点和广告牌必须设置此属性。

这里需要说明的是Entity的Point实际上是Cesium.PointGraphics对象,Cesium会自动在内部进行封装,其他的如color、show等属性同理。

更多内容请学习Cesium的Property属性系统相关知识。

也可以像下面这样写:

            return new Cesium.PointGraphics({
                show: new Cesium.ConstantProperty(true),
                ...
                color: new Cesium.ConstantProperty(color),
                ...
            })

 

        function getPoint(color = Cesium.Color.RED, heightReference = Cesium.HeightReference.CLAMP_TO_GROUND) {
            return {
                show: true,
                pixelSize: 30,
                heightReference: heightReference,
                color: color,
                outlineColor: Cesium.Color.YELLOW,
                outlineWidth: 10,
                scaleByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.3),
                translucencyByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.2),
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000)
            }
        }


        function addEntity(height = 500, pointOption) {
            var entity = new Cesium.Entity({
                name: 'test',
                show: true,
                position: Cesium.Cartesian3.fromDegrees(114, 39, height),
                point: pointOption,
                description: `
                <p>这是entity的属性信息,entity的description里面可以写一段html</p>                
                <img width="450" height="200" src="./test.png"></img>
                <video width="450" height="350" controls="controls" type="video/mp4" preload="auto">
                    <source src="./test2.mp4" autostart="true">
                </video>
                <p>苹果园dog</p>`
            });
            viewer.entities.add(entity);
            return entity;
        }

 三、Entity点的显示设置

scaleByDistance 可以赋值为一个NearFarScalar对象,其作用是设置根据到摄像机的距离设置绘制的图形的大小,构造函数如下:

new Cesium.NearFarScalar(near, nearValue, far, farValue)

距离在near和far之间时,点的大小在nearValue和farValue两个比例中改变大小,距离小于near时,大小比例为nearValue,距离大于far时,大小比例为farValue。

translucencyByDistance是设置透明度,原理和NearFarScalar相同。

distanceDisplayCondition是设置可见性,构造函数为new Cesium.DistanceDisplayCondition(near, far),在near和far之间可见,超出范围不可见。

 

四、Entity的属性信息

通过设置description属性,在点击entity时可显示信息,可以写一段HTML。

 

 

 

五、贴地

heightReference默认是为Cesium.HeightReference.NONE,也就是绝对高程。

通过设置heightReference为Cesium.HeightReference.CLAMP_TO_GROUND,可使点贴地,地就是地形。

Cesium.HeightReference.RELATIVE_TO_GROUND是设置距离地形的相对高度。
Cesium默认加载的是Cesium.EllipsoidTerrainProvider,初始化三维球时不指定其他地形的话等同于viewer.terrainProvider=new Cesium.EllipsoidTerrainProvider()。
该地形构建了球的基本骨架,各处高度全为0。
当制定了其他地形时,比如加载了Ceisum全球地形,如果设置了Cesium.HeightReference.NONE,就要留意点的高度,如果高度低于该位置地形高度,点将位于地下,
这时候当移动摄像机时,地下的点就会飘移,可通过设置地形遮挡viewer.scene.globe.depthTestAgainstTerrain = true进行验证。
实际上点不像polygon等其他图形可以设置真正的贴地,除非设置了绝对高度或者viewer.scene.globe.depthTestAgainstTerrain = true,否则当移动摄像机时,点无法固定(如果有方法赐教)。注意,Cesium的地形数据是异步请求的,因此一般通过鼠标点击球上的位置获取高程。当添加点的时候,该位置可能地形还没有加载完,获取的高程就不准了,除非事先知道了高程。所以在加了地形数据后,要留意点的高度。

 

 六、绘制一个闪烁的点

无新知识,主要是CallbackProperty。

 function getFlashPoint(color) {
            let pointOpacity = 1.0;
            let pointColor2Big = true;
            let pointSize2Big = true;
            let outlineColor2Big = true;
            let outLineOpacity = 1.0;
            let pixelSize = 50;
            let minSize = 20;
            let maxSize = 50;
            let preTime = Cesium.JulianDate.now();
            var preTime1 = Cesium.JulianDate.now();
            var preTime2 = Cesium.JulianDate.now();
            let pointOption = {
                color: new Cesium.CallbackProperty((time, result) => {
                    let timestep = Cesium.JulianDate.secondsDifference(time, preTime);
                    if (timestep < 0.1) {
                        return color.withAlpha(pointOpacity);
                    }
                    preTime = time;
                    pointOpacity = pointColor2Big ? pointOpacity + 0.1 : pointOpacity - 0.1;
                    pointColor2Big = (pointColor2Big && pointOpacity > 0.9) ? false : pointColor2Big;
                    pointColor2Big = (!pointColor2Big && pointOpacity < 0.2) ? true : pointColor2Big;
                    return color.withAlpha(pointOpacity);
                }, false),

 

七、绘制多个点

这个通过Cesium.PointPrimitiveCollection加就行了,后者加多个entity到entityCollection,具体参考Cesium官方文档。

八、其他

还有很多其他内容,比如 Cesium.EntityCluster、Cesium.PointPrimitive、鼠标拾取等,请参考文档。

 


 

 


 

posted on 2021-02-28 00:32  苹果园dog  阅读(3522)  评论(0编辑  收藏  举报

导航