Cesium官方教程中有一篇叫《空間數據可視化》(Visualizing Spatial Data)。該文文末簡單提到了Cesium的Property機制,而後話鋒一轉,宣告此教程的第二部分將重點講解Property機制。可是呢,第二部分尚未寫好,說在等待的過程當中,能夠先看下Cesium對影像和地形的支持。。css
能夠看官方教程中的說法,以下圖所示:web
因而,我苦等了一年啦。。官方教程的第二部分仍是沒能看到。。畢竟這是Cesium官方推薦使用的Entity API中最重要的部分之一。。竟然這麼久了也不給更新下。。api
我想仍是本身總結一下得好。。數組
仍是舉個例子來講吧。函數
好比我想在地球上的某個位置加一個盒子,能夠這樣寫代碼:spa
// 建立盒子 var blueBox = viewer.entities.add({ name : 'Blue box', position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0), box : { dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), material : Cesium.Color.BLUE, outline: true, } });
最終的效果如圖所示:3d
可是呢,若是我想讓這個盒子逐漸變長,該怎麼操做呢?以下圖所示:code
方法是有的,就是能夠不停地去修改blueBox.position,相似這樣:
setInterval(function(){ blueBox.box.dimensions = xxx; }, 3000);
orm
若是場景中有不少物體,在不一樣的時間段要發生各類走走停停地運動時,這樣操做可能會很累人。那麼Cesium就提供一種機制,讓dimensions能夠隨時間自動發生變化,自動賦予不一樣的數值(位置)。這也就是property的做用了。如下代碼的加入,就可讓盒子如上圖所示作線性運動了。對象
var property = new Cesium.SampledProperty(Cesium.Cartesian3); property.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 200000.0)); property.addSample(Cesium.JulianDate.fromIso8601('2019-01-03T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 700000.0)); blueBox.box.dimensions = property;
以上代碼的意思就是在兩個不一樣的時間點分別賦予不一樣的位置,用SampledProperty包裝成一個property,最後賦給blueBox.box.dimensions。
因而可知,Property最大的特色是和時間相互關聯,在不一樣的時間能夠動態地返回不一樣的屬性值。而Entity則能夠感知這些Property的變化,在不一樣的時間驅動物體進行動態展現。
Cesium宣稱本身是數據驅動和time-dynamic visualization,這些可都是仰仗Property系統來實現的。
固然,Property可不僅是這麼簡單,如下再詳細論述。
Cesium的Property不止有剛纔示例代碼中的SampleProperty,還有不少其餘的類型。若是搜索一下Cesium的API文檔,會有不少。。以下圖所示:
咱們簡單分類一下
Property是全部Property類型的虛基類。它定義瞭如下接口。
getValue 是一個方法,用來獲取某個時間點的特定屬性值。它有兩個參數:第一個是time,用來傳遞一個時間點;第二個是result,用來存儲屬性值,固然也能夠是undefined。這個result是Cesium的scratch機制,主要是用來避免頻繁建立和銷燬對象而致使內存碎片。Cesium就是經過調用getValue相似的一些函數來感知Property的變化的,固然這個方法咱們在外部也是可使用的。
isConstant 用來判斷該屬性是否會隨時間變化,是一個布爾值。Cesium會經過這個變量來決定是否須要在場景更新的每一幀中都獲取該屬性的數值,從而來更新三維場景中的物體。若是isConstant爲true,則只會獲取一次數值,除非definitionChanged事件被觸發。
definitionChanged 是一個事件,能夠經過該事件,來監聽該Property自身所發生的變化,好比數值發生修改。
equals 是一個方法,用來檢測屬性值是否相等。
咱們最先在上述示例中使用的就是它,用來經過給定多個不一樣時間點的Sample,而後在每兩個時間點之間進行線性插值的一種Property。代碼寫法以下:
var property = new Cesium.SampledProperty(Cesium.Cartesian3); property.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 200000.0)); property.addSample(Cesium.JulianDate.fromIso8601('2019-01-03T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 700000.0)); blueBox.box.dimensions = property;
效果以下所示:
該Property用來指定各個具體的時間段的屬性值,每一個時間段內的屬性值是恆定的,並不會發生變化,除非已經進入到下一個時間段。拿建立的盒子示例來講,表現出來的特色就是盒子尺寸的變化時跳躍式的。效果以下:
代碼以下:
var property = new Cesium.TimeIntervalCollectionProperty(Cesium.Cartesian3); property.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-01T00:00:00.00Z/2019-01-01T12:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 200000.0) })); property.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-01T12:00:01.00Z/2019-01-02T00:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 400000.0) })); property.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T00:00:01.00Z/2019-01-02T12:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0) })); property.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T12:00:01.00Z/2019-01-03T00:00:00.00Z', isStartIncluded : true, isStopIncluded : true, data : new Cesium.Cartesian3(400000.0, 300000.0, 700000.0) })); blueBox.box.dimensions = property;
經過對TimeIntervalCollectionProperty和SampleProperty的描述,讀者應該基本瞭解Property的特色。咱們回過頭來講下ConstantProperty,其實這纔是最經常使用的Property。
示例代碼以下:
blueBox.box.dimensions = new Cesium.Cartesian3(400000.0, 300000.0, 200000.0);
以上代碼貌似沒有使用ConstantProperty,實際上他是等同於:
blueBox.box.dimensions = new ConstantProperty(new Cesium.Cartesian3(400000.0, 300000.0, 200000.0));
也就是Entity的box.dimensions類型並非Cartesian3,而是一個Property。雖然咱們賦值了一個Cartesian3,可是Cesium內部會隱晦地轉化成了一個ConstantProperty。注意只會隱晦地轉化成ConstantProperty,而不是SampleProperty,更不是TimeIntervalCollectionProperty。
雖然叫ConstantProperty,可是,這裏Constant的意思並非說這個Property不可改變,而是說它不會隨時間發生變化。
舉個例子,咱們能夠經過 property.getValue(viewer.clock.currentTime) 方法來獲取某個時間點property的屬性值。若是property是SampleProperty或者TimeIntervalCollectionProperty的話,不一樣的時間點,可能getValue出不一樣的數值。可是若是這個property是ConstantProperty,那麼不管什麼時間(getValue的第一個參數不起做用),最後返回的數值都是同樣的。
可是不會隨時間變化,並不表明不可改變。ConstantProperty還有一個setValue的方法,開發者能夠經過調用它,來在適當的時候改變property的值。
好比,我能夠經過點擊按鈕來修改ConstantProperty,代碼以下:
blueBox.box.dimensions.setValue(new Cesium.Cartesian3(400000.0, 300000.0, 700000.0));
須要注意的是,雖然最終效果同樣,可是如下兩種寫法的意義是不同的。
blueBox.box.dimensions = new Cesium.Cartesian3(400000.0, 300000.0, 200000.0);
blueBox.box.dimensions.setValue(new Cesium.Cartesian3(400000.0, 300000.0, 700000.0));
前者會建立一個新的ConstantProperty,後者則會修改原有的ConstantProperty的值。
CompositeProperty的意思是組合的Property,能夠把多種不一樣類型的ConstantProperty、SampleProperty、TimeIntervalCollectionProperty等Property組合在一塊兒來操做。好比前一個時間段須要線性運動,後一段時間再跳躍式運動。則可使用相似下面這段代碼來實現。
// 1 sampledProperty var sampledProperty = new Cesium.SampledProperty(Cesium.Cartesian3); sampledProperty.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 200000.0)); sampledProperty.addSample(Cesium.JulianDate.fromIso8601('2019-01-02T00:00:00.00Z'), new Cesium.Cartesian3(400000.0, 300000.0, 400000.0)); // 2 ticProperty var ticProperty = new Cesium.TimeIntervalCollectionProperty(); ticProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T00:00:00.00Z/2019-01-02T06:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 400000.0) })); ticProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T06:00:00.00Z/2019-01-02T12:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0) })); ticProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T12:00:00.00Z/2019-01-02T18:00:00.00Z', isStartIncluded : true, isStopIncluded : false, data : new Cesium.Cartesian3(400000.0, 300000.0, 600000.0) })); ticProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T18:00:00.00Z/2019-01-03T23:00:00.00Z', isStartIncluded : true, isStopIncluded : true, data : new Cesium.Cartesian3(400000.0, 300000.0, 700000.0) })); // 3 compositeProperty var compositeProperty = new Cesium.CompositeProperty(); compositeProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-01T00:00:00.00Z/2019-01-02T00:00:00.00Z', data : sampledProperty })); compositeProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({ iso8601 : '2019-01-02T00:00:00.00Z/2019-01-03T00:00:00.00Z', isStartIncluded : false, isStopIncluded : false, data : ticProperty })); // 4 設置position blueBox.box.dimensions