劉雨
(昆明能訊科技有限責任公司,云南 昆明 650217)
隨著電網(wǎng)數(shù)字化的推進,與之相關(guān)的空間數(shù)據(jù)的數(shù)據(jù)量也在飛速增長。以云南省為例,僅電網(wǎng)設(shè)備的空間數(shù)據(jù)就已突破億級,每個設(shè)備上掛載有數(shù)個到數(shù)十個不等的關(guān)聯(lián)要素的空間屬性,粗略估算,云南省的空間數(shù)據(jù)占用已達PB級。迫切需要一種高壓縮率的空間數(shù)據(jù)序列化方案,解放硬盤、內(nèi)存、網(wǎng)絡(luò)帶寬等資源,為用戶帶來流暢、輕量的地圖使用體驗。
傳統(tǒng)的空間數(shù)據(jù)存儲和傳輸中,一般按照開源組織OGC提出的WKB(Well-known Binary)規(guī)范[1],將空間數(shù)據(jù)序列化為二進制流,以點數(shù)據(jù)為例,WKB將其壓縮為如下格式:
因此,WKB規(guī)范下,一個點對象需要占用1+4+8+8+8=29個字節(jié),其中,字節(jié)序僅為兼容高位在前的壓縮方式而存在,x、y、z坐標總是占用8字節(jié),對于精度已知的坐標也是一種壓縮浪費??梢?,WKB的壓縮方案存在較大的空間浪費問題。
另一方面,WKB僅定義了空間數(shù)據(jù)的序列化規(guī)范,而電網(wǎng)數(shù)據(jù)往往關(guān)聯(lián)諸如編號、名稱等屬性,需要一種方法能夠?qū)傩耘c空間數(shù)據(jù)一并序列化,使得具有屬性關(guān)聯(lián)的業(yè)務(wù)能夠便捷、高性能地開展。
protobuf (protocol buffer)[3],谷歌內(nèi)部的混合語言數(shù)據(jù)標準。通過將結(jié)構(gòu)化的數(shù)據(jù)進行序列化(串行化),用于通訊協(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴展的序列化結(jié)構(gòu)數(shù)據(jù)格式。
本文基于protobuf設(shè)計空間數(shù)據(jù)的序列化規(guī)范,主要考慮到protobuf的如下優(yōu)點:protobuf 用字段索引和字段類型通過算法計算得到字段之前的關(guān)系映射,從而達到更高的時間效率和空間效率,特別適合對數(shù)據(jù)大小和傳輸速率比較敏感的場合使用;另一方面,protobuf支持對double數(shù)據(jù)類型的不定長壓縮,也特別適合解決前文提到的定長數(shù)值在空間坐標上的浪費問題。
根據(jù)OGC[2]規(guī)范,空間對象類型分為以下7種:Point(點)、LineString(線)、Polygon(面)、Multi Point(多點)、MultiLineString(多線)、MultiPolygon(多面)、GeometryCollection(幾何容器),本文對這7種空間對象的protobuf格式進行了定義。
Point類型定義如下:
由于x、y、z是不定長的,且大部分電網(wǎng)空間數(shù)據(jù)的精度只到米級,只需4個字節(jié)即可無損描述,因此,大部分點類型數(shù)據(jù)只需要4+4+4=12個字節(jié)即可存儲,即是考慮到預留位等,其大小也比WKB小許多。
LineString類型定義如下:
采用3個double數(shù)組存儲x、y、z坐標串。Polygon類型定義如下:
采用3個double數(shù)組存儲x、y、z坐標串,并用分隔符來確認多邊形上各個環(huán)的位置。
余下4種類型的定義與Polygon的定義類似,均采用了坐標串和分隔符結(jié)合的方案,故不再贅述,完整的定義已開源至gitee.com/wowtools/gis/blob/master/ProtoFeature.proto供讀者詳細查閱。
關(guān)聯(lián)屬性的定義如下:
采用key/value的方式來存儲關(guān)聯(lián)屬性,為了進一步壓縮冗余數(shù)據(jù),key、value不存儲具體的值,而是為相同的值賦予相同的編號,key、value僅存儲編號,從而大幅減少了相同值的空間占用。
特別地,對于存在多層級嵌套的關(guān)聯(lián)屬性,定義一個sub key/value以允許屬性的嵌套。
我們利用google開源的工具protoc,將本方法所述的protobuf規(guī)范編譯為java代碼,并封裝了常用的工具函數(shù),將其打包為本方法對應(yīng)的java實現(xiàn)工具包,并對工具包的壓縮率及對屬性的支持進行驗證。
我們選擇RFC 7946規(guī)范中提及的示例空間數(shù)據(jù)作為測試數(shù)據(jù),分別以WKB規(guī)范和本文所述方法進行序列化,并比對序列化后的字節(jié)數(shù),結(jié)果如表1所示。
表1 RFC 7946規(guī)范數(shù)據(jù)壓縮率比較
可見,對于不同類型的空間數(shù)據(jù),對比WKB,本方法的壓縮率都有較為明顯的提高。
我們對Java中的8種基本數(shù)據(jù)類型及string、嵌套類型分別進行了驗證,數(shù)據(jù)被正確地序列化、反序列化,且數(shù)值精度未發(fā)生丟失,說明本方法對于屬性的支持是正確和準確的。
我省的樹障隱患數(shù)據(jù)大約有120萬條,需要將這些數(shù)據(jù)的分布情況在web地圖上展現(xiàn)出來(如圖1所示),無疑需要占用極大的網(wǎng)絡(luò)帶寬和瀏覽器內(nèi)存,我們采用本方法,結(jié)合矢量瓦片技術(shù)與webgl展現(xiàn)技術(shù),將數(shù)據(jù)量壓縮到了4.8MB,并使得樹障隱患數(shù)據(jù)在配置較差的電腦上也能流暢運行。
圖1 大數(shù)據(jù)量的樹障隱患空間數(shù)據(jù)展現(xiàn)
在輸電線路分析業(yè)務(wù)中,往往需要結(jié)合設(shè)備本體、電網(wǎng)風險、環(huán)境因素等多個領(lǐng)域的數(shù)據(jù),綜合給出判斷結(jié)果,本方法解決了空間數(shù)據(jù)字節(jié)流無法攜帶屬性信息的問題,將空間數(shù)據(jù)與業(yè)務(wù)數(shù)據(jù)天然地融合(如圖2所示)在一起,使得前端業(yè)務(wù)展現(xiàn)和分析時,無需考慮繁雜的數(shù)據(jù)融合問題,開發(fā)者可將更多的精力投入到業(yè)務(wù)應(yīng)用上。
圖2 空間數(shù)據(jù)與電網(wǎng)屬性的天然融合
本文提出了一種高壓縮率的空間數(shù)據(jù)序列化方法,用以解決WKB規(guī)范在壓縮率和屬性傳輸上的不足。通過本方法的研究和實現(xiàn),為大數(shù)據(jù)量、復雜屬性的GIS業(yè)務(wù)場景提出了一種可行方案和工具。