Skip to content

Cesium的扩展工具包 EarthSDK使用指南3

Tang Xiaofei edited this page Sep 2, 2019 · 1 revision

Cesium的扩展工具包-EarthSDK使用指南3

前言

EarthSDK通过JSON配置来实现三维场景对象的管理,而JSON配置中的每一个属性同时也是响应式属性。这里所说的响应式属性,是指属性的变化,不需要通过轮询的方式,即可以被即时监听。这样就可以实现对某些特定属性的监测,来完成相应的交互操作。

之前写过一篇文章说明响应式设计的特点:三维应用的响应式设计探索。可以参考下。

这里详细说明一下EarthSDK中如何使用响应式属性,来方便地进行UI交互功能开发。

响应式属性设计示例说明

这里以3dtiles数据的编辑交互为例来说明。这个示例在这里: http://earthsdk.com/v/last/Apps/Examples/?menu=false&url=./earth-3dtiles-editing.html

编辑交互示例

这个示例用来进行3dtiles数据的平移和旋转交互操作。当用户点击平移按钮以后,就会进入平移的编辑操作状态,此时三维场景中相应物体的中心位置会出现一个坐标架。这个坐标架分别用红绿蓝三种颜色表示在x、y、z三个轴向的移动操作。x轴对应地球上的经度方向,x轴向的移动代表经度的变化。y轴对应地球上的纬度方向,y轴向的移动代表纬度的变化。z轴指高度上的变化。旋转操作类似,不再详述。

平移和旋转的交互操作分别由以下两个属性来控制: tileset.positionEditing tileset.rotationEditing 当某个交互操作的属性为true时,表示该交互操作正在进行。当为false时,表示当前没有进行该交互操作。

这里的交互操作有以下特点:

  1. 在三维窗口中点击鼠标右键,会自动取消平移或者旋转的交互操作。意思是positionEditing/rotationEditing会自动变成false。
  2. 平移和旋转的交互操作是互斥的,当启动其中之一时,另一项会自动取消操作。比如positionEditing一开始为true,当设置rotationEditing为true时,positionEditing会自动变为false。
  3. 用户也可以直接调用平移或旋转的属性来取消或者启用相应的编辑功能。意思时用户可以强制设置positionEditing/rotationEditing为true或者false,来开启或者取消相应的交互操作。

编辑互斥

交互逻辑内部是很复杂的,但是对于前端开发者来说,却并不需要关心这些逻辑,需要做的工作仅仅是把vue中的viewmodel属性和三维场景的属性进行双向绑定:

XE.MVVM.bind(this, 'rotationEditing', tileset, 'rotationEditing');
XE.MVVM.bind(this, 'positionEditing', tileset, 'positionEditing');

然后通过ViewModel中的同名属性来决定按钮是否需要高亮,再通过ViewModel中的同名属性来进行true或者false的设置,这样就完成了此App的功能开发。

ViewModel

EarthSDK中的响应式属性绑定相关API说明

和响应式属性相关的API都被命名为XE.MVVM, API文档在这里

MVVM.bind

函数参数如下所示:

MVVM.bind(reactObject1, reactProperty1, reactObject2, reactProperty2, params)

reactObject1, reactProperty1 和 reactObject2, reactProperty2 分别代表两个对象和相应的属性。

注意点1:reactProperty1/reactProperty2 必须是字符串!写法形式如下:

XE.MVVM.bind(vm, 'rotationEditing', tileset, 'rotationEditing')

注意点2:这两个属性必须都是响应式的,普通属性是不行的,会报错。EarthSDK大部分属性都是响应式的,Vue的data中的属性也可以直接使用,例如上面示例中的vm.rotationEditing,实际上就是Vue中的属性。

注意点3:绑定两个属性之前,如果属性值不一样,那么会以第二个属性值为准。例如上例中 vm.rotationEditing的初始值为false,tileset.rotationEditing的初始值为true,那么调用MVVM.bind之后,就会发现,vm.rotationEditing的值已经变为true了。

注意点4:MVVM.bind的返回值是一个无参数的函数,调用该函数,会取消之前的绑定操作。例如:

var ub = XE.MVVM.bind(vm, 'rotationEditing', tileset, 'rotationEditing');
// 经过若干使用之后
// ...

// 取消之前的绑定操作,此时两个属性值的变化就不会相应影响了。
ub();

MVVM.bindPosition/MVVM.bindRotation

MVVM.bindPosition(degreesObject, degreesPropery, radiansObject, radiansProperty)
MVVM.bindRotation(degreesObject, degreesPropery, radiansObject, radiansProperty)

EarthSDK中用只有三个元素的数组来表示位置(position)和姿态(rotation)。

position表示位置,用经纬度表示地球上的位置,三个元素分别表示经度、纬度、高度。注意:经度和纬度的单位是弧度,高度的单位是米。

例如:北京的经纬度分别是116.39, 39.9,那么它的position需要这样表示:[116.39 / 180 * Math.PI , 39.9 / 180 * Math.PI, 0] = [2.0313887163962, 0.6963863715457375, 0]。

rotation表示姿态,用欧拉角表示旋转量,三个元素分别表示偏航角、俯仰角、翻转角。注意这三个元素的单位都是弧度。

EarthSDK集成自Cesium,使用的角度都是用弧度表示的。但是UI界面上一般会用角度来表示。为了解决这个问题,就可以用到 bindPosition/bindRotation 这两个函数。它们可以自动完成弧度到角度的转换。

这两个函数的前两个参数表示角度属性,后两个参数表示弧度属性。使用方法如下:

XE.MVVM.bindPosition(vm, 'xbsjPosition', tileset, 'xbsjPosition');
XE.MVVM.bindPosition(vm, 'xbsjRotation', tileset, 'xbsjRotation');
MVVM.track

MVVM.bind用来进行双向绑定,意思是两个属性值,任意一个发生变化,另外一个就会自动修改。

但是实际使用时,会遇到一些变量属于只读属性,只能读取属性的变化,并不能随意修改。

此时可以使用MVVM.track来进行跟踪,意思是 reactProperty1 跟踪 reactProperty2的变化。

MVVM.track(reactObject1, reactProperty1, reactObject2, reactProperty2, params)

如果reactProperty2发生变化,reactProperty1会进行相应的更改。但是如果reactProperty1变化了,reactProperty2并不会发生变化。


欢迎关注 Cesium实验室 ,QQ群号:830157717

QQ群