在应用基于Cesium的Mars3D第三方库做开发的时候,碰到了这么一个需要:“实现两个模型之间的连线,这个直线能够随着模型的挪动而挪动”。
Mars3D中提供了一个标绘性能,简略来说就是能够通过拖动鼠标扭转模型在图层上的地位。所以提出的需要就简化成了————“鼠标拖动模型,模型间的连线随着模型挪动而挪动”。
这里模型的挪动形式对于后续的计划解决有很大的影响。首先我来讲讲第一种计划失败的可能起因。
计划一(失败)
model的position应用PositionProperty, polyline的position应用PositionPropertyArray,array数组外面是ReferenceProperty, 这里是为了让polyline两端的地位依赖于模型的地位。
这种计划是能够胜利显示出连线的,然而问题出在标绘上。
调用提供的标绘函数的时候,会呈现如图的谬误
在ReferenceProperty的api文档中提到了只有援用的属性是PositionProperty是这个函数才无效。
然而咱们在最后设定模型position的时候的确是应用的PositionProperty,这里我猜测应该是标绘函数应用了一个CallbackProperty,回调的Object不再是PositionProperty类型了,因而会出错。Mars3D的api并没有开源,具体起因也无从得悉了。
计划二(胜利)
既然咱们想用Mars3D的api实现咱们的需要,就须要另辟蹊径。
第二种计划应用了czml数据格式,czml数据配置项中的polyline/position属性有一个references选项, 应用它也能够实现地位依赖。
"polyline":{ "positions":{ "references":[ "model1#position", "model2#position" ] } }
新的问题便是:怎么引入这个czml数据?
Mars3D中提供了很多图层,这些图层都具备不同的性能。咱们上文中提到的标绘性能,是基于graphicLayer的,然而graphicLayer并不反对导入czml,Mars3D独自提供了czmlLayer能够导入czml配置文件。
因而采纳“双图层同步”的解决方案:graphicLayer上的标绘扭转模型地位后,应用监听事件获取扭转后的模型坐标,同步更新czml配置文件的相应模型的position属性内容,并更新czmlLayer图层。
graphicLayer显示模型,czmlLayer中的配置项中仅仅记录模型的地位,不显示模型,只显示polyline。简略来说,graphicLayer上的模型和czmlLayer的模型实际上是两个独自的实体,只是通过监听事件让这它们的地位时刻保持一致。
//模型绑定监听事件 this.graphicLayer.getGraphicById("Firecar").on(mars3d.EventType.updatePosition,function (event){ //console.log("地位产生了变动!",event) console.log(event.position.getValue(Cesium.JulianDate.fromDate(new Date('2022-06-16 08:00:00')))) that.czml.forEach(function(value,index,array){ if(value.id ==='Firecar') value.position = { "cartographicDegrees": (mars3d.LngLatPoint.fromCartesian(event.position.getValue(Cesium.JulianDate.fromDate(new Date('2022-06-16 08:00:00'))))).toArray(false) } }); //更新czml图层 that.czmlLayer.load() console.log(that.czmlLayer) })
须要留神的点:监听事件返回的是一个event,event外面有监听的position属性,这个属性是一个callbackProperty,应用getValue办法传入轻易一个工夫值得到变动后的坐标,留神失去的这个坐标是cartesian3,更新czml时候要将cartesian3换成array,这样直线才会失常显示。
这里的代码只是示意,目标还是为了分享解决思路。