Cesium中的CZML文件結構解析

本文在官方介紹基礎上簡化總結而成

CZML 可以理解爲 Cesium Language 的簡寫,是cesium中很重要的一個概念,使得cesium很酷很炫地展示動態數據成爲可能
某種程度上說, Cesium 和 CZML的關係就像 Google Earth 和 KML。

CZML是JSON的子集,這意味着有效的CZML文檔也是有效的JSON文檔。 具體來說,CZML文檔包含一個JSON數組,其中數組中的每個對象文字元素都是一個CZML數據包(packet)。 CZML數據包描述了場景中單個對象(例如單個飛機)的圖形屬性。

一段示例:

[
    // packet one
    {
        "id": "GroundControlStation"
        "position": { "cartographicDegrees": [-75.5, 40.0, 0.0] },
        "point": {
            "color": { "rgba": [0, 0, 255, 255] },
        }
    },
    // packet two
    {
        "id": "PredatorUAV",
        // ...
    }
]

在上面的示例中,我們指定了“ GroundControlStation”對象在WGS 84經度-75.5度,緯度40.0度和高度0.0米處具有固定的位置,並在其位置繪製了一個藍色的Point。

ID

每個數據包都有一個id屬性,用於標識正在描述的對象。 ID不必是GUID,但它們確實需要唯一地標識CZML源中的單個對象以及加載到同一作用域中的任何其他CZML源。

如果未指定ID,客戶端將自動生成一個唯一的ID。但是,這會阻止以後的數據包引用該對象,以便例如向該對象添加更多數據。

間隔

定義某個屬性在不同時間間隔內的值時,將該屬性定義爲一個數組,並用interval屬性定義在不同時間段的值。

{
    "id": "myObject",
    "someProperty": [
        {
            "interval": "2012-04-30T12:00:00Z/13:00:00Z",
            "number": 5
        },
        {
            "interval": "2012-04-30T13:00:00Z/14:00:00Z",
            "number": 6
        },
    ]
}

這個示例中,在兩個時間間隔內定義someProperty屬性,
第一個時間間隔是中午12:00到1:00 PM(屬性值是5),
第二個時間間隔是1:00 PM到2:00 PM UTC(屬性值是6),
跨越兩個間隔之間的邊界時,該值將立即更改。我們使用數字來表示值,因爲這是一個數字類型的屬性。一些屬性(尤其是表示位置的屬性)允許以多種格式指定值,例如笛卡爾X,Y,Z位置或製圖經度,緯度,高度位置。每種類型的頁面列出了每種屬性支持的數據類型,以及每種屬性所使用的值名稱。

interval屬性是可選的。如果未指定,則假定該間隔跨越所有時間。指定多個無限間隔或通常重疊的間隔沒有多大意義,但是如果您指定了此間隔,則在CZML文件或流中的後面一個優先。

如果屬性的值在一個長間隔上不變,則只需定義一個,間隔數組可以省略。

{
    "id": "myObject",
    "someProperty": {
        "interval": "2012-04-30T12:00:00Z/14:00:00Z",
        "number": 5
    }
}

如果所有時間內,值都不變,則可簡寫爲:

{
    "id": "myObject",
    "someProperty": 5
}

該縮寫表示法對於其值可以用一種簡單的JSON數據類型(字符串,數字或布爾值)表示的任何屬性均有效。

複合值

用JSON數組來表示更復雜的複合值,例如笛卡爾位置或顏色。
對於笛卡爾位置,數組具有三個元素,分別對應於該位置的X,Y和Z分量。

{
    "id": "myObject",
    "someComplexProperty": {
        "cartesian": [1.0, 2.0, 3.0]
    }
}

屬性採樣

除了上面介紹的可以定義不同時間間隔的單一值和複合值,還可以定義不同時間點的採樣值,客戶端會根據這些值進行插值計算,補上沒有賦值的時間的數據。
注意時間使用ISO 8601字符串指定。

{
    // ...
    "someInterpolatableProperty": {
        "cartesian": [
            "2012-04-30T12:00Z", 1.0, 2.0, 3.0,
            "2012-04-30T12:01Z", 4.0, 5.0, 6.0,
            "2012-04-30T12:02Z", 7.0, 8.0, 9.0
        ]
    }
}

這個示例定義了三個時間點的座標,則後續時間的值會根據這三個值線性插值計算得出。
這個也可以簡寫,定義一個開始時間,數據默認以整秒遞增,例如:

{ 
    "someInterpolatableProperty": {
        "epoch": "2012-04-30T12:00Z",
        "cartesian": [
            0.0, 1.0, 2.0, 3.0,
            60.0, 4.0, 5.0, 6.0,
            120.0, 7.0, 8.0, 9.0
        ]
    }
}

另外,可以用其他屬性控制插值方式

{ 
    "someInterpolatableProperty": {
        "epoch": "2012-04-30T12:00Z",
        "cartesian": [
            0.0, 1.0, 2.0, 3.0,
            60.0, 4.0, 5.0, 6.0,
            120.0, 7.0, 8.0, 9.0
        ],
        "interpolationAlgorithm": "LAGRANGE",   //指定插值算法,默認線性插值
        "interpolationDegree": 5    //定義用來插值所使用的多項式的次數,默認1
    },
}

interpolationAlgorithm屬性可選值: "LINEAR", "LAGRANGE", and "HERMITE".
interpolationDegree屬性可選值:1表示線性差值,2表示二次插值法

EventSource and Streaming 服務器事件和流加載

將整個CZML文檔放在一個大JSON數組中,將很難以增量方式加載該文檔。 當今的網絡瀏覽器允許在流完成之前對流進行一些訪問,但是解析和解釋不完整的數據需要緩慢而麻煩的字符串操作。 爲了促進高性能流傳輸,還可以使用現代瀏覽器的服務器發送事件(EventSource)API來流傳輸CZML。 使用此API時,每個CZML數據包都作爲單獨的事件流傳輸到客戶端:

event: czml
data: {
    // packet one
}

event: czml
data: {
    // packet two
}

當瀏覽器接收到一個packet後就會發出一個事件,事件中會包含剛剛接收到了數據。這樣我們就可以通過增量的方式高效的處理CZML數據。

目前爲止,我們都是使用一個packet包來描述一個對象,這個packet包含了所有這個對象的圖形屬性。我們還可以使用其他的方式,例如一個CZML文件或流可以包含多個packet,每個packet都有相同的id,分別描述同一個對象的不同方面的屬性。

事實上在大多數情況下我們使用兩個packet來描述一個對象。當對象屬性跨越多個時間間隔,或者一個時間間隔有很多個時間戳採樣時,這樣做就很有用了。通過將一個屬性定義打包進多個packet,我們可以使數據更快的傳輸到Cesium中,減少用戶等待的時間。

當客戶端接收到一個packet,它會遍歷packet中的每一個屬性。對於每個屬性,它會遍歷屬性定義的每個時間間隔。對於每個時間間隔,它會判斷這個時間間隔是否已經定義,假如這個間隔已經定義,將更新已經存在的間隔,如果沒有定義,那麼就根據這個間隔創建一個新的。

當更新一個已存在的時間間隔時,假如有子屬性,那麼子屬性將覆蓋原有的值。有一個例外,就是當已有的屬性和新接收到的屬性都包含時間戳採樣時,新接收到的採樣不會覆蓋已有的,而是加到已有的採樣列表中。

當新的時間間隔與已有的發生重疊時,新的間隔擁有較高優先級,原有的間隔將被截斷或者整個移除。這點必須要牢記。

在同一個packet中的時間間隔的時間必須以增序排列,不同packet之間就沒有要求。但是對於不連續的採樣還是應該考慮合理的插值順序。

previousTime 和 nextTime

如果定義的兩個時間段之間時間沒有連接上,比如1-3,7-9,中間4-6時間的數據是插值還是空着呢?就用到 previousTime 和 nextTime 屬性了

Availability 可用性

{
    "id": "PredatorUAV",
    "availability": "2012-04-30T12:00:00Z/14:00:00Z",
    // ...
}

Availability屬性指示對象的數據何時可用。如果已知某個對象的數據在當前動畫時間可用,但是客戶端尚未獲得該數據(大概是因爲它將在以後的數據包中到達),則客戶端可以暫停並顯示諸如“正在緩衝...等待接收數據。該屬性可以是指定單個間隔的單個字符串,也可以是表示間隔的字符串數組。

假如availability變化了或者被發現是不正確的,那麼隨後的packet將會更新它的值。例如,一個SGP4 propagator可能總是可用的,但是隨後他發出了一個異常,所以他的值需要調整。如果availability屬性沒有定義,那麼默認是全部時間內都可用的。Availability的範圍被限定到一個特定的CZML流中,所以對同一個對象在兩個不同的流中可以有不同的availability。在一個流中,只有定義在最後的那個availability起作用,其他的都會被忽略。在某一時刻,如果一個對象是可用的,那麼這個對象至少要有一個可用的屬性並且在此時間段內需要的屬性都要有定義(也就是獲取到了數據),不然Cesium就會等待數據直到接收到數據爲止。

擴展 CZML

可以給CZML增加自定義屬性,但是爲避免衝突,我們強烈建議你給你的自定義屬性加上你特有的前綴。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章