SuperMap iClient3D for WebGL教程-CallbackProperty
这一节课程讲解CallbackProperty机制,官方解释为由回调函数延迟计算其值的属性。小编个人的理解为,该机制为间隔时间执行指定的方法返回属性值,用于对属性进行赋值。该机制可以可以说非常强大,可以实现许多动态效果。
首先来看下CallbackProperty的实例化参数
let CallbackProperty=new Cesium.CallbackProperty(callback, isConstant)
callback:回调函数,用于计算并返回属性值
isConstant:返回值是否变化
在Cesium原生范例中提供了一个线生长并计算线长度的范例,

callback
可以看到线非常平滑的在生长,同步的文本也在变化,下面来看下示例代码
var startLatitude = 35; var startLongitude = -120; var endLongitude; var startTime = Cesium.JulianDate.now(); // Add a polyline to the scene. Positions are dynamic. var isConstant = false; var redLine = viewer.entities.add({ polyline : { // This callback updates positions each frame. positions : new Cesium.CallbackProperty(function(time, result) { endLongitude = startLongitude + 0.001 * Cesium.JulianDate.secondsDifference(time, startTime); return Cesium.Cartesian3.fromDegreesArray([startLongitude, startLatitude, endLongitude, startLatitude], Cesium.Ellipsoid.WGS84, result); }, isConstant), width : 5, material : Cesium.Color.RED } });
可以看到在polyline的position设置时,使用CallbackProperty,通过计算线的结束点,不断返回位置坐标。
对于CallbackProperty有了初步的了解之后,这个时候会产生疑问,在什么情况下可以使用CallbackProperty?
根据小编的测试发现,在添加所有的entity时只要属性为property的都可以使用CallbackProperty。
下面来看下小编实现的一些效果:

交互绘制

高程量算
交互绘制和高程量算利用对鼠标事件的封装组合,形成常用的一些工具。以高程量算为例,示例代码如下
/** * 作者:ljw20190619 */ define([], function () { Cesium.measureHeighthandler = function (viewer) { this._viewer = viewer this._dislabel this._disline this._startposition this._endposition this._startpoint this._endpoint this._startHeight this._endHeight this._height this._circledis = 0 this._circle this._customdatasoure = new Cesium.CustomDataSource('myData'); this._handler = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas); this._viewer.dataSources.add(this._customdatasoure) let _that = this this.active = function () { //设置鼠标左键单击回调事件 _that._handler.setInputAction(function (e) { //获取点击位置笛卡尔坐标 let position = _that._viewer.scene.pickPosition(e.position); _that._startposition = position //将笛卡尔坐标转化为经纬度坐标 let cartographic = Cesium.Cartographic.fromCartesian(position); let startheight = cartographic.height; _that._startHeight = startheight //在点击位置添加对应点 if (!_that._startpoint) { _that._startpoint = _that._customdatasoure.entities.add({ point: { color: new Cesium.Color(1, 1, 0), pixelSize: 5, outlineColor: new Cesium.Color(0, 1, 1), disableDepthTestDistance: Number.POSITIVE_INFINITY }, position: new Cesium.CallbackProperty(function () { return _that._startposition }, false), }); } _that._handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK) _that._handler.setInputAction(function (e) { let position = _that._viewer.scene.pickPosition(e.endPosition); _that._endposition = position //将笛卡尔坐标转化为经纬度坐标 let cartographic = Cesium.Cartographic.fromCartesian(position); let endheight = cartographic.height; _that._endHeight = endheight _that._height = _that._endHeight - _that._startHeight _that._circledis = Cesium.Cartesian3.distance(_that._startposition, Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, _that._startHeight)) if (!_that._endpoint) { _that._endpoint = _that._customdatasoure.entities.add({ point: { color: new Cesium.Color(1, 1, 0), pixelSize: 5, outlineColor: new Cesium.Color(0, 1, 1), disableDepthTestDistance: Number.POSITIVE_INFINITY }, position: new Cesium.CallbackProperty(function () { let cartographic = Cesium.Cartographic.fromCartesian(_that._startposition); return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, _that._endHeight) }, false), }); } //绘制结果文本 if (!_that._dislabel) { _that._dislabel = _that._customdatasoure.entities.add({ position: new Cesium.CallbackProperty(function () { let cartographic = Cesium.Cartographic.fromCartesian(_that._startposition); return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, (cartographic.height + _that._endHeight) / 2) }, false), label: { text: new Cesium.CallbackProperty(function () { return Math.abs(_that._height).toFixed(2) + '米' }, false), font: '24px Helvetica', // fillColor: Cesium.Color.SKYBLUE, // outlineColor: Cesium.Color.BLACK, outlineWidth: 2, pixelOffset: new Cesium.Cartesian2(60, 0), showBackground: true, // style: Cesium.LabelStyle.FILL_AND_OUTLINE, disableDepthTestDistance: Number.POSITIVE_INFINITY } }) } //绘制结果线 if (!_that._disline) { _that._disline = _that._customdatasoure.entities.add({ polyline: { positions: new Cesium.CallbackProperty(function () { let cartographic = Cesium.Cartographic.fromCartesian(_that._startposition); return Cesium.Cartesian3.fromRadiansArrayHeights([cartographic.longitude, cartographic.latitude, cartographic.height, cartographic.longitude, cartographic.latitude, _that._endHeight]) }, false), width: 2, material: Cesium.Color.ORANGERED.withAlpha(0.5), //depthFailMaterial: Cesium.Color.ORANGERED.withAlpha(0.5) depthFailMaterial: new Cesium.ColorMaterialProperty(Cesium.Color.ORANGERED.withAlpha(0.5)) } }) } //绘制圆面 if (!_that._circle) { _that._circle = _that._customdatasoure.entities.add({ position: new Cesium.CallbackProperty(function () { let cartographic = Cesium.Cartographic.fromCartesian(_that._startposition); return Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, _that._endHeight) }, false), ellipse: { semiMajorAxis: new Cesium.CallbackProperty(function () { return _that._circledis }, false), semiMinorAxis: new Cesium.CallbackProperty(function () { return _that._circledis }, false), height: new Cesium.CallbackProperty(function () { return _that._endHeight }, false), material: Cesium.Color.YELLOW.withAlpha(0.2), outline: true, outlineColor: Cesium.Color.WHITE.withAlpha(0.5) } }) } _that._handler.setInputAction(function (e) { if (_that._circle) { _that._customdatasoure.entities.remove(_that._circle) } _that._circle = undefined _that._handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE) _that._handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK) }, Cesium.ScreenSpaceEventType.RIGHT_CLICK) }, Cesium.ScreenSpaceEventType.MOUSE_MOVE) }, Cesium.ScreenSpaceEventType.LEFT_CLICK); } this.disactive = function () { _that._customdatasoure.entities.removeAll() _that._dislabel=undefined _that._disline = undefined _that._startposition = undefined _that._endposition = undefined _that._startpoint = undefined _that._endpoint = undefined _that._startHeight = undefined _that._endHeight = undefined _that._height = undefined _that._circledis = 0 _that._circle = undefined } } return Cesium.measureHeighthandler })

旋转
旋转相对比较简单,利用对圆面设置旋转实现,代码如下:
var addRoatePOI = function(POIObjs) { POIObjs.forEach(function(value, index, array) { var POIEntity = viewer.entities.add({ name: value[2], position: Cesium.Cartesian3.fromDegrees(value[0], value[1], 180000), ellipse: { semiMinorAxis: 100000, semiMajorAxis: 100000, height: 180000, material: new Cesium.ImageMaterialProperty({ image: 'images/Oval.png', repeat: new Cesium.Cartesian2(1, 1), transparent: true }), rotation: new Cesium.CallbackProperty(getRotationValue, false), stRotation: new Cesium.CallbackProperty(getRotationValue, false), outline: false, // height must be set for outline to display numberOfVerticalLines: 100 }, description: '测试数据' }); }) var rotation = Cesium.Math.toRadians(30); function getRotationValue() { rotation += 0.002; return rotation; } }
本节教程就到这里,欢迎转发、留言、讨论。